aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/include')
-rw-r--r--contrib/llvm/include/llvm-c/Analysis.h65
-rw-r--r--contrib/llvm/include/llvm-c/BitReader.h76
-rw-r--r--contrib/llvm/include/llvm-c/BitWriter.h56
-rw-r--r--contrib/llvm/include/llvm-c/Core.h2697
-rw-r--r--contrib/llvm/include/llvm-c/Disassembler.h175
-rw-r--r--contrib/llvm/include/llvm-c/EnhancedDisassembly.h530
-rw-r--r--contrib/llvm/include/llvm-c/ExecutionEngine.h163
-rw-r--r--contrib/llvm/include/llvm-c/Initialization.h54
-rw-r--r--contrib/llvm/include/llvm-c/LinkTimeOptimizer.h69
-rw-r--r--contrib/llvm/include/llvm-c/Object.h149
-rw-r--r--contrib/llvm/include/llvm-c/Target.h253
-rw-r--r--contrib/llvm/include/llvm-c/TargetMachine.h142
-rw-r--r--contrib/llvm/include/llvm-c/Transforms/IPO.h81
-rw-r--r--contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h101
-rw-r--r--contrib/llvm/include/llvm-c/Transforms/Scalar.h134
-rw-r--r--contrib/llvm/include/llvm-c/Transforms/Vectorize.h48
-rw-r--r--contrib/llvm/include/llvm-c/lto.h302
-rw-r--r--contrib/llvm/include/llvm/ADT/APFloat.h467
-rw-r--r--contrib/llvm/include/llvm/ADT/APInt.h1755
-rw-r--r--contrib/llvm/include/llvm/ADT/APSInt.h266
-rw-r--r--contrib/llvm/include/llvm/ADT/ArrayRef.h300
-rw-r--r--contrib/llvm/include/llvm/ADT/BitVector.h503
-rw-r--r--contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h76
-rw-r--r--contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h91
-rw-r--r--contrib/llvm/include/llvm/ADT/DenseMap.h576
-rw-r--r--contrib/llvm/include/llvm/ADT/DenseMapInfo.h168
-rw-r--r--contrib/llvm/include/llvm/ADT/DenseSet.h129
-rw-r--r--contrib/llvm/include/llvm/ADT/DepthFirstIterator.h268
-rw-r--r--contrib/llvm/include/llvm/ADT/EquivalenceClasses.h281
-rw-r--r--contrib/llvm/include/llvm/ADT/FoldingSet.h680
-rw-r--r--contrib/llvm/include/llvm/ADT/GraphTraits.h106
-rw-r--r--contrib/llvm/include/llvm/ADT/Hashing.h770
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h248
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableList.h230
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableMap.h418
-rw-r--r--contrib/llvm/include/llvm/ADT/ImmutableSet.h1224
-rw-r--r--contrib/llvm/include/llvm/ADT/InMemoryStruct.h77
-rw-r--r--contrib/llvm/include/llvm/ADT/IndexedMap.h87
-rw-r--r--contrib/llvm/include/llvm/ADT/IntEqClasses.h88
-rw-r--r--contrib/llvm/include/llvm/ADT/IntervalMap.h2146
-rw-r--r--contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h247
-rw-r--r--contrib/llvm/include/llvm/ADT/NullablePtr.h52
-rw-r--r--contrib/llvm/include/llvm/ADT/Optional.h120
-rw-r--r--contrib/llvm/include/llvm/ADT/OwningPtr.h133
-rw-r--r--contrib/llvm/include/llvm/ADT/PackedVector.h158
-rw-r--r--contrib/llvm/include/llvm/ADT/PointerIntPair.h167
-rw-r--r--contrib/llvm/include/llvm/ADT/PointerUnion.h452
-rw-r--r--contrib/llvm/include/llvm/ADT/PostOrderIterator.h240
-rw-r--r--contrib/llvm/include/llvm/ADT/PriorityQueue.h84
-rw-r--r--contrib/llvm/include/llvm/ADT/SCCIterator.h220
-rw-r--r--contrib/llvm/include/llvm/ADT/STLExtras.h302
-rw-r--r--contrib/llvm/include/llvm/ADT/ScopedHashTable.h256
-rw-r--r--contrib/llvm/include/llvm/ADT/SetOperations.h71
-rw-r--r--contrib/llvm/include/llvm/ADT/SetVector.h184
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallBitVector.h461
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallPtrSet.h307
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallSet.h118
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallString.h295
-rw-r--r--contrib/llvm/include/llvm/ADT/SmallVector.h748
-rw-r--r--contrib/llvm/include/llvm/ADT/SparseBitVector.h881
-rw-r--r--contrib/llvm/include/llvm/ADT/SparseSet.h268
-rw-r--r--contrib/llvm/include/llvm/ADT/Statistic.h139
-rw-r--r--contrib/llvm/include/llvm/ADT/StringExtras.h134
-rw-r--r--contrib/llvm/include/llvm/ADT/StringMap.h463
-rw-r--r--contrib/llvm/include/llvm/ADT/StringRef.h528
-rw-r--r--contrib/llvm/include/llvm/ADT/StringSet.h38
-rw-r--r--contrib/llvm/include/llvm/ADT/StringSwitch.h126
-rw-r--r--contrib/llvm/include/llvm/ADT/TinyPtrVector.h165
-rw-r--r--contrib/llvm/include/llvm/ADT/Trie.h334
-rw-r--r--contrib/llvm/include/llvm/ADT/Triple.h432
-rw-r--r--contrib/llvm/include/llvm/ADT/Twine.h524
-rw-r--r--contrib/llvm/include/llvm/ADT/UniqueVector.h89
-rw-r--r--contrib/llvm/include/llvm/ADT/ValueMap.h366
-rw-r--r--contrib/llvm/include/llvm/ADT/VariadicFunction.h331
-rw-r--r--contrib/llvm/include/llvm/ADT/edit_distance.h102
-rw-r--r--contrib/llvm/include/llvm/ADT/ilist.h704
-rw-r--r--contrib/llvm/include/llvm/ADT/ilist_node.h106
-rw-r--r--contrib/llvm/include/llvm/Analysis/AliasAnalysis.h578
-rw-r--r--contrib/llvm/include/llvm/Analysis/AliasSetTracker.h439
-rw-r--r--contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h342
-rw-r--r--contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h55
-rw-r--r--contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h129
-rw-r--r--contrib/llvm/include/llvm/Analysis/CFGPrinter.h114
-rw-r--r--contrib/llvm/include/llvm/Analysis/CallGraph.h378
-rw-r--r--contrib/llvm/include/llvm/Analysis/CaptureTracking.h63
-rw-r--r--contrib/llvm/include/llvm/Analysis/CodeMetrics.h93
-rw-r--r--contrib/llvm/include/llvm/Analysis/ConstantFolding.h102
-rw-r--r--contrib/llvm/include/llvm/Analysis/ConstantsScanner.h93
-rw-r--r--contrib/llvm/include/llvm/Analysis/DIBuilder.h560
-rw-r--r--contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h83
-rw-r--r--contrib/llvm/include/llvm/Analysis/DebugInfo.h928
-rw-r--r--contrib/llvm/include/llvm/Analysis/DomPrinter.h30
-rw-r--r--contrib/llvm/include/llvm/Analysis/DominanceFrontier.h190
-rw-r--r--contrib/llvm/include/llvm/Analysis/DominatorInternals.h289
-rw-r--r--contrib/llvm/include/llvm/Analysis/Dominators.h904
-rw-r--r--contrib/llvm/include/llvm/Analysis/FindUsedTypes.h66
-rw-r--r--contrib/llvm/include/llvm/Analysis/IVUsers.h185
-rw-r--r--contrib/llvm/include/llvm/Analysis/InlineCost.h136
-rw-r--r--contrib/llvm/include/llvm/Analysis/InstructionSimplify.h218
-rw-r--r--contrib/llvm/include/llvm/Analysis/Interval.h153
-rw-r--r--contrib/llvm/include/llvm/Analysis/IntervalIterator.h259
-rw-r--r--contrib/llvm/include/llvm/Analysis/IntervalPartition.h111
-rw-r--r--contrib/llvm/include/llvm/Analysis/LazyValueInfo.h81
-rw-r--r--contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h73
-rw-r--r--contrib/llvm/include/llvm/Analysis/LibCallSemantics.h167
-rw-r--r--contrib/llvm/include/llvm/Analysis/Lint.h49
-rw-r--r--contrib/llvm/include/llvm/Analysis/Loads.h57
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopDependenceAnalysis.h124
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopInfo.h1100
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopIterator.h186
-rw-r--r--contrib/llvm/include/llvm/Analysis/LoopPass.h158
-rw-r--r--contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h84
-rw-r--r--contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h445
-rw-r--r--contrib/llvm/include/llvm/Analysis/PHITransAddr.h121
-rw-r--r--contrib/llvm/include/llvm/Analysis/Passes.h205
-rw-r--r--contrib/llvm/include/llvm/Analysis/PathNumbering.h304
-rw-r--r--contrib/llvm/include/llvm/Analysis/PathProfileInfo.h112
-rw-r--r--contrib/llvm/include/llvm/Analysis/PostDominators.h106
-rw-r--r--contrib/llvm/include/llvm/Analysis/ProfileInfo.h247
-rw-r--r--contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h84
-rw-r--r--contrib/llvm/include/llvm/Analysis/ProfileInfoTypes.h60
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionInfo.h688
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionIterator.h342
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionPass.h126
-rw-r--r--contrib/llvm/include/llvm/Analysis/RegionPrinter.h26
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolution.h885
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h265
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h498
-rw-r--r--contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h78
-rw-r--r--contrib/llvm/include/llvm/Analysis/SparsePropagation.h206
-rw-r--r--contrib/llvm/include/llvm/Analysis/Trace.h119
-rw-r--r--contrib/llvm/include/llvm/Analysis/ValueTracking.h181
-rw-r--r--contrib/llvm/include/llvm/Analysis/Verifier.h75
-rw-r--r--contrib/llvm/include/llvm/Argument.h92
-rw-r--r--contrib/llvm/include/llvm/Assembly/AssemblyAnnotationWriter.h63
-rw-r--r--contrib/llvm/include/llvm/Assembly/Parser.h64
-rw-r--r--contrib/llvm/include/llvm/Assembly/PrintModulePass.h42
-rw-r--r--contrib/llvm/include/llvm/Assembly/Writer.h37
-rw-r--r--contrib/llvm/include/llvm/Attributes.h377
-rw-r--r--contrib/llvm/include/llvm/AutoUpgrade.h44
-rw-r--r--contrib/llvm/include/llvm/BasicBlock.h291
-rw-r--r--contrib/llvm/include/llvm/Bitcode/Archive.h546
-rw-r--r--contrib/llvm/include/llvm/Bitcode/BitCodes.h186
-rw-r--r--contrib/llvm/include/llvm/Bitcode/BitstreamReader.h668
-rw-r--r--contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h546
-rw-r--r--contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h326
-rw-r--r--contrib/llvm/include/llvm/Bitcode/ReaderWriter.h154
-rw-r--r--contrib/llvm/include/llvm/CallGraphSCCPass.h104
-rw-r--r--contrib/llvm/include/llvm/CallingConv.h103
-rw-r--r--contrib/llvm/include/llvm/CodeGen/Analysis.h97
-rw-r--r--contrib/llvm/include/llvm/CodeGen/AsmPrinter.h482
-rw-r--r--contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h78
-rw-r--r--contrib/llvm/include/llvm/CodeGen/CallingConvLower.h325
-rw-r--r--contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h147
-rw-r--r--contrib/llvm/include/llvm/CodeGen/EdgeBundles.h69
-rw-r--r--contrib/llvm/include/llvm/CodeGen/FastISel.h394
-rw-r--r--contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h231
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCMetadata.h193
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h73
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCStrategy.h153
-rw-r--r--contrib/llvm/include/llvm/CodeGen/GCs.h35
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h809
-rw-r--r--contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h59
-rw-r--r--contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h342
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h100
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LexicalScopes.h249
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h37
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h53
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveInterval.h573
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h407
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h207
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h99
-rw-r--r--contrib/llvm/include/llvm/CodeGen/LiveVariables.h315
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachORelocation.h56
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h708
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h56
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h86
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h335
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h53
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h174
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineDominators.h203
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h561
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunction.h487
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h51
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h59
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstr.h961
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h316
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h203
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h130
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h178
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h112
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h174
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h405
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h97
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineOperand.h674
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h157
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h545
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineRelocation.h342
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineSSAUpdater.h115
-rw-r--r--contrib/llvm/include/llvm/CodeGen/MachineScheduler.h91
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h461
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicBase.h246
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h616
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h469
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Math.h288
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h94
-rw-r--r--contrib/llvm/include/llvm/CodeGen/Passes.h452
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ProcessImplicitDefs.h51
-rw-r--r--contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h112
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h168
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h66
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h170
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h142
-rw-r--r--contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h330
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h711
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h351
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h93
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h107
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h127
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAG.h1074
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h313
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h1858
-rw-r--r--contrib/llvm/include/llvm/CodeGen/SlotIndexes.h694
-rw-r--r--contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h133
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ValueTypes.h715
-rw-r--r--contrib/llvm/include/llvm/CodeGen/ValueTypes.td81
-rw-r--r--contrib/llvm/include/llvm/Constant.h158
-rw-r--r--contrib/llvm/include/llvm/Constants.h1159
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DIContext.h68
-rw-r--r--contrib/llvm/include/llvm/DefaultPasses.h168
-rw-r--r--contrib/llvm/include/llvm/DerivedTypes.h462
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h623
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h44
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h102
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h38
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/JIT.h38
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h116
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h206
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h38
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h124
-rw-r--r--contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h87
-rw-r--r--contrib/llvm/include/llvm/Function.h458
-rw-r--r--contrib/llvm/include/llvm/GVMaterializer.h66
-rw-r--r--contrib/llvm/include/llvm/GlobalAlias.h94
-rw-r--r--contrib/llvm/include/llvm/GlobalValue.h291
-rw-r--r--contrib/llvm/include/llvm/GlobalVariable.h175
-rw-r--r--contrib/llvm/include/llvm/InitializePasses.h256
-rw-r--r--contrib/llvm/include/llvm/InlineAsm.h297
-rw-r--r--contrib/llvm/include/llvm/InstrTypes.h854
-rw-r--r--contrib/llvm/include/llvm/Instruction.def199
-rw-r--r--contrib/llvm/include/llvm/Instruction.h377
-rw-r--r--contrib/llvm/include/llvm/Instructions.h3598
-rw-r--r--contrib/llvm/include/llvm/IntrinsicInst.h282
-rw-r--r--contrib/llvm/include/llvm/Intrinsics.h81
-rw-r--r--contrib/llvm/include/llvm/Intrinsics.td443
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsARM.td442
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsCellSPU.td242
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsHexagon.td3671
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsPTX.td92
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsPowerPC.td465
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsX86.td2677
-rw-r--r--contrib/llvm/include/llvm/IntrinsicsXCore.td114
-rw-r--r--contrib/llvm/include/llvm/LLVMContext.h111
-rw-r--r--contrib/llvm/include/llvm/LinkAllPasses.h169
-rw-r--r--contrib/llvm/include/llvm/LinkAllVMCore.h53
-rw-r--r--contrib/llvm/include/llvm/Linker.h306
-rw-r--r--contrib/llvm/include/llvm/MC/EDInstInfo.h29
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmBackend.h150
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfo.h594
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h36
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h29
-rw-r--r--contrib/llvm/include/llvm/MC/MCAsmLayout.h105
-rw-r--r--contrib/llvm/include/llvm/MC/MCAssembler.h931
-rw-r--r--contrib/llvm/include/llvm/MC/MCAtom.h68
-rw-r--r--contrib/llvm/include/llvm/MC/MCCodeEmitter.h38
-rw-r--r--contrib/llvm/include/llvm/MC/MCCodeGenInfo.h48
-rw-r--r--contrib/llvm/include/llvm/MC/MCContext.h406
-rw-r--r--contrib/llvm/include/llvm/MC/MCDirectives.h57
-rw-r--r--contrib/llvm/include/llvm/MC/MCDisassembler.h136
-rw-r--r--contrib/llvm/include/llvm/MC/MCDwarf.h337
-rw-r--r--contrib/llvm/include/llvm/MC/MCELFObjectWriter.h110
-rw-r--r--contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h58
-rw-r--r--contrib/llvm/include/llvm/MC/MCExpr.h464
-rw-r--r--contrib/llvm/include/llvm/MC/MCFixup.h112
-rw-r--r--contrib/llvm/include/llvm/MC/MCFixupKindInfo.h43
-rw-r--r--contrib/llvm/include/llvm/MC/MCInst.h204
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstPrinter.h66
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrAnalysis.h61
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrDesc.h535
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrInfo.h62
-rw-r--r--contrib/llvm/include/llvm/MC/MCInstrItineraries.h253
-rw-r--r--contrib/llvm/include/llvm/MC/MCLabel.h56
-rw-r--r--contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h46
-rw-r--r--contrib/llvm/include/llvm/MC/MCMachObjectWriter.h257
-rw-r--r--contrib/llvm/include/llvm/MC/MCModule.h58
-rw-r--r--contrib/llvm/include/llvm/MC/MCObjectFileInfo.h312
-rw-r--r--contrib/llvm/include/llvm/MC/MCObjectStreamer.h90
-rw-r--r--contrib/llvm/include/llvm/MC/MCObjectWriter.h194
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/AsmCond.h40
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h70
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h181
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h146
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h80
-rw-r--r--contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h47
-rw-r--r--contrib/llvm/include/llvm/MC/MCRegisterInfo.h361
-rw-r--r--contrib/llvm/include/llvm/MC/MCSection.h73
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionCOFF.h69
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionELF.h88
-rw-r--r--contrib/llvm/include/llvm/MC/MCSectionMachO.h182
-rw-r--r--contrib/llvm/include/llvm/MC/MCStreamer.h676
-rw-r--r--contrib/llvm/include/llvm/MC/MCSubtargetInfo.h79
-rw-r--r--contrib/llvm/include/llvm/MC/MCSymbol.h164
-rw-r--r--contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h89
-rw-r--r--contrib/llvm/include/llvm/MC/MCTargetAsmParser.h103
-rw-r--r--contrib/llvm/include/llvm/MC/MCValue.h77
-rw-r--r--contrib/llvm/include/llvm/MC/MCWin64EH.h93
-rw-r--r--contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h36
-rw-r--r--contrib/llvm/include/llvm/MC/MachineLocation.h98
-rw-r--r--contrib/llvm/include/llvm/MC/SectionKind.h240
-rw-r--r--contrib/llvm/include/llvm/MC/SubtargetFeature.h115
-rw-r--r--contrib/llvm/include/llvm/Metadata.h239
-rw-r--r--contrib/llvm/include/llvm/Module.h602
-rw-r--r--contrib/llvm/include/llvm/Object/Archive.h145
-rw-r--r--contrib/llvm/include/llvm/Object/Binary.h104
-rw-r--r--contrib/llvm/include/llvm/Object/COFF.h200
-rw-r--r--contrib/llvm/include/llvm/Object/ELF.h2218
-rw-r--r--contrib/llvm/include/llvm/Object/Error.h50
-rw-r--r--contrib/llvm/include/llvm/Object/MachO.h133
-rw-r--r--contrib/llvm/include/llvm/Object/MachOFormat.h377
-rw-r--r--contrib/llvm/include/llvm/Object/MachOObject.h204
-rw-r--r--contrib/llvm/include/llvm/Object/ObjectFile.h597
-rw-r--r--contrib/llvm/include/llvm/OperandTraits.h160
-rw-r--r--contrib/llvm/include/llvm/Operator.h326
-rw-r--r--contrib/llvm/include/llvm/Pass.h375
-rw-r--r--contrib/llvm/include/llvm/PassAnalysisSupport.h253
-rw-r--r--contrib/llvm/include/llvm/PassManager.h103
-rw-r--r--contrib/llvm/include/llvm/PassManagers.h460
-rw-r--r--contrib/llvm/include/llvm/PassRegistry.h84
-rw-r--r--contrib/llvm/include/llvm/PassSupport.h341
-rw-r--r--contrib/llvm/include/llvm/Support/AIXDataTypesFix.h25
-rw-r--r--contrib/llvm/include/llvm/Support/AlignOf.h60
-rw-r--r--contrib/llvm/include/llvm/Support/Allocator.h242
-rw-r--r--contrib/llvm/include/llvm/Support/Atomic.h39
-rw-r--r--contrib/llvm/include/llvm/Support/BlockFrequency.h65
-rw-r--r--contrib/llvm/include/llvm/Support/BranchProbability.h77
-rw-r--r--contrib/llvm/include/llvm/Support/CFG.h357
-rw-r--r--contrib/llvm/include/llvm/Support/COFF.h586
-rw-r--r--contrib/llvm/include/llvm/Support/CallSite.h311
-rw-r--r--contrib/llvm/include/llvm/Support/Capacity.h32
-rw-r--r--contrib/llvm/include/llvm/Support/Casting.h233
-rw-r--r--contrib/llvm/include/llvm/Support/CodeGen.h52
-rw-r--r--contrib/llvm/include/llvm/Support/CommandLine.h1689
-rw-r--r--contrib/llvm/include/llvm/Support/Compiler.h152
-rw-r--r--contrib/llvm/include/llvm/Support/ConstantFolder.h238
-rw-r--r--contrib/llvm/include/llvm/Support/ConstantRange.h265
-rw-r--r--contrib/llvm/include/llvm/Support/CrashRecoveryContext.h200
-rw-r--r--contrib/llvm/include/llvm/Support/DOTGraphTraits.h161
-rw-r--r--contrib/llvm/include/llvm/Support/DataExtractor.h352
-rw-r--r--contrib/llvm/include/llvm/Support/DataFlow.h103
-rw-r--r--contrib/llvm/include/llvm/Support/DataStream.h38
-rw-r--r--contrib/llvm/include/llvm/Support/DataTypes.h.in212
-rw-r--r--contrib/llvm/include/llvm/Support/Debug.h101
-rw-r--r--contrib/llvm/include/llvm/Support/DebugLoc.h113
-rw-r--r--contrib/llvm/include/llvm/Support/Disassembler.h35
-rw-r--r--contrib/llvm/include/llvm/Support/Dwarf.h740
-rw-r--r--contrib/llvm/include/llvm/Support/DynamicLibrary.h104
-rw-r--r--contrib/llvm/include/llvm/Support/ELF.h1141
-rw-r--r--contrib/llvm/include/llvm/Support/Endian.h224
-rw-r--r--contrib/llvm/include/llvm/Support/Errno.h34
-rw-r--r--contrib/llvm/include/llvm/Support/ErrorHandling.h106
-rw-r--r--contrib/llvm/include/llvm/Support/FEnv.h56
-rw-r--r--contrib/llvm/include/llvm/Support/FileSystem.h720
-rw-r--r--contrib/llvm/include/llvm/Support/FileUtilities.h80
-rw-r--r--contrib/llvm/include/llvm/Support/Format.h216
-rw-r--r--contrib/llvm/include/llvm/Support/FormattedStream.h154
-rw-r--r--contrib/llvm/include/llvm/Support/GCOV.h224
-rw-r--r--contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h113
-rw-r--r--contrib/llvm/include/llvm/Support/GraphWriter.h357
-rw-r--r--contrib/llvm/include/llvm/Support/Host.h66
-rw-r--r--contrib/llvm/include/llvm/Support/IRBuilder.h1281
-rw-r--r--contrib/llvm/include/llvm/Support/IRReader.h112
-rw-r--r--contrib/llvm/include/llvm/Support/IncludeFile.h79
-rw-r--r--contrib/llvm/include/llvm/Support/InstIterator.h147
-rw-r--r--contrib/llvm/include/llvm/Support/InstVisitor.h243
-rw-r--r--contrib/llvm/include/llvm/Support/LeakDetector.h92
-rw-r--r--contrib/llvm/include/llvm/Support/Locale.h17
-rw-r--r--contrib/llvm/include/llvm/Support/LockFileManager.h74
-rw-r--r--contrib/llvm/include/llvm/Support/MDBuilder.h118
-rw-r--r--contrib/llvm/include/llvm/Support/MachO.h714
-rw-r--r--contrib/llvm/include/llvm/Support/ManagedStatic.h115
-rw-r--r--contrib/llvm/include/llvm/Support/MathExtras.h474
-rw-r--r--contrib/llvm/include/llvm/Support/Memory.h96
-rw-r--r--contrib/llvm/include/llvm/Support/MemoryBuffer.h141
-rw-r--r--contrib/llvm/include/llvm/Support/MemoryObject.h69
-rw-r--r--contrib/llvm/include/llvm/Support/Mutex.h154
-rw-r--r--contrib/llvm/include/llvm/Support/MutexGuard.h41
-rw-r--r--contrib/llvm/include/llvm/Support/NoFolder.h286
-rw-r--r--contrib/llvm/include/llvm/Support/OutputBuffer.h166
-rw-r--r--contrib/llvm/include/llvm/Support/PassNameParser.h137
-rw-r--r--contrib/llvm/include/llvm/Support/Path.h16
-rw-r--r--contrib/llvm/include/llvm/Support/PathV1.h743
-rw-r--r--contrib/llvm/include/llvm/Support/PathV2.h358
-rw-r--r--contrib/llvm/include/llvm/Support/PatternMatch.h824
-rw-r--r--contrib/llvm/include/llvm/Support/PluginLoader.h37
-rw-r--r--contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h81
-rw-r--r--contrib/llvm/include/llvm/Support/PredIteratorCache.h70
-rw-r--r--contrib/llvm/include/llvm/Support/PrettyStackTrace.h71
-rw-r--r--contrib/llvm/include/llvm/Support/Process.h150
-rw-r--r--contrib/llvm/include/llvm/Support/Program.h159
-rw-r--r--contrib/llvm/include/llvm/Support/RWMutex.h173
-rw-r--r--contrib/llvm/include/llvm/Support/Recycler.h118
-rw-r--r--contrib/llvm/include/llvm/Support/RecyclingAllocator.h73
-rw-r--r--contrib/llvm/include/llvm/Support/Regex.h81
-rw-r--r--contrib/llvm/include/llvm/Support/Registry.h223
-rw-r--r--contrib/llvm/include/llvm/Support/RegistryParser.h55
-rw-r--r--contrib/llvm/include/llvm/Support/SMLoc.h62
-rw-r--r--contrib/llvm/include/llvm/Support/SaveAndRestore.h47
-rw-r--r--contrib/llvm/include/llvm/Support/Signals.h59
-rw-r--r--contrib/llvm/include/llvm/Support/Solaris.h40
-rw-r--r--contrib/llvm/include/llvm/Support/SourceMgr.h199
-rw-r--r--contrib/llvm/include/llvm/Support/StreamableMemoryObject.h181
-rw-r--r--contrib/llvm/include/llvm/Support/StringPool.h139
-rw-r--r--contrib/llvm/include/llvm/Support/SwapByteOrder.h101
-rw-r--r--contrib/llvm/include/llvm/Support/SystemUtils.h44
-rw-r--r--contrib/llvm/include/llvm/Support/TargetFolder.h255
-rw-r--r--contrib/llvm/include/llvm/Support/TargetRegistry.h1140
-rw-r--r--contrib/llvm/include/llvm/Support/TargetSelect.h166
-rw-r--r--contrib/llvm/include/llvm/Support/ThreadLocal.h54
-rw-r--r--contrib/llvm/include/llvm/Support/Threading.h59
-rw-r--r--contrib/llvm/include/llvm/Support/TimeValue.h382
-rw-r--r--contrib/llvm/include/llvm/Support/Timer.h194
-rw-r--r--contrib/llvm/include/llvm/Support/ToolOutputFile.h62
-rw-r--r--contrib/llvm/include/llvm/Support/TypeBuilder.h399
-rw-r--r--contrib/llvm/include/llvm/Support/Valgrind.h75
-rw-r--r--contrib/llvm/include/llvm/Support/ValueHandle.h417
-rw-r--r--contrib/llvm/include/llvm/Support/Win64EH.h100
-rw-r--r--contrib/llvm/include/llvm/Support/YAMLParser.h552
-rw-r--r--contrib/llvm/include/llvm/Support/circular_raw_ostream.h171
-rw-r--r--contrib/llvm/include/llvm/Support/raw_os_ostream.h42
-rw-r--r--contrib/llvm/include/llvm/Support/raw_ostream.h496
-rw-r--r--contrib/llvm/include/llvm/Support/system_error.h903
-rw-r--r--contrib/llvm/include/llvm/Support/type_traits.h205
-rw-r--r--contrib/llvm/include/llvm/SymbolTableListTraits.h79
-rw-r--r--contrib/llvm/include/llvm/TableGen/Error.h48
-rw-r--r--contrib/llvm/include/llvm/TableGen/Main.h26
-rw-r--r--contrib/llvm/include/llvm/TableGen/Record.h1625
-rw-r--r--contrib/llvm/include/llvm/TableGen/TableGenAction.h35
-rw-r--r--contrib/llvm/include/llvm/TableGen/TableGenBackend.h43
-rw-r--r--contrib/llvm/include/llvm/Target/Mangler.h73
-rw-r--r--contrib/llvm/include/llvm/Target/Target.td928
-rw-r--r--contrib/llvm/include/llvm/Target/TargetCallingConv.h144
-rw-r--r--contrib/llvm/include/llvm/Target/TargetCallingConv.td146
-rw-r--r--contrib/llvm/include/llvm/Target/TargetData.h363
-rw-r--r--contrib/llvm/include/llvm/Target/TargetELFWriterInfo.h120
-rw-r--r--contrib/llvm/include/llvm/Target/TargetFrameLowering.h193
-rw-r--r--contrib/llvm/include/llvm/Target/TargetInstrInfo.h885
-rw-r--r--contrib/llvm/include/llvm/Target/TargetIntrinsicInfo.h64
-rw-r--r--contrib/llvm/include/llvm/Target/TargetJITInfo.h137
-rw-r--r--contrib/llvm/include/llvm/Target/TargetLibraryInfo.h293
-rw-r--r--contrib/llvm/include/llvm/Target/TargetLowering.h2051
-rw-r--r--contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h147
-rw-r--r--contrib/llvm/include/llvm/Target/TargetMachine.h333
-rw-r--r--contrib/llvm/include/llvm/Target/TargetOpcodes.h95
-rw-r--r--contrib/llvm/include/llvm/Target/TargetOptions.h191
-rw-r--r--contrib/llvm/include/llvm/Target/TargetRegisterInfo.h747
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSchedule.td130
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSelectionDAG.td1018
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSelectionDAGInfo.h101
-rw-r--r--contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h68
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO.h198
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h90
-rw-r--r--contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h149
-rw-r--r--contrib/llvm/include/llvm/Transforms/Instrumentation.h43
-rw-r--r--contrib/llvm/include/llvm/Transforms/Scalar.h369
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h108
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h211
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h112
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/Cloning.h206
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h66
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/FunctionUtils.h45
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/Local.h187
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h33
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h45
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h166
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h456
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h54
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h51
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h33
-rw-r--r--contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h80
-rw-r--r--contrib/llvm/include/llvm/Transforms/Vectorize.h115
-rw-r--r--contrib/llvm/include/llvm/Type.h453
-rw-r--r--contrib/llvm/include/llvm/Use.h219
-rw-r--r--contrib/llvm/include/llvm/User.h177
-rw-r--r--contrib/llvm/include/llvm/Value.h415
-rw-r--r--contrib/llvm/include/llvm/ValueSymbolTable.h133
495 files changed, 140534 insertions, 0 deletions
diff --git a/contrib/llvm/include/llvm-c/Analysis.h b/contrib/llvm/include/llvm-c/Analysis.h
new file mode 100644
index 000000000000..f0bdddc50ab7
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Analysis.h
@@ -0,0 +1,65 @@
+/*===-- llvm-c/Analysis.h - Analysis Library 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 libLLVMAnalysis.a, which *|
+|* implements various analyses of the LLVM IR. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_ANALYSIS_H
+#define LLVM_C_ANALYSIS_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCAnalysis Analysis
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+typedef enum {
+ LLVMAbortProcessAction, /* verifier will print to stderr and abort() */
+ LLVMPrintMessageAction, /* verifier will print to stderr and return 1 */
+ LLVMReturnStatusAction /* verifier will just return 1 */
+} LLVMVerifierFailureAction;
+
+
+/* Verifies that a module is valid, taking the specified action if not.
+ Optionally returns a human-readable description of any invalid constructs.
+ OutMessage must be disposed with LLVMDisposeMessage. */
+LLVMBool LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action,
+ char **OutMessage);
+
+/* Verifies that a single function is valid, taking the specified action. Useful
+ for debugging. */
+LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action);
+
+/* Open up a ghostview window that displays the CFG of the current function.
+ Useful for debugging. */
+void LLVMViewFunctionCFG(LLVMValueRef Fn);
+void LLVMViewFunctionCFGOnly(LLVMValueRef Fn);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/BitReader.h b/contrib/llvm/include/llvm-c/BitReader.h
new file mode 100644
index 000000000000..522803518398
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/BitReader.h
@@ -0,0 +1,76 @@
+/*===-- llvm-c/BitReader.h - BitReader Library 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 libLLVMBitReader.a, which *|
+|* implements input of the LLVM bitcode format. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_BITCODEREADER_H
+#define LLVM_C_BITCODEREADER_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCBitReader Bit Reader
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+/* Builds a module from the bitcode in the specified memory buffer, returning a
+ reference to the module via the OutModule parameter. Returns 0 on success.
+ Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutModule, char **OutMessage);
+
+LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutModule, char **OutMessage);
+
+/** Reads a module from the specified path, returning via the OutMP parameter
+ a module provider which performs lazy deserialization. Returns 0 on success.
+ Optionally returns a human-readable error message via OutMessage. */
+LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleRef *OutM,
+ char **OutMessage);
+
+LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM,
+ char **OutMessage);
+
+
+/** Deprecated: Use LLVMGetBitcodeModuleInContext instead. */
+LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef,
+ LLVMMemoryBufferRef MemBuf,
+ LLVMModuleProviderRef *OutMP,
+ char **OutMessage);
+
+/** Deprecated: Use LLVMGetBitcodeModule instead. */
+LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf,
+ LLVMModuleProviderRef *OutMP,
+ char **OutMessage);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/BitWriter.h b/contrib/llvm/include/llvm-c/BitWriter.h
new file mode 100644
index 000000000000..ba5a6778c942
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/BitWriter.h
@@ -0,0 +1,56 @@
+/*===-- llvm-c/BitWriter.h - BitWriter Library 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 libLLVMBitWriter.a, which *|
+|* implements output of the LLVM bitcode format. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_BITCODEWRITER_H
+#define LLVM_C_BITCODEWRITER_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCBitWriter Bit Writer
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+/*===-- Operations on modules ---------------------------------------------===*/
+
+/** Writes a module to the specified path. Returns 0 on success. */
+int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path);
+
+/** Writes a module to an open file descriptor. Returns 0 on success. */
+int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose,
+ int Unbuffered);
+
+/** Deprecated for LLVMWriteBitcodeToFD. Writes a module to an open file
+ descriptor. Returns 0 on success. Closes the Handle. */
+int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Core.h b/contrib/llvm/include/llvm-c/Core.h
new file mode 100644
index 000000000000..77746069a25c
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Core.h
@@ -0,0 +1,2697 @@
+/*===-- llvm-c/Core.h - Core Library 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 libLLVMCore.a, which implements *|
+|* the LLVM intermediate representation. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_CORE_H
+#define LLVM_C_CORE_H
+
+#include "llvm/Support/DataTypes.h"
+
+#ifdef __cplusplus
+
+/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap'
+ and 'unwrap' conversion functions. */
+#include "llvm/Module.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/Support/IRBuilder.h"
+
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMC LLVM-C: C interface to LLVM
+ *
+ * This module exposes parts of the LLVM library as a C API.
+ *
+ * @{
+ */
+
+/**
+ * @defgroup LLVMCTransforms Transforms
+ */
+
+/**
+ * @defgroup LLVMCCore Core
+ *
+ * This modules provide an interface to libLLVMCore, which implements
+ * the LLVM intermediate representation as well as other related types
+ * and utilities.
+ *
+ * LLVM uses a polymorphic type hierarchy which C cannot represent, therefore
+ * parameters must be passed as base types. Despite the declared types, most
+ * of the functions provided operate only on branches of the type hierarchy.
+ * The declared parameter names are descriptive and specify which type is
+ * required. Additionally, each type hierarchy is documented along with the
+ * functions that operate upon it. For more detail, refer to LLVM's C++ code.
+ * If in doubt, refer to Core.cpp, which performs paramter downcasts in the
+ * form unwrap<RequiredType>(Param).
+ *
+ * Many exotic languages can interoperate with C code but have a harder time
+ * with C++ due to name mangling. So in addition to C, this interface enables
+ * tools written in such languages.
+ *
+ * When included into a C++ source file, also declares 'wrap' and 'unwrap'
+ * helpers to perform opaque reference<-->pointer conversions. These helpers
+ * are shorter and more tightly typed than writing the casts by hand when
+ * authoring bindings. In assert builds, they will do runtime type checking.
+ *
+ * @{
+ */
+
+/**
+ * @defgroup LLVMCCoreTypes Types and Enumerations
+ *
+ * @{
+ */
+
+typedef int LLVMBool;
+
+/* Opaque types. */
+
+/**
+ * The top-level container for all LLVM global data. See the LLVMContext class.
+ */
+typedef struct LLVMOpaqueContext *LLVMContextRef;
+
+/**
+ * The top-level container for all other LLVM Intermediate Representation (IR)
+ * objects.
+ *
+ * @see llvm::Module
+ */
+typedef struct LLVMOpaqueModule *LLVMModuleRef;
+
+/**
+ * Each value in the LLVM IR has a type, an LLVMTypeRef.
+ *
+ * @see llvm::Type
+ */
+typedef struct LLVMOpaqueType *LLVMTypeRef;
+
+/**
+ * Represents an individual value in LLVM IR.
+ *
+ * This models llvm::Value.
+ */
+typedef struct LLVMOpaqueValue *LLVMValueRef;
+
+/**
+ * Represents a basic block of instruction in LLVM IR.
+ *
+ * This models llvm::BasicBlock.
+ */
+typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
+
+/**
+ * Represents an LLVM basic block builder.
+ *
+ * This models llvm::IRBuilder.
+ */
+typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
+
+/**
+ * Interface used to provide a module to JIT or interpreter.
+ * This is now just a synonym for llvm::Module, but we have to keep using the
+ * different type to keep binary compatibility.
+ */
+typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
+
+/**
+ * Used to provide a module to JIT or interpreter.
+ *
+ * @see llvm::MemoryBuffer
+ */
+typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
+
+/** @see llvm::PassManagerBase */
+typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
+
+/** @see llvm::PassRegistry */
+typedef struct LLVMOpaquePassRegistry *LLVMPassRegistryRef;
+
+/**
+ * Used to get the users and usees of a Value.
+ *
+ * @see llvm::Use */
+typedef struct LLVMOpaqueUse *LLVMUseRef;
+
+typedef enum {
+ LLVMZExtAttribute = 1<<0,
+ LLVMSExtAttribute = 1<<1,
+ LLVMNoReturnAttribute = 1<<2,
+ LLVMInRegAttribute = 1<<3,
+ LLVMStructRetAttribute = 1<<4,
+ LLVMNoUnwindAttribute = 1<<5,
+ LLVMNoAliasAttribute = 1<<6,
+ LLVMByValAttribute = 1<<7,
+ LLVMNestAttribute = 1<<8,
+ LLVMReadNoneAttribute = 1<<9,
+ LLVMReadOnlyAttribute = 1<<10,
+ LLVMNoInlineAttribute = 1<<11,
+ LLVMAlwaysInlineAttribute = 1<<12,
+ LLVMOptimizeForSizeAttribute = 1<<13,
+ LLVMStackProtectAttribute = 1<<14,
+ LLVMStackProtectReqAttribute = 1<<15,
+ LLVMAlignment = 31<<16,
+ LLVMNoCaptureAttribute = 1<<21,
+ LLVMNoRedZoneAttribute = 1<<22,
+ LLVMNoImplicitFloatAttribute = 1<<23,
+ LLVMNakedAttribute = 1<<24,
+ LLVMInlineHintAttribute = 1<<25,
+ LLVMStackAlignment = 7<<26,
+ LLVMReturnsTwice = 1 << 29,
+ LLVMUWTable = 1 << 30,
+ LLVMNonLazyBind = 1 << 31
+
+ // FIXME: This attribute is currently not included in the C API as
+ // a temporary measure until the API/ABI impact to the C API is understood
+ // and the path forward agreed upon.
+ //LLVMAddressSafety = 1ULL << 32
+} LLVMAttribute;
+
+typedef enum {
+ /* Terminator Instructions */
+ LLVMRet = 1,
+ LLVMBr = 2,
+ LLVMSwitch = 3,
+ LLVMIndirectBr = 4,
+ LLVMInvoke = 5,
+ /* removed 6 due to API changes */
+ LLVMUnreachable = 7,
+
+ /* Standard Binary Operators */
+ LLVMAdd = 8,
+ LLVMFAdd = 9,
+ LLVMSub = 10,
+ LLVMFSub = 11,
+ LLVMMul = 12,
+ LLVMFMul = 13,
+ LLVMUDiv = 14,
+ LLVMSDiv = 15,
+ LLVMFDiv = 16,
+ LLVMURem = 17,
+ LLVMSRem = 18,
+ LLVMFRem = 19,
+
+ /* Logical Operators */
+ LLVMShl = 20,
+ LLVMLShr = 21,
+ LLVMAShr = 22,
+ LLVMAnd = 23,
+ LLVMOr = 24,
+ LLVMXor = 25,
+
+ /* Memory Operators */
+ LLVMAlloca = 26,
+ LLVMLoad = 27,
+ LLVMStore = 28,
+ LLVMGetElementPtr = 29,
+
+ /* Cast Operators */
+ LLVMTrunc = 30,
+ LLVMZExt = 31,
+ LLVMSExt = 32,
+ LLVMFPToUI = 33,
+ LLVMFPToSI = 34,
+ LLVMUIToFP = 35,
+ LLVMSIToFP = 36,
+ LLVMFPTrunc = 37,
+ LLVMFPExt = 38,
+ LLVMPtrToInt = 39,
+ LLVMIntToPtr = 40,
+ LLVMBitCast = 41,
+
+ /* Other Operators */
+ LLVMICmp = 42,
+ LLVMFCmp = 43,
+ LLVMPHI = 44,
+ LLVMCall = 45,
+ LLVMSelect = 46,
+ LLVMUserOp1 = 47,
+ LLVMUserOp2 = 48,
+ LLVMVAArg = 49,
+ LLVMExtractElement = 50,
+ LLVMInsertElement = 51,
+ LLVMShuffleVector = 52,
+ LLVMExtractValue = 53,
+ LLVMInsertValue = 54,
+
+ /* Atomic operators */
+ LLVMFence = 55,
+ LLVMAtomicCmpXchg = 56,
+ LLVMAtomicRMW = 57,
+
+ /* Exception Handling Operators */
+ LLVMResume = 58,
+ LLVMLandingPad = 59
+
+} LLVMOpcode;
+
+typedef enum {
+ LLVMVoidTypeKind, /**< type with no size */
+ LLVMHalfTypeKind, /**< 16 bit floating point type */
+ LLVMFloatTypeKind, /**< 32 bit floating point type */
+ LLVMDoubleTypeKind, /**< 64 bit floating point type */
+ LLVMX86_FP80TypeKind, /**< 80 bit floating point type (X87) */
+ LLVMFP128TypeKind, /**< 128 bit floating point type (112-bit mantissa)*/
+ LLVMPPC_FP128TypeKind, /**< 128 bit floating point type (two 64-bits) */
+ LLVMLabelTypeKind, /**< Labels */
+ LLVMIntegerTypeKind, /**< Arbitrary bit width integers */
+ LLVMFunctionTypeKind, /**< Functions */
+ LLVMStructTypeKind, /**< Structures */
+ LLVMArrayTypeKind, /**< Arrays */
+ LLVMPointerTypeKind, /**< Pointers */
+ LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
+ LLVMMetadataTypeKind, /**< Metadata */
+ LLVMX86_MMXTypeKind /**< X86 MMX */
+} LLVMTypeKind;
+
+typedef enum {
+ LLVMExternalLinkage, /**< Externally visible function */
+ LLVMAvailableExternallyLinkage,
+ LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/
+ LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something
+ equivalent. */
+ LLVMWeakAnyLinkage, /**< Keep one copy of function when linking (weak) */
+ LLVMWeakODRLinkage, /**< Same, but only replaced by something
+ equivalent. */
+ LLVMAppendingLinkage, /**< Special purpose, only applies to global arrays */
+ LLVMInternalLinkage, /**< Rename collisions when linking (static
+ functions) */
+ LLVMPrivateLinkage, /**< Like Internal, but omit from symbol table */
+ LLVMDLLImportLinkage, /**< Function to be imported from DLL */
+ LLVMDLLExportLinkage, /**< Function to be accessible from DLL */
+ LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
+ LLVMGhostLinkage, /**< Obsolete */
+ LLVMCommonLinkage, /**< Tentative definitions */
+ LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */
+ LLVMLinkerPrivateWeakLinkage, /**< Like LinkerPrivate, but is weak. */
+ LLVMLinkerPrivateWeakDefAutoLinkage /**< Like LinkerPrivateWeak, but possibly
+ hidden. */
+} LLVMLinkage;
+
+typedef enum {
+ LLVMDefaultVisibility, /**< The GV is visible */
+ LLVMHiddenVisibility, /**< The GV is hidden */
+ LLVMProtectedVisibility /**< The GV is protected */
+} LLVMVisibility;
+
+typedef enum {
+ LLVMCCallConv = 0,
+ LLVMFastCallConv = 8,
+ LLVMColdCallConv = 9,
+ LLVMX86StdcallCallConv = 64,
+ LLVMX86FastcallCallConv = 65
+} LLVMCallConv;
+
+typedef enum {
+ LLVMIntEQ = 32, /**< equal */
+ LLVMIntNE, /**< not equal */
+ LLVMIntUGT, /**< unsigned greater than */
+ LLVMIntUGE, /**< unsigned greater or equal */
+ LLVMIntULT, /**< unsigned less than */
+ LLVMIntULE, /**< unsigned less or equal */
+ LLVMIntSGT, /**< signed greater than */
+ LLVMIntSGE, /**< signed greater or equal */
+ LLVMIntSLT, /**< signed less than */
+ LLVMIntSLE /**< signed less or equal */
+} LLVMIntPredicate;
+
+typedef enum {
+ LLVMRealPredicateFalse, /**< Always false (always folded) */
+ LLVMRealOEQ, /**< True if ordered and equal */
+ LLVMRealOGT, /**< True if ordered and greater than */
+ LLVMRealOGE, /**< True if ordered and greater than or equal */
+ LLVMRealOLT, /**< True if ordered and less than */
+ LLVMRealOLE, /**< True if ordered and less than or equal */
+ LLVMRealONE, /**< True if ordered and operands are unequal */
+ LLVMRealORD, /**< True if ordered (no nans) */
+ LLVMRealUNO, /**< True if unordered: isnan(X) | isnan(Y) */
+ LLVMRealUEQ, /**< True if unordered or equal */
+ LLVMRealUGT, /**< True if unordered or greater than */
+ LLVMRealUGE, /**< True if unordered, greater than, or equal */
+ LLVMRealULT, /**< True if unordered or less than */
+ LLVMRealULE, /**< True if unordered, less than, or equal */
+ LLVMRealUNE, /**< True if unordered or not equal */
+ LLVMRealPredicateTrue /**< Always true (always folded) */
+} LLVMRealPredicate;
+
+typedef enum {
+ LLVMLandingPadCatch, /**< A catch clause */
+ LLVMLandingPadFilter /**< A filter clause */
+} LLVMLandingPadClauseTy;
+
+/**
+ * @}
+ */
+
+void LLVMInitializeCore(LLVMPassRegistryRef R);
+
+
+/*===-- Error handling ----------------------------------------------------===*/
+
+void LLVMDisposeMessage(char *Message);
+
+
+/**
+ * @defgroup LLVMCCoreContext Contexts
+ *
+ * Contexts are execution states for the core LLVM IR system.
+ *
+ * Most types are tied to a context instance. Multiple contexts can
+ * exist simultaneously. A single context is not thread safe. However,
+ * different contexts can execute on different threads simultaneously.
+ *
+ * @{
+ */
+
+/**
+ * Create a new context.
+ *
+ * Every call to this function should be paired with a call to
+ * LLVMContextDispose() or the context will leak memory.
+ */
+LLVMContextRef LLVMContextCreate(void);
+
+/**
+ * Obtain the global context instance.
+ */
+LLVMContextRef LLVMGetGlobalContext(void);
+
+/**
+ * Destroy a context instance.
+ *
+ * This should be called for every call to LLVMContextCreate() or memory
+ * will be leaked.
+ */
+void LLVMContextDispose(LLVMContextRef C);
+
+unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name,
+ unsigned SLen);
+unsigned LLVMGetMDKindID(const char* Name, unsigned SLen);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreModule Modules
+ *
+ * Modules represent the top-level structure in a LLVM program. An LLVM
+ * module is effectively a translation unit or a collection of
+ * translation units merged together.
+ *
+ * @{
+ */
+
+/**
+ * Create a new, empty module in the global context.
+ *
+ * This is equivalent to calling LLVMModuleCreateWithNameInContext with
+ * LLVMGetGlobalContext() as the context parameter.
+ *
+ * Every invocation should be paired with LLVMDisposeModule() or memory
+ * will be leaked.
+ */
+LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID);
+
+/**
+ * Create a new, empty module in a specific context.
+ *
+ * Every invocation should be paired with LLVMDisposeModule() or memory
+ * will be leaked.
+ */
+LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID,
+ LLVMContextRef C);
+
+/**
+ * Destroy a module instance.
+ *
+ * This must be called for every created module or memory will be
+ * leaked.
+ */
+void LLVMDisposeModule(LLVMModuleRef M);
+
+/**
+ * Obtain the data layout for a module.
+ *
+ * @see Module::getDataLayout()
+ */
+const char *LLVMGetDataLayout(LLVMModuleRef M);
+
+/**
+ * Set the data layout for a module.
+ *
+ * @see Module::setDataLayout()
+ */
+void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple);
+
+/**
+ * Obtain the target triple for a module.
+ *
+ * @see Module::getTargetTriple()
+ */
+const char *LLVMGetTarget(LLVMModuleRef M);
+
+/**
+ * Set the target triple for a module.
+ *
+ * @see Module::setTargetTriple()
+ */
+void LLVMSetTarget(LLVMModuleRef M, const char *Triple);
+
+/**
+ * Dump a representation of a module to stderr.
+ *
+ * @see Module::dump()
+ */
+void LLVMDumpModule(LLVMModuleRef M);
+
+/**
+ * Set inline assembly for a module.
+ *
+ * @see Module::setModuleInlineAsm()
+ */
+void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm);
+
+/**
+ * Obtain the context to which this module is associated.
+ *
+ * @see Module::getContext()
+ */
+LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M);
+
+/**
+ * Obtain a Type from a module by its registered name.
+ */
+LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
+
+/**
+ * Obtain the number of operands for named metadata in a module.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ */
+unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name);
+
+/**
+ * Obtain the named metadata operands for a module.
+ *
+ * The passed LLVMValueRef pointer should refer to an array of
+ * LLVMValueRef at least LLVMGetNamedMetadataNumOperands long. This
+ * array will be populated with the LLVMValueRef instances. Each
+ * instance corresponds to a llvm::MDNode.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ * @see llvm::MDNode::getOperand()
+ */
+void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest);
+
+/**
+ * Add an operand to named metadata.
+ *
+ * @see llvm::Module::getNamedMetadata()
+ * @see llvm::MDNode::addOperand()
+ */
+void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name,
+ LLVMValueRef Val);
+
+/**
+ * Add a function to a module under a specified name.
+ *
+ * @see llvm::Function::Create()
+ */
+LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
+ LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain a Function value from a Module by its name.
+ *
+ * The returned value corresponds to a llvm::Function value.
+ *
+ * @see llvm::Module::getFunction()
+ */
+LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name);
+
+/**
+ * Obtain an iterator to the first Function in a Module.
+ *
+ * @see llvm::Module::begin()
+ */
+LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M);
+
+/**
+ * Obtain an iterator to the last Function in a Module.
+ *
+ * @see llvm::Module::end()
+ */
+LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M);
+
+/**
+ * Advance a Function iterator to the next Function.
+ *
+ * Returns NULL if the iterator was already at the end and there are no more
+ * functions.
+ */
+LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn);
+
+/**
+ * Decrement a Function iterator to the previous Function.
+ *
+ * Returns NULL if the iterator was already at the beginning and there are
+ * no previous functions.
+ */
+LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreType Types
+ *
+ * Types represent the type of a value.
+ *
+ * Types are associated with a context instance. The context internally
+ * deduplicates types so there is only 1 instance of a specific type
+ * alive at a time. In other words, a unique type is shared among all
+ * consumers within a context.
+ *
+ * A Type in the C API corresponds to llvm::Type.
+ *
+ * Types have the following hierarchy:
+ *
+ * types:
+ * integer type
+ * real type
+ * function type
+ * sequence types:
+ * array type
+ * pointer type
+ * vector type
+ * void type
+ * label type
+ * opaque type
+ *
+ * @{
+ */
+
+/**
+ * Obtain the enumerated type of a Type instance.
+ *
+ * @see llvm::Type:getTypeID()
+ */
+LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty);
+
+/**
+ * Whether the type has a known size.
+ *
+ * Things that don't have a size are abstract types, labels, and void.a
+ *
+ * @see llvm::Type::isSized()
+ */
+LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty);
+
+/**
+ * Obtain the context to which this type instance is associated.
+ *
+ * @see llvm::Type::getContext()
+ */
+LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty);
+
+/**
+ * @defgroup LLVMCCoreTypeInt Integer Types
+ *
+ * Functions in this section operate on integer types.
+ *
+ * @{
+ */
+
+/**
+ * Obtain an integer type from a context with specified bit width.
+ */
+LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C);
+LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits);
+
+/**
+ * Obtain an integer type from the global context with a specified bit
+ * width.
+ */
+LLVMTypeRef LLVMInt1Type(void);
+LLVMTypeRef LLVMInt8Type(void);
+LLVMTypeRef LLVMInt16Type(void);
+LLVMTypeRef LLVMInt32Type(void);
+LLVMTypeRef LLVMInt64Type(void);
+LLVMTypeRef LLVMIntType(unsigned NumBits);
+unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeFloat Floating Point Types
+ *
+ * @{
+ */
+
+/**
+ * Obtain a 16-bit floating point type from a context.
+ */
+LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 32-bit floating point type from a context.
+ */
+LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 64-bit floating point type from a context.
+ */
+LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 80-bit floating point type (X87) from a context.
+ */
+LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 128-bit floating point type (112-bit mantissa) from a
+ * context.
+ */
+LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a 128-bit floating point type (two 64-bits) from a context.
+ */
+LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C);
+
+/**
+ * Obtain a floating point type from the global context.
+ *
+ * These map to the functions in this group of the same name.
+ */
+LLVMTypeRef LLVMHalfType(void);
+LLVMTypeRef LLVMFloatType(void);
+LLVMTypeRef LLVMDoubleType(void);
+LLVMTypeRef LLVMX86FP80Type(void);
+LLVMTypeRef LLVMFP128Type(void);
+LLVMTypeRef LLVMPPCFP128Type(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeFunction Function Types
+ *
+ * @{
+ */
+
+/**
+ * Obtain a function type consisting of a specified signature.
+ *
+ * The function is defined as a tuple of a return Type, a list of
+ * parameter types, and whether the function is variadic.
+ */
+LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType,
+ LLVMTypeRef *ParamTypes, unsigned ParamCount,
+ LLVMBool IsVarArg);
+
+/**
+ * Returns whether a function type is variadic.
+ */
+LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain the Type this function Type returns.
+ */
+LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain the number of parameters this function accepts.
+ */
+unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy);
+
+/**
+ * Obtain the types of a function's parameters.
+ *
+ * The Dest parameter should point to a pre-allocated array of
+ * LLVMTypeRef at least LLVMCountParamTypes() large. On return, the
+ * first LLVMCountParamTypes() entries in the array will be populated
+ * with LLVMTypeRef instances.
+ *
+ * @param FunctionTy The function type to operate on.
+ * @param Dest Memory address of an array to be filled with result.
+ */
+void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeStruct Structure Types
+ *
+ * These functions relate to LLVMTypeRef instances.
+ *
+ * @see llvm::StructType
+ *
+ * @{
+ */
+
+/**
+ * Create a new structure type in a context.
+ *
+ * A structure is specified by a list of inner elements/types and
+ * whether these can be packed together.
+ *
+ * @see llvm::StructType::create()
+ */
+LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes,
+ unsigned ElementCount, LLVMBool Packed);
+
+/**
+ * Create a new structure type in the global context.
+ *
+ * @see llvm::StructType::create()
+ */
+LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount,
+ LLVMBool Packed);
+
+/**
+ * Create an empty structure in a context having a specified name.
+ *
+ * @see llvm::StructType::create()
+ */
+LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name);
+
+/**
+ * Obtain the name of a structure.
+ *
+ * @see llvm::StructType::getName()
+ */
+const char *LLVMGetStructName(LLVMTypeRef Ty);
+
+/**
+ * Set the contents of a structure type.
+ *
+ * @see llvm::StructType::setBody()
+ */
+void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes,
+ unsigned ElementCount, LLVMBool Packed);
+
+/**
+ * Get the number of elements defined inside the structure.
+ *
+ * @see llvm::StructType::getNumElements()
+ */
+unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
+
+/**
+ * Get the elements within a structure.
+ *
+ * The function is passed the address of a pre-allocated array of
+ * LLVMTypeRef at least LLVMCountStructElementTypes() long. After
+ * invocation, this array will be populated with the structure's
+ * elements. The objects in the destination array will have a lifetime
+ * of the structure type itself, which is the lifetime of the context it
+ * is contained in.
+ */
+void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
+
+/**
+ * Determine whether a structure is packed.
+ *
+ * @see llvm::StructType::isPacked()
+ */
+LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy);
+
+/**
+ * Determine whether a structure is opaque.
+ *
+ * @see llvm::StructType::isOpaque()
+ */
+LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup LLVMCCoreTypeSequential Sequential Types
+ *
+ * Sequential types represents "arrays" of types. This is a super class
+ * for array, vector, and pointer types.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the type of elements within a sequential type.
+ *
+ * This works on array, vector, and pointer types.
+ *
+ * @see llvm::SequentialType::getElementType()
+ */
+LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty);
+
+/**
+ * Create a fixed size array type that refers to a specific type.
+ *
+ * The created type will exist in the context that its element type
+ * exists in.
+ *
+ * @see llvm::ArrayType::get()
+ */
+LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount);
+
+/**
+ * Obtain the length of an array type.
+ *
+ * This only works on types that represent arrays.
+ *
+ * @see llvm::ArrayType::getNumElements()
+ */
+unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy);
+
+/**
+ * Create a pointer type that points to a defined type.
+ *
+ * The created type will exist in the context that its pointee type
+ * exists in.
+ *
+ * @see llvm::PointerType::get()
+ */
+LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace);
+
+/**
+ * Obtain the address space of a pointer type.
+ *
+ * This only works on types that represent pointers.
+ *
+ * @see llvm::PointerType::getAddressSpace()
+ */
+unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy);
+
+/**
+ * Create a vector type that contains a defined type and has a specific
+ * number of elements.
+ *
+ * The created type will exist in the context thats its element type
+ * exists in.
+ *
+ * @see llvm::VectorType::get()
+ */
+LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount);
+
+/**
+ * Obtain the number of elements in a vector type.
+ *
+ * This only works on types that represent vectors.
+ *
+ * @see llvm::VectorType::getNumElements()
+ */
+unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreTypeOther Other Types
+ *
+ * @{
+ */
+
+/**
+ * Create a void type in a context.
+ */
+LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C);
+
+/**
+ * Create a label type in a context.
+ */
+LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C);
+
+/**
+ * Create a X86 MMX type in a context.
+ */
+LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C);
+
+/**
+ * These are similar to the above functions except they operate on the
+ * global context.
+ */
+LLVMTypeRef LLVMVoidType(void);
+LLVMTypeRef LLVMLabelType(void);
+LLVMTypeRef LLVMX86MMXType(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValues Values
+ *
+ * The bulk of LLVM's object model consists of values, which comprise a very
+ * rich type hierarchy.
+ *
+ * LLVMValueRef essentially represents llvm::Value. There is a rich
+ * hierarchy of classes within this type. Depending on the instance
+ * obtain, not all APIs are available.
+ *
+ * Callers can determine the type of a LLVMValueRef by calling the
+ * LLVMIsA* family of functions (e.g. LLVMIsAArgument()). These
+ * functions are defined by a macro, so it isn't obvious which are
+ * available by looking at the Doxygen source code. Instead, look at the
+ * source definition of LLVM_FOR_EACH_VALUE_SUBCLASS and note the list
+ * of value names given. These value names also correspond to classes in
+ * the llvm::Value hierarchy.
+ *
+ * @{
+ */
+
+#define LLVM_FOR_EACH_VALUE_SUBCLASS(macro) \
+ macro(Argument) \
+ macro(BasicBlock) \
+ macro(InlineAsm) \
+ macro(MDNode) \
+ macro(MDString) \
+ macro(User) \
+ macro(Constant) \
+ macro(BlockAddress) \
+ macro(ConstantAggregateZero) \
+ macro(ConstantArray) \
+ macro(ConstantExpr) \
+ macro(ConstantFP) \
+ macro(ConstantInt) \
+ macro(ConstantPointerNull) \
+ macro(ConstantStruct) \
+ macro(ConstantVector) \
+ macro(GlobalValue) \
+ macro(Function) \
+ macro(GlobalAlias) \
+ macro(GlobalVariable) \
+ macro(UndefValue) \
+ macro(Instruction) \
+ macro(BinaryOperator) \
+ macro(CallInst) \
+ macro(IntrinsicInst) \
+ macro(DbgInfoIntrinsic) \
+ macro(DbgDeclareInst) \
+ macro(MemIntrinsic) \
+ macro(MemCpyInst) \
+ macro(MemMoveInst) \
+ macro(MemSetInst) \
+ macro(CmpInst) \
+ macro(FCmpInst) \
+ macro(ICmpInst) \
+ macro(ExtractElementInst) \
+ macro(GetElementPtrInst) \
+ macro(InsertElementInst) \
+ macro(InsertValueInst) \
+ macro(LandingPadInst) \
+ macro(PHINode) \
+ macro(SelectInst) \
+ macro(ShuffleVectorInst) \
+ macro(StoreInst) \
+ macro(TerminatorInst) \
+ macro(BranchInst) \
+ macro(IndirectBrInst) \
+ macro(InvokeInst) \
+ macro(ReturnInst) \
+ macro(SwitchInst) \
+ macro(UnreachableInst) \
+ macro(ResumeInst) \
+ macro(UnaryInstruction) \
+ macro(AllocaInst) \
+ macro(CastInst) \
+ macro(BitCastInst) \
+ macro(FPExtInst) \
+ macro(FPToSIInst) \
+ macro(FPToUIInst) \
+ macro(FPTruncInst) \
+ macro(IntToPtrInst) \
+ macro(PtrToIntInst) \
+ macro(SExtInst) \
+ macro(SIToFPInst) \
+ macro(TruncInst) \
+ macro(UIToFPInst) \
+ macro(ZExtInst) \
+ macro(ExtractValueInst) \
+ macro(LoadInst) \
+ macro(VAArgInst)
+
+/**
+ * @defgroup LLVMCCoreValueGeneral General APIs
+ *
+ * Functions in this section work on all LLVMValueRef instances,
+ * regardless of their sub-type. They correspond to functions available
+ * on llvm::Value.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the type of a value.
+ *
+ * @see llvm::Value::getType()
+ */
+LLVMTypeRef LLVMTypeOf(LLVMValueRef Val);
+
+/**
+ * Obtain the string name of a value.
+ *
+ * @see llvm::Value::getName()
+ */
+const char *LLVMGetValueName(LLVMValueRef Val);
+
+/**
+ * Set the string name of a value.
+ *
+ * @see llvm::Value::setName()
+ */
+void LLVMSetValueName(LLVMValueRef Val, const char *Name);
+
+/**
+ * Dump a representation of a value to stderr.
+ *
+ * @see llvm::Value::dump()
+ */
+void LLVMDumpValue(LLVMValueRef Val);
+
+/**
+ * Replace all uses of a value with another one.
+ *
+ * @see llvm::Value::replaceAllUsesWith()
+ */
+void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal);
+
+/**
+ * Determine whether the specified constant instance is constant.
+ */
+LLVMBool LLVMIsConstant(LLVMValueRef Val);
+
+/**
+ * Determine whether a value instance is undefined.
+ */
+LLVMBool LLVMIsUndef(LLVMValueRef Val);
+
+/**
+ * Convert value instances between types.
+ *
+ * Internally, a LLVMValueRef is "pinned" to a specific type. This
+ * series of functions allows you to cast an instance to a specific
+ * type.
+ *
+ * If the cast is not valid for the specified type, NULL is returned.
+ *
+ * @see llvm::dyn_cast_or_null<>
+ */
+#define LLVM_DECLARE_VALUE_CAST(name) \
+ LLVMValueRef LLVMIsA##name(LLVMValueRef Val);
+LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DECLARE_VALUE_CAST)
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueUses Usage
+ *
+ * This module defines functions that allow you to inspect the uses of a
+ * LLVMValueRef.
+ *
+ * It is possible to obtain a LLVMUseRef for any LLVMValueRef instance.
+ * Each LLVMUseRef (which corresponds to a llvm::Use instance) holds a
+ * llvm::User and llvm::Value.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the first use of a value.
+ *
+ * Uses are obtained in an iterator fashion. First, call this function
+ * to obtain a reference to the first use. Then, call LLVMGetNextUse()
+ * on that instance and all subsequently obtained instances untl
+ * LLVMGetNextUse() returns NULL.
+ *
+ * @see llvm::Value::use_begin()
+ */
+LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val);
+
+/**
+ * Obtain the next use of a value.
+ *
+ * This effectively advances the iterator. It returns NULL if you are on
+ * the final use and no more are available.
+ */
+LLVMUseRef LLVMGetNextUse(LLVMUseRef U);
+
+/**
+ * Obtain the user value for a user.
+ *
+ * The returned value corresponds to a llvm::User type.
+ *
+ * @see llvm::Use::getUser()
+ */
+LLVMValueRef LLVMGetUser(LLVMUseRef U);
+
+/**
+ * Obtain the value this use corresponds to.
+ *
+ * @see llvm::Use::get().
+ */
+LLVMValueRef LLVMGetUsedValue(LLVMUseRef U);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueUser User value
+ *
+ * Function in this group pertain to LLVMValueRef instances that descent
+ * from llvm::User. This includes constants, instructions, and
+ * operators.
+ *
+ * @{
+ */
+
+/**
+ * Obtain an operand at a specific index in a llvm::User value.
+ *
+ * @see llvm::User::getOperand()
+ */
+LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index);
+
+/**
+ * Set an operand at a specific index in a llvm::User value.
+ *
+ * @see llvm::User::setOperand()
+ */
+void LLVMSetOperand(LLVMValueRef User, unsigned Index, LLVMValueRef Val);
+
+/**
+ * Obtain the number of operands in a llvm::User value.
+ *
+ * @see llvm::User::getNumOperands()
+ */
+int LLVMGetNumOperands(LLVMValueRef Val);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstant Constants
+ *
+ * This section contains APIs for interacting with LLVMValueRef that
+ * correspond to llvm::Constant instances.
+ *
+ * These functions will work for any LLVMValueRef in the llvm::Constant
+ * class hierarchy.
+ *
+ * @{
+ */
+
+/**
+ * Obtain a constant value referring to the null instance of a type.
+ *
+ * @see llvm::Constant::getNullValue()
+ */
+LLVMValueRef LLVMConstNull(LLVMTypeRef Ty); /* all zeroes */
+
+/**
+ * Obtain a constant value referring to the instance of a type
+ * consisting of all ones.
+ *
+ * This is only valid for integer types.
+ *
+ * @see llvm::Constant::getAllOnesValue()
+ */
+LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty);
+
+/**
+ * Obtain a constant value referring to an undefined value of a type.
+ *
+ * @see llvm::UndefValue::get()
+ */
+LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty);
+
+/**
+ * Determine whether a value instance is null.
+ *
+ * @see llvm::Constant::isNullValue()
+ */
+LLVMBool LLVMIsNull(LLVMValueRef Val);
+
+/**
+ * Obtain a constant that is a constant pointer pointing to NULL for a
+ * specified type.
+ */
+LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty);
+
+/**
+ * @defgroup LLVMCCoreValueConstantScalar Scalar constants
+ *
+ * Functions in this group model LLVMValueRef instances that correspond
+ * to constants referring to scalar types.
+ *
+ * For integer types, the LLVMTypeRef parameter should correspond to a
+ * llvm::IntegerType instance and the returned LLVMValueRef will
+ * correspond to a llvm::ConstantInt.
+ *
+ * For floating point types, the LLVMTypeRef returned corresponds to a
+ * llvm::ConstantFP.
+ *
+ * @{
+ */
+
+/**
+ * Obtain a constant value for an integer type.
+ *
+ * The returned value corresponds to a llvm::ConstantInt.
+ *
+ * @see llvm::ConstantInt::get()
+ *
+ * @param IntTy Integer type to obtain value of.
+ * @param N The value the returned instance should refer to.
+ * @param SignExtend Whether to sign extend the produced value.
+ */
+LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N,
+ LLVMBool SignExtend);
+
+/**
+ * Obtain a constant value for an integer of arbitrary precision.
+ *
+ * @see llvm::ConstantInt::get()
+ */
+LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy,
+ unsigned NumWords,
+ const uint64_t Words[]);
+
+/**
+ * Obtain a constant value for an integer parsed from a string.
+ *
+ * A similar API, LLVMConstIntOfStringAndSize is also available. If the
+ * string's length is available, it is preferred to call that function
+ * instead.
+ *
+ * @see llvm::ConstantInt::get()
+ */
+LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char *Text,
+ uint8_t Radix);
+
+/**
+ * Obtain a constant value for an integer parsed from a string with
+ * specified length.
+ *
+ * @see llvm::ConstantInt::get()
+ */
+LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char *Text,
+ unsigned SLen, uint8_t Radix);
+
+/**
+ * Obtain a constant value referring to a double floating point value.
+ */
+LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N);
+
+/**
+ * Obtain a constant for a floating point value parsed from a string.
+ *
+ * A similar API, LLVMConstRealOfStringAndSize is also available. It
+ * should be used if the input string's length is known.
+ */
+LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text);
+
+/**
+ * Obtain a constant for a floating point value parsed from a string.
+ */
+LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char *Text,
+ unsigned SLen);
+
+/**
+ * Obtain the zero extended value for an integer constant value.
+ *
+ * @see llvm::ConstantInt::getZExtValue()
+ */
+unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal);
+
+/**
+ * Obtain the sign extended value for an integer constant value.
+ *
+ * @see llvm::ConstantInt::getSExtValue()
+ */
+long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstantComposite Composite Constants
+ *
+ * Functions in this group operate on composite constants.
+ *
+ * @{
+ */
+
+/**
+ * Create a ConstantDataSequential and initialize it with a string.
+ *
+ * @see llvm::ConstantDataArray::getString()
+ */
+LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str,
+ unsigned Length, LLVMBool DontNullTerminate);
+
+/**
+ * Create a ConstantDataSequential with string content in the global context.
+ *
+ * This is the same as LLVMConstStringInContext except it operates on the
+ * global context.
+ *
+ * @see LLVMConstStringInContext()
+ * @see llvm::ConstantDataArray::getString()
+ */
+LLVMValueRef LLVMConstString(const char *Str, unsigned Length,
+ LLVMBool DontNullTerminate);
+
+/**
+ * Create an anonymous ConstantStruct with the specified values.
+ *
+ * @see llvm::ConstantStruct::getAnon()
+ */
+LLVMValueRef LLVMConstStructInContext(LLVMContextRef C,
+ LLVMValueRef *ConstantVals,
+ unsigned Count, LLVMBool Packed);
+
+/**
+ * Create a ConstantStruct in the global Context.
+ *
+ * This is the same as LLVMConstStructInContext except it operates on the
+ * global Context.
+ *
+ * @see LLVMConstStructInContext()
+ */
+LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count,
+ LLVMBool Packed);
+
+/**
+ * Create a ConstantArray from values.
+ *
+ * @see llvm::ConstantArray::get()
+ */
+LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy,
+ LLVMValueRef *ConstantVals, unsigned Length);
+
+/**
+ * Create a non-anonymous ConstantStruct from values.
+ *
+ * @see llvm::ConstantStruct::get()
+ */
+LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy,
+ LLVMValueRef *ConstantVals,
+ unsigned Count);
+
+/**
+ * Create a ConstantVector from values.
+ *
+ * @see llvm::ConstantVector::get()
+ */
+LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstantExpressions Constant Expressions
+ *
+ * Functions in this group correspond to APIs on llvm::ConstantExpr.
+ *
+ * @see llvm::ConstantExpr.
+ *
+ * @{
+ */
+LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty);
+LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty);
+LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal);
+LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate,
+ LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate,
+ LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant);
+LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal,
+ LLVMValueRef *ConstantIndices, unsigned NumIndices);
+LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal,
+ LLVMValueRef *ConstantIndices,
+ unsigned NumIndices);
+LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal,
+ LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal,
+ LLVMTypeRef ToType);
+LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal,
+ LLVMTypeRef ToType);
+LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal,
+ LLVMTypeRef ToType);
+LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType,
+ LLVMBool isSigned);
+LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType);
+LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition,
+ LLVMValueRef ConstantIfTrue,
+ LLVMValueRef ConstantIfFalse);
+LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant,
+ LLVMValueRef IndexConstant);
+LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant,
+ LLVMValueRef ElementValueConstant,
+ LLVMValueRef IndexConstant);
+LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
+ LLVMValueRef VectorBConstant,
+ LLVMValueRef MaskConstant);
+LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
+ unsigned NumIdx);
+LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
+ LLVMValueRef ElementValueConstant,
+ unsigned *IdxList, unsigned NumIdx);
+LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty,
+ const char *AsmString, const char *Constraints,
+ LLVMBool HasSideEffects, LLVMBool IsAlignStack);
+LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueConstantGlobals Global Values
+ *
+ * This group contains functions that operate on global values. Functions in
+ * this group relate to functions in the llvm::GlobalValue class tree.
+ *
+ * @see llvm::GlobalValue
+ *
+ * @{
+ */
+
+LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global);
+LLVMBool LLVMIsDeclaration(LLVMValueRef Global);
+LLVMLinkage LLVMGetLinkage(LLVMValueRef Global);
+void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage);
+const char *LLVMGetSection(LLVMValueRef Global);
+void LLVMSetSection(LLVMValueRef Global, const char *Section);
+LLVMVisibility LLVMGetVisibility(LLVMValueRef Global);
+void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz);
+unsigned LLVMGetAlignment(LLVMValueRef Global);
+void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes);
+
+/**
+ * @defgroup LLVMCoreValueConstantGlobalVariable Global Variables
+ *
+ * This group contains functions that operate on global variable values.
+ *
+ * @see llvm::GlobalVariable
+ *
+ * @{
+ */
+LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty,
+ const char *Name,
+ unsigned AddressSpace);
+LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name);
+LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M);
+LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M);
+LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar);
+LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar);
+void LLVMDeleteGlobal(LLVMValueRef GlobalVar);
+LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar);
+void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal);
+LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar);
+void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal);
+LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar);
+void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCoreValueConstantGlobalAlias Global Aliases
+ *
+ * This group contains function that operate on global alias values.
+ *
+ * @see llvm::GlobalAlias
+ *
+ * @{
+ */
+LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
+ const char *Name);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueFunction Function values
+ *
+ * Functions in this group operate on LLVMValueRef instances that
+ * correspond to llvm::Function instances.
+ *
+ * @see llvm::Function
+ *
+ * @{
+ */
+
+/**
+ * Remove a function from its containing module and deletes it.
+ *
+ * @see llvm::Function::eraseFromParent()
+ */
+void LLVMDeleteFunction(LLVMValueRef Fn);
+
+/**
+ * Obtain the ID number from a function instance.
+ *
+ * @see llvm::Function::getIntrinsicID()
+ */
+unsigned LLVMGetIntrinsicID(LLVMValueRef Fn);
+
+/**
+ * Obtain the calling function of a function.
+ *
+ * The returned value corresponds to the LLVMCallConv enumeration.
+ *
+ * @see llvm::Function::getCallingConv()
+ */
+unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn);
+
+/**
+ * Set the calling convention of a function.
+ *
+ * @see llvm::Function::setCallingConv()
+ *
+ * @param Fn Function to operate on
+ * @param CC LLVMCallConv to set calling convention to
+ */
+void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC);
+
+/**
+ * Obtain the name of the garbage collector to use during code
+ * generation.
+ *
+ * @see llvm::Function::getGC()
+ */
+const char *LLVMGetGC(LLVMValueRef Fn);
+
+/**
+ * Define the garbage collector to use during code generation.
+ *
+ * @see llvm::Function::setGC()
+ */
+void LLVMSetGC(LLVMValueRef Fn, const char *Name);
+
+/**
+ * Add an attribute to a function.
+ *
+ * @see llvm::Function::addAttribute()
+ */
+void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);
+
+/**
+ * Obtain an attribute from a function.
+ *
+ * @see llvm::Function::getAttributes()
+ */
+LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn);
+
+/**
+ * Remove an attribute from a function.
+ */
+void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA);
+
+/**
+ * @defgroup LLVMCCoreValueFunctionParameters Function Parameters
+ *
+ * Functions in this group relate to arguments/parameters on functions.
+ *
+ * Functions in this group expect LLVMValueRef instances that correspond
+ * to llvm::Function instances.
+ *
+ * @{
+ */
+
+/**
+ * Obtain the number of parameters in a function.
+ *
+ * @see llvm::Function::arg_size()
+ */
+unsigned LLVMCountParams(LLVMValueRef Fn);
+
+/**
+ * Obtain the parameters in a function.
+ *
+ * The takes a pointer to a pre-allocated array of LLVMValueRef that is
+ * at least LLVMCountParams() long. This array will be filled with
+ * LLVMValueRef instances which correspond to the parameters the
+ * function receives. Each LLVMValueRef corresponds to a llvm::Argument
+ * instance.
+ *
+ * @see llvm::Function::arg_begin()
+ */
+void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params);
+
+/**
+ * Obtain the parameter at the specified index.
+ *
+ * Parameters are indexed from 0.
+ *
+ * @see llvm::Function::arg_begin()
+ */
+LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index);
+
+/**
+ * Obtain the function to which this argument belongs.
+ *
+ * Unlike other functions in this group, this one takes a LLVMValueRef
+ * that corresponds to a llvm::Attribute.
+ *
+ * The returned LLVMValueRef is the llvm::Function to which this
+ * argument belongs.
+ */
+LLVMValueRef LLVMGetParamParent(LLVMValueRef Inst);
+
+/**
+ * Obtain the first parameter to a function.
+ *
+ * @see llvm::Function::arg_begin()
+ */
+LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn);
+
+/**
+ * Obtain the last parameter to a function.
+ *
+ * @see llvm::Function::arg_end()
+ */
+LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn);
+
+/**
+ * Obtain the next parameter to a function.
+ *
+ * This takes a LLVMValueRef obtained from LLVMGetFirstParam() (which is
+ * actually a wrapped iterator) and obtains the next parameter from the
+ * underlying iterator.
+ */
+LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg);
+
+/**
+ * Obtain the previous parameter to a function.
+ *
+ * This is the opposite of LLVMGetNextParam().
+ */
+LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg);
+
+/**
+ * Add an attribute to a function argument.
+ *
+ * @see llvm::Argument::addAttr()
+ */
+void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA);
+
+/**
+ * Remove an attribute from a function argument.
+ *
+ * @see llvm::Argument::removeAttr()
+ */
+void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA);
+
+/**
+ * Get an attribute from a function argument.
+ */
+LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg);
+
+/**
+ * Set the alignment for a function parameter.
+ *
+ * @see llvm::Argument::addAttr()
+ * @see llvm::Attribute::constructAlignmentFromInt()
+ */
+void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueMetadata Metadata
+ *
+ * @{
+ */
+
+/**
+ * Obtain a MDString value from a context.
+ *
+ * The returned instance corresponds to the llvm::MDString class.
+ *
+ * The instance is specified by string data of a specified length. The
+ * string content is copied, so the backing memory can be freed after
+ * this function returns.
+ */
+LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str,
+ unsigned SLen);
+
+/**
+ * Obtain a MDString value from the global context.
+ */
+LLVMValueRef LLVMMDString(const char *Str, unsigned SLen);
+
+/**
+ * Obtain a MDNode value from a context.
+ *
+ * The returned value corresponds to the llvm::MDNode class.
+ */
+LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals,
+ unsigned Count);
+
+/**
+ * Obtain a MDNode value from the global context.
+ */
+LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count);
+
+/**
+ * Obtain the underlying string from a MDString value.
+ *
+ * @param V Instance to obtain string from.
+ * @param Len Memory address which will hold length of returned string.
+ * @return String data in MDString.
+ */
+const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueBasicBlock Basic Block
+ *
+ * A basic block represents a single entry single exit section of code.
+ * Basic blocks contain a list of instructions which form the body of
+ * the block.
+ *
+ * Basic blocks belong to functions. They have the type of label.
+ *
+ * Basic blocks are themselves values. However, the C API models them as
+ * LLVMBasicBlockRef.
+ *
+ * @see llvm::BasicBlock
+ *
+ * @{
+ */
+
+/**
+ * Convert a basic block instance to a value type.
+ */
+LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB);
+
+/**
+ * Determine whether a LLVMValueRef is itself a basic block.
+ */
+LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val);
+
+/**
+ * Convert a LLVMValueRef to a LLVMBasicBlockRef instance.
+ */
+LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
+
+/**
+ * Obtain the function to which a basic block belongs.
+ *
+ * @see llvm::BasicBlock::getParent()
+ */
+LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the terminator instruction for a basic block.
+ *
+ * If the basic block does not have a terminator (it is not well-formed
+ * if it doesn't), then NULL is returned.
+ *
+ * The returned LLVMValueRef corresponds to a llvm::TerminatorInst.
+ *
+ * @see llvm::BasicBlock::getTerminator()
+ */
+LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the number of basic blocks in a function.
+ *
+ * @param Fn Function value to operate on.
+ */
+unsigned LLVMCountBasicBlocks(LLVMValueRef Fn);
+
+/**
+ * Obtain all of the basic blocks in a function.
+ *
+ * This operates on a function value. The BasicBlocks parameter is a
+ * pointer to a pre-allocated array of LLVMBasicBlockRef of at least
+ * LLVMCountBasicBlocks() in length. This array is populated with
+ * LLVMBasicBlockRef instances.
+ */
+void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks);
+
+/**
+ * Obtain the first basic block in a function.
+ *
+ * The returned basic block can be used as an iterator. You will likely
+ * eventually call into LLVMGetNextBasicBlock() with it.
+ *
+ * @see llvm::Function::begin()
+ */
+LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn);
+
+/**
+ * Obtain the last basic block in a function.
+ *
+ * @see llvm::Function::end()
+ */
+LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn);
+
+/**
+ * Advance a basic block iterator.
+ */
+LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB);
+
+/**
+ * Go backwards in a basic block iterator.
+ */
+LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the basic block that corresponds to the entry point of a
+ * function.
+ *
+ * @see llvm::Function::getEntryBlock()
+ */
+LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn);
+
+/**
+ * Append a basic block to the end of a function.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C,
+ LLVMValueRef Fn,
+ const char *Name);
+
+/**
+ * Append a basic block to the end of a function using the global
+ * context.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name);
+
+/**
+ * Insert a basic block in a function before another basic block.
+ *
+ * The function to add to is determined by the function of the
+ * passed basic block.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C,
+ LLVMBasicBlockRef BB,
+ const char *Name);
+
+/**
+ * Insert a basic block in a function using the global context.
+ *
+ * @see llvm::BasicBlock::Create()
+ */
+LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
+ const char *Name);
+
+/**
+ * Remove a basic block from a function and delete it.
+ *
+ * This deletes the basic block from its containing function and deletes
+ * the basic block itself.
+ *
+ * @see llvm::BasicBlock::eraseFromParent()
+ */
+void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
+
+/**
+ * Remove a basic block from a function.
+ *
+ * This deletes the basic block from its containing function but keep
+ * the basic block alive.
+ *
+ * @see llvm::BasicBlock::removeFromParent()
+ */
+void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB);
+
+/**
+ * Move a basic block to before another one.
+ *
+ * @see llvm::BasicBlock::moveBefore()
+ */
+void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
+
+/**
+ * Move a basic block to after another one.
+ *
+ * @see llvm::BasicBlock::moveAfter()
+ */
+void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos);
+
+/**
+ * Obtain the first instruction in a basic block.
+ *
+ * The returned LLVMValueRef corresponds to a llvm::Instruction
+ * instance.
+ */
+LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB);
+
+/**
+ * Obtain the last instruction in a basic block.
+ *
+ * The returned LLVMValueRef corresponds to a LLVM:Instruction.
+ */
+LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreValueInstruction Instructions
+ *
+ * Functions in this group relate to the inspection and manipulation of
+ * individual instructions.
+ *
+ * In the C++ API, an instruction is modeled by llvm::Instruction. This
+ * class has a large number of descendents. llvm::Instruction is a
+ * llvm::Value and in the C API, instructions are modeled by
+ * LLVMValueRef.
+ *
+ * This group also contains sub-groups which operate on specific
+ * llvm::Instruction types, e.g. llvm::CallInst.
+ *
+ * @{
+ */
+
+/**
+ * Determine whether an instruction has any metadata attached.
+ */
+int LLVMHasMetadata(LLVMValueRef Val);
+
+/**
+ * Return metadata associated with an instruction value.
+ */
+LLVMValueRef LLVMGetMetadata(LLVMValueRef Val, unsigned KindID);
+
+/**
+ * Set metadata associated with an instruction value.
+ */
+void LLVMSetMetadata(LLVMValueRef Val, unsigned KindID, LLVMValueRef Node);
+
+/**
+ * Obtain the basic block to which an instruction belongs.
+ *
+ * @see llvm::Instruction::getParent()
+ */
+LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst);
+
+/**
+ * Obtain the instruction that occurs after the one specified.
+ *
+ * The next instruction will be from the same basic block.
+ *
+ * If this is the last instruction in a basic block, NULL will be
+ * returned.
+ */
+LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst);
+
+/**
+ * Obtain the instruction that occured before this one.
+ *
+ * If the instruction is the first instruction in a basic block, NULL
+ * will be returned.
+ */
+LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst);
+
+/**
+ * Remove and delete an instruction.
+ *
+ * The instruction specified is removed from its containing building
+ * block and then deleted.
+ *
+ * @see llvm::Instruction::eraseFromParent()
+ */
+void LLVMInstructionEraseFromParent(LLVMValueRef Inst);
+
+/**
+ * Obtain the code opcode for an individual instruction.
+ *
+ * @see llvm::Instruction::getOpCode()
+ */
+LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst);
+
+/**
+ * Obtain the predicate of an instruction.
+ *
+ * This is only valid for instructions that correspond to llvm::ICmpInst
+ * or llvm::ConstantExpr whose opcode is llvm::Instruction::ICmp.
+ *
+ * @see llvm::ICmpInst::getPredicate()
+ */
+LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst);
+
+/**
+ * @defgroup LLVMCCoreValueInstructionCall Call Sites and Invocations
+ *
+ * Functions in this group apply to instructions that refer to call
+ * sites and invocations. These correspond to C++ types in the
+ * llvm::CallInst class tree.
+ *
+ * @{
+ */
+
+/**
+ * Set the calling convention for a call instruction.
+ *
+ * This expects an LLVMValueRef that corresponds to a llvm::CallInst or
+ * llvm::InvokeInst.
+ *
+ * @see llvm::CallInst::setCallingConv()
+ * @see llvm::InvokeInst::setCallingConv()
+ */
+void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC);
+
+/**
+ * Obtain the calling convention for a call instruction.
+ *
+ * This is the opposite of LLVMSetInstructionCallConv(). Reads its
+ * usage.
+ *
+ * @see LLVMSetInstructionCallConv()
+ */
+unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr);
+
+
+void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, LLVMAttribute);
+void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,
+ LLVMAttribute);
+void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
+ unsigned align);
+
+/**
+ * Obtain whether a call instruction is a tail call.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::isTailCall()
+ */
+LLVMBool LLVMIsTailCall(LLVMValueRef CallInst);
+
+/**
+ * Set whether a call instruction is a tail call.
+ *
+ * This only works on llvm::CallInst instructions.
+ *
+ * @see llvm::CallInst::setTailCall()
+ */
+void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall);
+
+/**
+ * @}
+ */
+
+/**
+ * Obtain the default destination basic block of a switch instruction.
+ *
+ * This only works on llvm::SwitchInst instructions.
+ *
+ * @see llvm::SwitchInst::getDefaultDest()
+ */
+LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr);
+
+/**
+ * @defgroup LLVMCCoreValueInstructionPHINode PHI Nodes
+ *
+ * Functions in this group only apply to instructions that map to
+ * llvm::PHINode instances.
+ *
+ * @{
+ */
+
+/**
+ * Add an incoming value to the end of a PHI list.
+ */
+void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues,
+ LLVMBasicBlockRef *IncomingBlocks, unsigned Count);
+
+/**
+ * Obtain the number of incoming basic blocks to a PHI node.
+ */
+unsigned LLVMCountIncoming(LLVMValueRef PhiNode);
+
+/**
+ * Obtain an incoming value to a PHI node as a LLVMValueRef.
+ */
+LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index);
+
+/**
+ * Obtain an incoming value to a PHI node as a LLVMBasicBlockRef.
+ */
+LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreInstructionBuilder Instruction Builders
+ *
+ * An instruction builder represents a point within a basic block and is
+ * the exclusive means of building instructions using the C interface.
+ *
+ * @{
+ */
+
+LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C);
+LLVMBuilderRef LLVMCreateBuilder(void);
+void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block,
+ LLVMValueRef Instr);
+void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr);
+void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block);
+LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder);
+void LLVMClearInsertionPosition(LLVMBuilderRef Builder);
+void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr);
+void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr,
+ const char *Name);
+void LLVMDisposeBuilder(LLVMBuilderRef Builder);
+
+/* Metadata */
+void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L);
+LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder);
+void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst);
+
+/* Terminators */
+LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef);
+LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V);
+LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef, LLVMValueRef *RetVals,
+ unsigned N);
+LLVMValueRef LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef Dest);
+LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If,
+ LLVMBasicBlockRef Then, LLVMBasicBlockRef Else);
+LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
+ LLVMBasicBlockRef Else, unsigned NumCases);
+LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr,
+ unsigned NumDests);
+LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
+ LLVMValueRef *Args, unsigned NumArgs,
+ LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
+ const char *Name);
+LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
+ LLVMValueRef PersFn, unsigned NumClauses,
+ const char *Name);
+LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
+LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
+
+/* Add a case to the switch instruction */
+void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
+ LLVMBasicBlockRef Dest);
+
+/* Add a destination to the indirectbr instruction */
+void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest);
+
+/* Add a catch or filter clause to the landingpad instruction */
+void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal);
+
+/* Set the 'cleanup' flag in the landingpad instruction */
+void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val);
+
+/* Arithmetic */
+LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildFSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildFMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildURem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildShl(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V,
+ const char *Name);
+LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
+ const char *Name);
+LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+
+/* Memory */
+LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,
+ LLVMValueRef Val, const char *Name);
+LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef Ty,
+ LLVMValueRef Val, const char *Name);
+LLVMValueRef LLVMBuildFree(LLVMBuilderRef, LLVMValueRef PointerVal);
+LLVMValueRef LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef PointerVal,
+ const char *Name);
+LLVMValueRef LLVMBuildStore(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef Ptr);
+LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+ LLVMValueRef *Indices, unsigned NumIndices,
+ const char *Name);
+LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+ LLVMValueRef *Indices, unsigned NumIndices,
+ const char *Name);
+LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+ unsigned Idx, const char *Name);
+LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str,
+ const char *Name);
+LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str,
+ const char *Name);
+LLVMBool LLVMGetVolatile(LLVMValueRef MemoryAccessInst);
+void LLVMSetVolatile(LLVMValueRef MemoryAccessInst, LLVMBool IsVolatile);
+
+/* Casts */
+LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef Val, /*Signed cast!*/
+ LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef Val,
+ LLVMTypeRef DestTy, const char *Name);
+
+/* Comparisons */
+LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ const char *Name);
+
+/* Miscellaneous instructions */
+LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn,
+ LLVMValueRef *Args, unsigned NumArgs,
+ const char *Name);
+LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If,
+ LLVMValueRef Then, LLVMValueRef Else,
+ const char *Name);
+LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty,
+ const char *Name);
+LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef VecVal,
+ LLVMValueRef Index, const char *Name);
+LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal,
+ LLVMValueRef EltVal, LLVMValueRef Index,
+ const char *Name);
+LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
+ LLVMValueRef V2, LLVMValueRef Mask,
+ const char *Name);
+LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef, LLVMValueRef AggVal,
+ unsigned Index, const char *Name);
+LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef AggVal,
+ LLVMValueRef EltVal, unsigned Index,
+ const char *Name);
+
+LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef Val,
+ const char *Name);
+LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val,
+ const char *Name);
+LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
+ LLVMValueRef RHS, const char *Name);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreModuleProvider Module Providers
+ *
+ * @{
+ */
+
+/**
+ * Changes the type of M so it can be passed to FunctionPassManagers and the
+ * JIT. They take ModuleProviders for historical reasons.
+ */
+LLVMModuleProviderRef
+LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M);
+
+/**
+ * Destroys the module M.
+ */
+void LLVMDisposeModuleProvider(LLVMModuleProviderRef M);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCoreMemoryBuffers Memory Buffers
+ *
+ * @{
+ */
+
+LLVMBool LLVMCreateMemoryBufferWithContentsOfFile(const char *Path,
+ LLVMMemoryBufferRef *OutMemBuf,
+ char **OutMessage);
+LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
+ char **OutMessage);
+void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCorePassRegistry Pass Registry
+ *
+ * @{
+ */
+
+/** Return the global pass registry, for use with initialization functions.
+ @see llvm::PassRegistry::getPassRegistry */
+LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup LLVMCCorePassManagers Pass Managers
+ *
+ * @{
+ */
+
+/** Constructs a new whole-module pass pipeline. This type of pipeline is
+ suitable for link-time optimization and whole-module transformations.
+ @see llvm::PassManager::PassManager */
+LLVMPassManagerRef LLVMCreatePassManager(void);
+
+/** Constructs a new function-by-function pass pipeline over the module
+ provider. It does not take ownership of the module provider. This type of
+ pipeline is suitable for code generation and JIT compilation tasks.
+ @see llvm::FunctionPassManager::FunctionPassManager */
+LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M);
+
+/** Deprecated: Use LLVMCreateFunctionPassManagerForModule instead. */
+LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
+
+/** Initializes, executes on the provided module, and finalizes all of the
+ passes scheduled in the pass manager. Returns 1 if any of the passes
+ modified the module, 0 otherwise.
+ @see llvm::PassManager::run(Module&) */
+LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M);
+
+/** Initializes all of the function passes scheduled in the function pass
+ manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+ @see llvm::FunctionPassManager::doInitialization */
+LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM);
+
+/** Executes all of the function passes scheduled in the function pass manager
+ on the provided function. Returns 1 if any of the passes modified the
+ function, false otherwise.
+ @see llvm::FunctionPassManager::run(Function&) */
+LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F);
+
+/** Finalizes all of the function passes scheduled in in the function pass
+ manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+ @see llvm::FunctionPassManager::doFinalization */
+LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
+
+/** Frees the memory of a pass pipeline. For function pipelines, does not free
+ the module provider.
+ @see llvm::PassManagerBase::~PassManagerBase. */
+void LLVMDisposePassManager(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+ class MemoryBuffer;
+ class PassManagerBase;
+
+ #define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
+ inline ty *unwrap(ref P) { \
+ return reinterpret_cast<ty*>(P); \
+ } \
+ \
+ inline ref wrap(const ty *P) { \
+ return reinterpret_cast<ref>(const_cast<ty*>(P)); \
+ }
+
+ #define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref) \
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
+ \
+ template<typename T> \
+ inline T *unwrap(ref P) { \
+ return cast<T>(unwrap(P)); \
+ }
+
+ #define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref) \
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
+ \
+ template<typename T> \
+ inline T *unwrap(ref P) { \
+ T *Q = (T*)unwrap(P); \
+ assert(Q && "Invalid cast!"); \
+ return Q; \
+ }
+
+ DEFINE_ISA_CONVERSION_FUNCTIONS (Type, LLVMTypeRef )
+ DEFINE_ISA_CONVERSION_FUNCTIONS (Value, LLVMValueRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>, LLVMBuilderRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext, LLVMContextRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef )
+ DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
+ DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry, LLVMPassRegistryRef )
+ /* LLVMModuleProviderRef exists for historical reasons, but now just holds a
+ * Module.
+ */
+ inline Module *unwrap(LLVMModuleProviderRef MP) {
+ return reinterpret_cast<Module*>(MP);
+ }
+
+ #undef DEFINE_STDCXX_CONVERSION_FUNCTIONS
+ #undef DEFINE_ISA_CONVERSION_FUNCTIONS
+ #undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
+
+ /* Specialized opaque context conversions.
+ */
+ inline LLVMContext **unwrap(LLVMContextRef* Tys) {
+ return reinterpret_cast<LLVMContext**>(Tys);
+ }
+
+ inline LLVMContextRef *wrap(const LLVMContext **Tys) {
+ return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys));
+ }
+
+ /* Specialized opaque type conversions.
+ */
+ inline Type **unwrap(LLVMTypeRef* Tys) {
+ return reinterpret_cast<Type**>(Tys);
+ }
+
+ inline LLVMTypeRef *wrap(Type **Tys) {
+ return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
+ }
+
+ /* Specialized opaque value conversions.
+ */
+ inline Value **unwrap(LLVMValueRef *Vals) {
+ return reinterpret_cast<Value**>(Vals);
+ }
+
+ template<typename T>
+ inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
+ #if DEBUG
+ for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
+ cast<T>(*I);
+ #endif
+ (void)Length;
+ return reinterpret_cast<T**>(Vals);
+ }
+
+ inline LLVMValueRef *wrap(const Value **Vals) {
+ return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
+ }
+}
+
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_CORE_H) */
diff --git a/contrib/llvm/include/llvm-c/Disassembler.h b/contrib/llvm/include/llvm-c/Disassembler.h
new file mode 100644
index 000000000000..a676e37768e4
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Disassembler.h
@@ -0,0 +1,175 @@
+/*===-- llvm-c/Disassembler.h - Disassembler Public 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 provides a public interface to a disassembler library. *|
+|* LLVM provides an implementation of this interface. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_DISASSEMBLER_H
+#define LLVM_C_DISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <stddef.h>
+
+/**
+ * @defgroup LLVMCDisassembler Disassembler
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+/**
+ * An opaque reference to a disassembler context.
+ */
+typedef void *LLVMDisasmContextRef;
+
+/**
+ * The type for the operand information call back function. This is called to
+ * get the symbolic information for an operand of an instruction. Typically
+ * this is from the relocation information, symbol table, etc. That block of
+ * information is saved when the disassembler context is created and passed to
+ * the call back in the DisInfo parameter. The instruction containing operand
+ * is at the PC parameter. For some instruction sets, there can be more than
+ * one operand with symbolic information. To determine the symbolic operand
+ * information for each operand, the bytes for the specific operand in the
+ * instruction are specified by the Offset parameter and its byte widith is the
+ * size parameter. For instructions sets with fixed widths and one symbolic
+ * operand per instruction, the Offset parameter will be zero and Size parameter
+ * will be the instruction width. The information is returned in TagBuf and is
+ * Triple specific with its specific information defined by the value of
+ * TagType for that Triple. If symbolic information is returned the function
+ * returns 1, otherwise it returns 0.
+ */
+typedef int (*LLVMOpInfoCallback)(void *DisInfo, uint64_t PC,
+ uint64_t Offset, uint64_t Size,
+ int TagType, void *TagBuf);
+
+/**
+ * The initial support in LLVM MC for the most general form of a relocatable
+ * expression is "AddSymbol - SubtractSymbol + Offset". For some Darwin targets
+ * this full form is encoded in the relocation information so that AddSymbol and
+ * SubtractSymbol can be link edited independent of each other. Many other
+ * platforms only allow a relocatable expression of the form AddSymbol + Offset
+ * to be encoded.
+ *
+ * The LLVMOpInfoCallback() for the TagType value of 1 uses the struct
+ * LLVMOpInfo1. The value of the relocatable expression for the operand,
+ * including any PC adjustment, is passed in to the call back in the Value
+ * field. The symbolic information about the operand is returned using all
+ * the fields of the structure with the Offset of the relocatable expression
+ * returned in the Value field. It is possible that some symbols in the
+ * relocatable expression were assembly temporary symbols, for example
+ * "Ldata - LpicBase + constant", and only the Values of the symbols without
+ * symbol names are present in the relocation information. The VariantKind
+ * type is one of the Target specific #defines below and is used to print
+ * operands like "_foo@GOT", ":lower16:_foo", etc.
+ */
+struct LLVMOpInfoSymbol1 {
+ uint64_t Present; /* 1 if this symbol is present */
+ const char *Name; /* symbol name if not NULL */
+ uint64_t Value; /* symbol value if name is NULL */
+};
+
+struct LLVMOpInfo1 {
+ struct LLVMOpInfoSymbol1 AddSymbol;
+ struct LLVMOpInfoSymbol1 SubtractSymbol;
+ uint64_t Value;
+ uint64_t VariantKind;
+};
+
+/**
+ * The operand VariantKinds for symbolic disassembly.
+ */
+#define LLVMDisassembler_VariantKind_None 0 /* all targets */
+
+/**
+ * The ARM target VariantKinds.
+ */
+#define LLVMDisassembler_VariantKind_ARM_HI16 1 /* :upper16: */
+#define LLVMDisassembler_VariantKind_ARM_LO16 2 /* :lower16: */
+
+/**
+ * The type for the symbol lookup function. This may be called by the
+ * disassembler for things like adding a comment for a PC plus a constant
+ * offset load instruction to use a symbol name instead of a load address value.
+ * It is passed the block information is saved when the disassembler context is
+ * created and the ReferenceValue to look up as a symbol. If no symbol is found
+ * for the ReferenceValue NULL is returned. The ReferenceType of the
+ * instruction is passed indirectly as is the PC of the instruction in
+ * ReferencePC. If the output reference can be determined its type is returned
+ * indirectly in ReferenceType along with ReferenceName if any, or that is set
+ * to NULL.
+ */
+typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
+ uint64_t ReferenceValue,
+ uint64_t *ReferenceType,
+ uint64_t ReferencePC,
+ const char **ReferenceName);
+/**
+ * The reference types on input and output.
+ */
+/* No input reference type or no output reference type. */
+#define LLVMDisassembler_ReferenceType_InOut_None 0
+
+/* The input reference is from a branch instruction. */
+#define LLVMDisassembler_ReferenceType_In_Branch 1
+/* The input reference is from a PC relative load instruction. */
+#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2
+
+/* The output reference is to as symbol stub. */
+#define LLVMDisassembler_ReferenceType_Out_SymbolStub 1
+/* The output reference is to a symbol address in a literal pool. */
+#define LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr 2
+/* The output reference is to a cstring address in a literal pool. */
+#define LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr 3
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* !defined(__cplusplus) */
+
+/**
+ * Create a disassembler for the TripleName. 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 LLVMCreateDisasm(const char *TripleName, void *DisInfo,
+ int TagType, LLVMOpInfoCallback GetOpInfo,
+ LLVMSymbolLookupCallback SymbolLookUp);
+
+/**
+ * Dispose of a disassembler context.
+ */
+void LLVMDisasmDispose(LLVMDisasmContextRef DC);
+
+/**
+ * Disassemble a single instruction using the disassembler context specified in
+ * the parameter DC. The bytes of the instruction are specified in the
+ * parameter Bytes, and contains at least BytesSize number of bytes. The
+ * instruction is at the address specified by the PC parameter. If a valid
+ * instruction can be disassembled, its string is returned indirectly in
+ * OutString whose size is specified in the parameter OutStringSize. This
+ * function returns the number of bytes in the instruction or zero if there was
+ * no valid instruction.
+ */
+size_t LLVMDisasmInstruction(LLVMDisasmContextRef DC, uint8_t *Bytes,
+ uint64_t BytesSize, uint64_t PC,
+ char *OutString, size_t OutStringSize);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_DISASSEMBLER_H) */
diff --git a/contrib/llvm/include/llvm-c/EnhancedDisassembly.h b/contrib/llvm/include/llvm-c/EnhancedDisassembly.h
new file mode 100644
index 000000000000..71a0d496c028
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/EnhancedDisassembly.h
@@ -0,0 +1,530 @@
+/*===-- 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/contrib/llvm/include/llvm-c/ExecutionEngine.h b/contrib/llvm/include/llvm-c/ExecutionEngine.h
new file mode 100644
index 000000000000..cb77bb2e2e23
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/ExecutionEngine.h
@@ -0,0 +1,163 @@
+/*===-- llvm-c/ExecutionEngine.h - ExecutionEngine Lib C Iface --*- 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 libLLVMExecutionEngine.o, which *|
+|* implements various analyses of the LLVM IR. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_EXECUTIONENGINE_H
+#define LLVM_C_EXECUTIONENGINE_H
+
+#include "llvm-c/Core.h"
+#include "llvm-c/Target.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCExecutionEngine Execution Engine
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+void LLVMLinkInJIT(void);
+void LLVMLinkInInterpreter(void);
+
+typedef struct LLVMOpaqueGenericValue *LLVMGenericValueRef;
+typedef struct LLVMOpaqueExecutionEngine *LLVMExecutionEngineRef;
+
+/*===-- Operations on generic values --------------------------------------===*/
+
+LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
+ unsigned long long N,
+ LLVMBool IsSigned);
+
+LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P);
+
+LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef Ty, double N);
+
+unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef);
+
+unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenVal,
+ LLVMBool IsSigned);
+
+void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal);
+
+double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal);
+
+void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal);
+
+/*===-- Operations on execution engines -----------------------------------===*/
+
+LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
+ LLVMModuleRef M,
+ char **OutError);
+
+LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
+ LLVMModuleRef M,
+ char **OutError);
+
+LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
+ LLVMModuleRef M,
+ unsigned OptLevel,
+ char **OutError);
+
+/** Deprecated: Use LLVMCreateExecutionEngineForModule instead. */
+LLVMBool LLVMCreateExecutionEngine(LLVMExecutionEngineRef *OutEE,
+ LLVMModuleProviderRef MP,
+ char **OutError);
+
+/** Deprecated: Use LLVMCreateInterpreterForModule instead. */
+LLVMBool LLVMCreateInterpreter(LLVMExecutionEngineRef *OutInterp,
+ LLVMModuleProviderRef MP,
+ char **OutError);
+
+/** Deprecated: Use LLVMCreateJITCompilerForModule instead. */
+LLVMBool LLVMCreateJITCompiler(LLVMExecutionEngineRef *OutJIT,
+ LLVMModuleProviderRef MP,
+ unsigned OptLevel,
+ char **OutError);
+
+void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE);
+
+void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE);
+
+void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE);
+
+int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
+ unsigned ArgC, const char * const *ArgV,
+ const char * const *EnvP);
+
+LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
+ unsigned NumArgs,
+ LLVMGenericValueRef *Args);
+
+void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F);
+
+void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M);
+
+/** Deprecated: Use LLVMAddModule instead. */
+void LLVMAddModuleProvider(LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP);
+
+LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
+ LLVMModuleRef *OutMod, char **OutError);
+
+/** Deprecated: Use LLVMRemoveModule instead. */
+LLVMBool LLVMRemoveModuleProvider(LLVMExecutionEngineRef EE,
+ LLVMModuleProviderRef MP,
+ LLVMModuleRef *OutMod, char **OutError);
+
+LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
+ LLVMValueRef *OutFn);
+
+void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE, LLVMValueRef Fn);
+
+LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
+
+void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
+ void* Addr);
+
+void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+ struct GenericValue;
+ class ExecutionEngine;
+
+ #define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
+ inline ty *unwrap(ref P) { \
+ return reinterpret_cast<ty*>(P); \
+ } \
+ \
+ inline ref wrap(const ty *P) { \
+ return reinterpret_cast<ref>(const_cast<ty*>(P)); \
+ }
+
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef )
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
+
+ #undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
+}
+
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Initialization.h b/contrib/llvm/include/llvm-c/Initialization.h
new file mode 100644
index 000000000000..cb3ab9e3f393
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Initialization.h
@@ -0,0 +1,54 @@
+/*===-- llvm-c/Initialization.h - Initialization 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 LLVM initialization routines, *|
+|* which must be called before you can use the functionality provided by *|
+|* the corresponding LLVM library. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_INITIALIZEPASSES_H
+#define LLVM_C_INITIALIZEPASSES_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCInitialization Initialization Routines
+ * @ingroup LLVMC
+ *
+ * This module contains routines used to initialize the LLVM system.
+ *
+ * @{
+ */
+
+void LLVMInitializeCore(LLVMPassRegistryRef R);
+void LLVMInitializeTransformUtils(LLVMPassRegistryRef R);
+void LLVMInitializeScalarOpts(LLVMPassRegistryRef R);
+void LLVMInitializeVectorization(LLVMPassRegistryRef R);
+void LLVMInitializeInstCombine(LLVMPassRegistryRef R);
+void LLVMInitializeIPO(LLVMPassRegistryRef R);
+void LLVMInitializeInstrumentation(LLVMPassRegistryRef R);
+void LLVMInitializeAnalysis(LLVMPassRegistryRef R);
+void LLVMInitializeIPA(LLVMPassRegistryRef R);
+void LLVMInitializeCodeGen(LLVMPassRegistryRef R);
+void LLVMInitializeTarget(LLVMPassRegistryRef R);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h b/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h
new file mode 100644
index 000000000000..5338d3fc4c85
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/LinkTimeOptimizer.h
@@ -0,0 +1,69 @@
+//===-- llvm/LinkTimeOptimizer.h - LTO Public 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 provides a C API to use the LLVM link time optimization
+// library. This is intended to be used by linkers which are C-only in
+// their implementation for performing LTO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LTO_CAPI_H__
+#define __LTO_CAPI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCLinkTimeOptimizer Link Time Optimization
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+ /// This provides a dummy type for pointers to the LTO object.
+ typedef void* llvm_lto_t;
+
+ /// This provides a C-visible enumerator to manage status codes.
+ /// This should map exactly onto the C++ enumerator LTOStatus.
+ typedef enum llvm_lto_status {
+ LLVM_LTO_UNKNOWN,
+ LLVM_LTO_OPT_SUCCESS,
+ LLVM_LTO_READ_SUCCESS,
+ LLVM_LTO_READ_FAILURE,
+ LLVM_LTO_WRITE_FAILURE,
+ LLVM_LTO_NO_TARGET,
+ LLVM_LTO_NO_WORK,
+ LLVM_LTO_MODULE_MERGE_FAILURE,
+ LLVM_LTO_ASM_FAILURE,
+
+ // Added C-specific error codes
+ LLVM_LTO_NULL_OBJECT
+ } llvm_lto_status_t;
+
+ /// This provides C interface to initialize link time optimizer. This allows
+ /// linker to use dlopen() interface to dynamically load LinkTimeOptimizer.
+ /// extern "C" helps, because dlopen() interface uses name to find the symbol.
+ extern llvm_lto_t llvm_create_optimizer(void);
+ extern void llvm_destroy_optimizer(llvm_lto_t lto);
+
+ extern llvm_lto_status_t llvm_read_object_file
+ (llvm_lto_t lto, const char* input_filename);
+ extern llvm_lto_status_t llvm_optimize_modules
+ (llvm_lto_t lto, const char* output_filename);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Object.h b/contrib/llvm/include/llvm-c/Object.h
new file mode 100644
index 000000000000..e2dad62b4e07
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Object.h
@@ -0,0 +1,149 @@
+/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- 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 libLLVMObject.a, which */
+/* implements object file reading and writing. */
+/* */
+/* Many exotic languages can interoperate with C code but have a harder time */
+/* with C++ due to name mangling. So in addition to C, this interface enables */
+/* tools written in such languages. */
+/* */
+/*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_OBJECT_H
+#define LLVM_C_OBJECT_H
+
+#include "llvm-c/Core.h"
+#include "llvm/Config/llvm-config.h"
+
+#ifdef __cplusplus
+#include "llvm/Object/ObjectFile.h"
+
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCObject Object file reading and writing
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+// Opaque type wrappers
+typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef;
+typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
+typedef struct LLVMOpaqueSymbolIterator *LLVMSymbolIteratorRef;
+typedef struct LLVMOpaqueRelocationIterator *LLVMRelocationIteratorRef;
+
+// ObjectFile creation
+LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf);
+void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile);
+
+// ObjectFile Section iterators
+LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile);
+void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI);
+LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
+ LLVMSectionIteratorRef SI);
+void LLVMMoveToNextSection(LLVMSectionIteratorRef SI);
+void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
+ LLVMSymbolIteratorRef Sym);
+
+// ObjectFile Symbol iterators
+LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile);
+void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI);
+LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
+ LLVMSymbolIteratorRef SI);
+void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI);
+
+// SectionRef accessors
+const char *LLVMGetSectionName(LLVMSectionIteratorRef SI);
+uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI);
+const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI);
+uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI);
+LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
+ LLVMSymbolIteratorRef Sym);
+
+// Section Relocation iterators
+LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section);
+void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef RI);
+LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
+ LLVMRelocationIteratorRef RI);
+void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef RI);
+
+
+// SymbolRef accessors
+const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI);
+uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI);
+uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI);
+uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI);
+
+// RelocationRef accessors
+uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI);
+uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI);
+LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI);
+uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI);
+// NOTE: Caller takes ownership of returned string of the two
+// following functions.
+const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI);
+const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+ namespace object {
+ inline ObjectFile *unwrap(LLVMObjectFileRef OF) {
+ return reinterpret_cast<ObjectFile*>(OF);
+ }
+
+ inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
+ return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
+ }
+
+ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
+ return reinterpret_cast<section_iterator*>(SI);
+ }
+
+ inline LLVMSectionIteratorRef
+ wrap(const section_iterator *SI) {
+ return reinterpret_cast<LLVMSectionIteratorRef>
+ (const_cast<section_iterator*>(SI));
+ }
+
+ inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
+ return reinterpret_cast<symbol_iterator*>(SI);
+ }
+
+ inline LLVMSymbolIteratorRef
+ wrap(const symbol_iterator *SI) {
+ return reinterpret_cast<LLVMSymbolIteratorRef>
+ (const_cast<symbol_iterator*>(SI));
+ }
+
+ inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
+ return reinterpret_cast<relocation_iterator*>(SI);
+ }
+
+ inline LLVMRelocationIteratorRef
+ wrap(const relocation_iterator *SI) {
+ return reinterpret_cast<LLVMRelocationIteratorRef>
+ (const_cast<relocation_iterator*>(SI));
+ }
+
+ }
+}
+
+#endif /* defined(__cplusplus) */
+
+#endif
+
diff --git a/contrib/llvm/include/llvm-c/Target.h b/contrib/llvm/include/llvm-c/Target.h
new file mode 100644
index 000000000000..568e60dfb43e
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Target.h
@@ -0,0 +1,253 @@
+/*===-- llvm-c/Target.h - Target Lib C Iface --------------------*- 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 libLLVMTarget.a, which */
+/* implements target information. */
+/* */
+/* Many exotic languages can interoperate with C code but have a harder time */
+/* with C++ due to name mangling. So in addition to C, this interface enables */
+/* tools written in such languages. */
+/* */
+/*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TARGET_H
+#define LLVM_C_TARGET_H
+
+#include "llvm-c/Core.h"
+#include "llvm/Config/llvm-config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTarget Target information
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian };
+
+typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
+typedef struct LLVMOpaqueTargetLibraryInfotData *LLVMTargetLibraryInfoRef;
+typedef struct LLVMStructLayout *LLVMStructLayoutRef;
+
+/* Declare all of the target-initialization functions that are available. */
+#define LLVM_TARGET(TargetName) \
+ void LLVMInitialize##TargetName##TargetInfo(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
+
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
+
+#define LLVM_TARGET(TargetName) \
+ void LLVMInitialize##TargetName##TargetMC(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
+
+/* Declare all of the available assembly printer initialization functions. */
+#define LLVM_ASM_PRINTER(TargetName) \
+ void LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+#undef LLVM_ASM_PRINTER /* Explicit undef to make SWIG happier */
+
+/* Declare all of the available assembly parser initialization functions. */
+#define LLVM_ASM_PARSER(TargetName) \
+ void LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+#undef LLVM_ASM_PARSER /* Explicit undef to make SWIG happier */
+
+/* Declare all of the available disassembler initialization functions. */
+#define LLVM_DISASSEMBLER(TargetName) \
+ void LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+#undef LLVM_DISASSEMBLER /* Explicit undef to make SWIG happier */
+
+/** LLVMInitializeAllTargetInfos - The main program should call this function if
+ it wants access to all available targets that LLVM is configured to
+ support. */
+static inline void LLVMInitializeAllTargetInfos(void) {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo();
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllTargets - The main program should call this function if it
+ wants to link in all available targets that LLVM is configured to
+ support. */
+static inline void LLVMInitializeAllTargets(void) {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllTargetMCs - The main program should call this function if
+ it wants access to all available target MC that LLVM is configured to
+ support. */
+static inline void LLVMInitializeAllTargetMCs(void) {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllAsmPrinters - The main program should call this function if
+ it wants all asm printers that LLVM is configured to support, to make them
+ available via the TargetRegistry. */
+static inline void LLVMInitializeAllAsmPrinters() {
+#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+#undef LLVM_ASM_PRINTER /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllAsmParsers - The main program should call this function if
+ it wants all asm parsers that LLVM is configured to support, to make them
+ available via the TargetRegistry. */
+static inline void LLVMInitializeAllAsmParsers() {
+#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+#undef LLVM_ASM_PARSER /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeAllDisassemblers - The main program should call this function
+ if it wants all disassemblers that LLVM is configured to support, to make
+ them available via the TargetRegistry. */
+static inline void LLVMInitializeAllDisassemblers() {
+#define LLVM_DISASSEMBLER(TargetName) \
+ LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+#undef LLVM_DISASSEMBLER /* Explicit undef to make SWIG happier */
+}
+
+/** LLVMInitializeNativeTarget - The main program should call this function to
+ initialize the native target corresponding to the host. This is useful
+ for JIT applications to ensure that the target gets linked in correctly. */
+static inline LLVMBool LLVMInitializeNativeTarget(void) {
+ /* If we have a native target, initialize it to ensure it is linked in. */
+#ifdef LLVM_NATIVE_TARGET
+ LLVM_NATIVE_TARGETINFO();
+ LLVM_NATIVE_TARGET();
+ LLVM_NATIVE_TARGETMC();
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+/*===-- Target Data -------------------------------------------------------===*/
+
+/** Creates target data from a target layout string.
+ See the constructor llvm::TargetData::TargetData. */
+LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep);
+
+/** Adds target data information to a pass manager. This does not take ownership
+ of the target data.
+ See the method llvm::PassManagerBase::add. */
+void LLVMAddTargetData(LLVMTargetDataRef, LLVMPassManagerRef);
+
+/** Adds target library information to a pass manager. This does not take
+ ownership of the target library info.
+ See the method llvm::PassManagerBase::add. */
+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. */
+char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
+
+/** Returns the byte order of a target, either LLVMBigEndian or
+ LLVMLittleEndian.
+ See the method llvm::TargetData::isLittleEndian. */
+enum LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef);
+
+/** Returns the pointer size in bytes for a target.
+ See the method llvm::TargetData::getPointerSize. */
+unsigned LLVMPointerSize(LLVMTargetDataRef);
+
+/** Returns the integer type that is the same size as a pointer on a target.
+ See the method llvm::TargetData::getIntPtrType. */
+LLVMTypeRef LLVMIntPtrType(LLVMTargetDataRef);
+
+/** Computes the size of a type in bytes for a target.
+ See the method llvm::TargetData::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. */
+unsigned long long LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
+
+/** Computes the ABI size of a type in bytes for a target.
+ See the method llvm::TargetData::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. */
+unsigned LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
+
+/** Computes the call frame alignment of a type in bytes for a target.
+ See the method llvm::TargetData::getTypeABISize. */
+unsigned LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
+
+/** Computes the preferred alignment of a type in bytes for a target.
+ See the method llvm::TargetData::getTypeABISize. */
+unsigned LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
+
+/** Computes the preferred alignment of a global variable in bytes for a target.
+ See the method llvm::TargetData::getPreferredAlignment. */
+unsigned LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,
+ LLVMValueRef GlobalVar);
+
+/** Computes the structure element that contains the byte offset for a target.
+ See the method llvm::StructLayout::getElementContainingOffset. */
+unsigned LLVMElementAtOffset(LLVMTargetDataRef, LLVMTypeRef StructTy,
+ unsigned long long Offset);
+
+/** Computes the byte offset of the indexed struct element for a target.
+ See the method llvm::StructLayout::getElementContainingOffset. */
+unsigned long long LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef StructTy,
+ unsigned Element);
+
+/** Deallocates a TargetData.
+ See the destructor llvm::TargetData::~TargetData. */
+void LLVMDisposeTargetData(LLVMTargetDataRef);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+ class TargetData;
+ class TargetLibraryInfo;
+
+ inline TargetData *unwrap(LLVMTargetDataRef P) {
+ return reinterpret_cast<TargetData*>(P);
+ }
+
+ inline LLVMTargetDataRef wrap(const TargetData *P) {
+ return reinterpret_cast<LLVMTargetDataRef>(const_cast<TargetData*>(P));
+ }
+
+ inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
+ return reinterpret_cast<TargetLibraryInfo*>(P);
+ }
+
+ inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
+ TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
+ return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
+ }
+}
+
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/TargetMachine.h b/contrib/llvm/include/llvm-c/TargetMachine.h
new file mode 100644
index 000000000000..0d35d73a11df
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/TargetMachine.h
@@ -0,0 +1,142 @@
+/*===-- llvm-c/TargetMachine.h - Target Machine Library 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 the Target and TargetMachine *|
+|* classes, which can be used to generate assembly or object files. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TARGETMACHINE_H
+#define LLVM_C_TARGETMACHINE_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct LLVMTargetMachine *LLVMTargetMachineRef;
+typedef struct LLVMTarget *LLVMTargetRef;
+
+typedef enum {
+ LLVMCodeGenLevelNone,
+ LLVMCodeGenLevelLess,
+ LLVMCodeGenLevelDefault,
+ LLVMCodeGenLevelAggressive
+} LLVMCodeGenOptLevel;
+
+typedef enum {
+ LLVMRelocDefault,
+ LLVMRelocStatic,
+ LLVMRelocPIC,
+ LLVMRelocDynamicNoPic
+} LLVMRelocMode;
+
+typedef enum {
+ LLVMCodeModelDefault,
+ LLVMCodeModelJITDefault,
+ LLVMCodeModelSmall,
+ LLVMCodeModelKernel,
+ LLVMCodeModelMedium,
+ LLVMCodeModelLarge
+} LLVMCodeModel;
+
+typedef enum {
+ LLVMAssemblyFile,
+ LLVMObjectFile
+} LLVMCodeGenFileType;
+
+/** Returns the first llvm::Target in the registered targets list. */
+LLVMTargetRef LLVMGetFirstTarget();
+/** Returns the next llvm::Target given a previous one (or null if there's none) */
+LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T);
+
+/*===-- Target ------------------------------------------------------------===*/
+/** Returns the name of a target. See llvm::Target::getName */
+const char *LLVMGetTargetName(LLVMTargetRef T);
+
+/** Returns the description of a target. See llvm::Target::getDescription */
+const char *LLVMGetTargetDescription(LLVMTargetRef T);
+
+/** Returns if the target has a JIT */
+LLVMBool LLVMTargetHasJIT(LLVMTargetRef T);
+
+/** Returns if the target has a TargetMachine associated */
+LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T);
+
+/** Returns if the target as an ASM backend (required for emitting output) */
+LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T);
+
+/*===-- Target Machine ----------------------------------------------------===*/
+/** Creates a new llvm::TargetMachine. See llvm::Target::createTargetMachine */
+LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, char *Triple,
+ char *CPU, char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
+ LLVMCodeModel CodeModel);
+
+/** Dispose the LLVMTargetMachineRef instance generated by
+ LLVMCreateTargetMachine. */
+void LLVMDisposeTargetMachine(LLVMTargetMachineRef T);
+
+/** Returns the Target used in a TargetMachine */
+LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T);
+
+/** Returns the triple used creating this target machine. See
+ llvm::TargetMachine::getTriple. The result needs to be disposed with
+ LLVMDisposeMessage. */
+char *LLVMGetTargetMachineTriple(LLVMTargetMachineRef T);
+
+/** Returns the cpu used creating this target machine. See
+ llvm::TargetMachine::getCPU. The result needs to be disposed with
+ LLVMDisposeMessage. */
+char *LLVMGetTargetMachineCPU(LLVMTargetMachineRef T);
+
+/** Returns the feature string used creating this target machine. See
+ llvm::TargetMachine::getFeatureString. The result needs to be disposed with
+ LLVMDisposeMessage. */
+char *LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T);
+
+/** Returns the llvm::TargetData used for this llvm:TargetMachine. */
+LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T);
+
+/** Emits an asm or object file for the given module to the filename. This
+ wraps several c++ only classes (among them a file stream). Returns any
+ error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
+LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
+ char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
+
+
+
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+ class TargetMachine;
+ class Target;
+
+ inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
+ return reinterpret_cast<TargetMachine*>(P);
+ }
+ inline Target *unwrap(LLVMTargetRef P) {
+ return reinterpret_cast<Target*>(P);
+ }
+ inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
+ return reinterpret_cast<LLVMTargetMachineRef>(
+ const_cast<TargetMachine*>(P));
+ }
+ inline LLVMTargetRef wrap(const Target * P) {
+ return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
+ }
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Transforms/IPO.h b/contrib/llvm/include/llvm-c/Transforms/IPO.h
new file mode 100644
index 000000000000..448078012eac
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Transforms/IPO.h
@@ -0,0 +1,81 @@
+/*===-- IPO.h - Interprocedural Transformations 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 libLLVMIPO.a, which implements *|
+|* various interprocedural transformations of the LLVM IR. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_IPO_H
+#define LLVM_C_TRANSFORMS_IPO_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsIPO Interprocedural transformations
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::createArgumentPromotionPass function. */
+void LLVMAddArgumentPromotionPass(LLVMPassManagerRef PM);
+
+/** See llvm::createConstantMergePass function. */
+void LLVMAddConstantMergePass(LLVMPassManagerRef PM);
+
+/** See llvm::createDeadArgEliminationPass function. */
+void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createFunctionAttrsPass function. */
+void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM);
+
+/** See llvm::createFunctionInliningPass function. */
+void LLVMAddFunctionInliningPass(LLVMPassManagerRef PM);
+
+/** See llvm::createAlwaysInlinerPass function. */
+void LLVMAddAlwaysInlinerPass(LLVMPassManagerRef PM);
+
+/** See llvm::createGlobalDCEPass function. */
+void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM);
+
+/** See llvm::createGlobalOptimizerPass function. */
+void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM);
+
+/** See llvm::createIPConstantPropagationPass function. */
+void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createPruneEHPass function. */
+void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
+
+/** See llvm::createIPSCCPPass function. */
+void LLVMAddIPSCCPPass(LLVMPassManagerRef PM);
+
+/** See llvm::createInternalizePass function. */
+void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain);
+
+/** See llvm::createStripDeadPrototypesPass function. */
+void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM);
+
+/** See llvm::createStripSymbolsPass function. */
+void LLVMAddStripSymbolsPass(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h b/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h
new file mode 100644
index 000000000000..cee6e5a0ee08
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Transforms/PassManagerBuilder.h
@@ -0,0 +1,101 @@
+/*===-- llvm-c/Transform/PassManagerBuilder.h - PMB 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 the PassManagerBuilder class. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_PASSMANAGERBUILDER
+#define LLVM_C_PASSMANAGERBUILDER
+
+#include "llvm-c/Core.h"
+
+typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef;
+
+#ifdef __cplusplus
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsPassManagerBuilder Pass manager builder
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::PassManagerBuilder. */
+LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void);
+void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB);
+
+/** See llvm::PassManagerBuilder::OptLevel. */
+void
+LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB,
+ unsigned OptLevel);
+
+/** See llvm::PassManagerBuilder::SizeLevel. */
+void
+LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB,
+ unsigned SizeLevel);
+
+/** See llvm::PassManagerBuilder::DisableUnitAtATime. */
+void
+LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB,
+ LLVMBool Value);
+
+/** See llvm::PassManagerBuilder::DisableUnrollLoops. */
+void
+LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB,
+ LLVMBool Value);
+
+/** See llvm::PassManagerBuilder::DisableSimplifyLibCalls */
+void
+LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB,
+ LLVMBool Value);
+
+/** See llvm::PassManagerBuilder::Inliner. */
+void
+LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB,
+ unsigned Threshold);
+
+/** See llvm::PassManagerBuilder::populateFunctionPassManager. */
+void
+LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB,
+ LLVMPassManagerRef PM);
+
+/** See llvm::PassManagerBuilder::populateModulePassManager. */
+void
+LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB,
+ LLVMPassManagerRef PM);
+
+/** See llvm::PassManagerBuilder::populateLTOPassManager. */
+void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB,
+ LLVMPassManagerRef PM,
+ bool Internalize,
+ bool RunInliner);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+ inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
+ return reinterpret_cast<PassManagerBuilder*>(P);
+ }
+
+ inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
+ return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
+ }
+}
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Transforms/Scalar.h b/contrib/llvm/include/llvm-c/Transforms/Scalar.h
new file mode 100644
index 000000000000..a2c4d6116f03
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Transforms/Scalar.h
@@ -0,0 +1,134 @@
+/*===-- Scalar.h - Scalar Transformation Library 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 libLLVMScalarOpts.a, which *|
+|* implements various scalar transformations of the LLVM IR. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_SCALAR_H
+#define LLVM_C_TRANSFORMS_SCALAR_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsScalar Scalar transformations
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::createAggressiveDCEPass function. */
+void LLVMAddAggressiveDCEPass(LLVMPassManagerRef PM);
+
+/** See llvm::createCFGSimplificationPass function. */
+void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createDeadStoreEliminationPass function. */
+void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createGVNPass function. */
+void LLVMAddGVNPass(LLVMPassManagerRef PM);
+
+/** See llvm::createIndVarSimplifyPass function. */
+void LLVMAddIndVarSimplifyPass(LLVMPassManagerRef PM);
+
+/** See llvm::createInstructionCombiningPass function. */
+void LLVMAddInstructionCombiningPass(LLVMPassManagerRef PM);
+
+/** See llvm::createJumpThreadingPass function. */
+void LLVMAddJumpThreadingPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLICMPass function. */
+void LLVMAddLICMPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopDeletionPass function. */
+void LLVMAddLoopDeletionPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopIdiomPass function */
+void LLVMAddLoopIdiomPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopRotatePass function. */
+void LLVMAddLoopRotatePass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopUnrollPass function. */
+void LLVMAddLoopUnrollPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLoopUnswitchPass function. */
+void LLVMAddLoopUnswitchPass(LLVMPassManagerRef PM);
+
+/** See llvm::createMemCpyOptPass function. */
+void LLVMAddMemCpyOptPass(LLVMPassManagerRef PM);
+
+/** See llvm::createPromoteMemoryToRegisterPass function. */
+void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef PM);
+
+/** See llvm::createReassociatePass function. */
+void LLVMAddReassociatePass(LLVMPassManagerRef PM);
+
+/** See llvm::createSCCPPass function. */
+void LLVMAddSCCPPass(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarReplAggregatesPass function. */
+void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarReplAggregatesPass function. */
+void LLVMAddScalarReplAggregatesPassSSA(LLVMPassManagerRef PM);
+
+/** See llvm::createScalarReplAggregatesPass function. */
+void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef PM,
+ int Threshold);
+
+/** See llvm::createSimplifyLibCallsPass function. */
+void LLVMAddSimplifyLibCallsPass(LLVMPassManagerRef PM);
+
+/** See llvm::createTailCallEliminationPass function. */
+void LLVMAddTailCallEliminationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createConstantPropagationPass function. */
+void LLVMAddConstantPropagationPass(LLVMPassManagerRef PM);
+
+/** See llvm::demotePromoteMemoryToRegisterPass function. */
+void LLVMAddDemoteMemoryToRegisterPass(LLVMPassManagerRef PM);
+
+/** See llvm::createVerifierPass function. */
+void LLVMAddVerifierPass(LLVMPassManagerRef PM);
+
+/** See llvm::createCorrelatedValuePropagationPass function */
+void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM);
+
+/** See llvm::createEarlyCSEPass function */
+void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM);
+
+/** See llvm::createLowerExpectIntrinsicPass function */
+void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM);
+
+/** See llvm::createTypeBasedAliasAnalysisPass function */
+void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM);
+
+/** See llvm::createBasicAliasAnalysisPass function */
+void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
diff --git a/contrib/llvm/include/llvm-c/Transforms/Vectorize.h b/contrib/llvm/include/llvm-c/Transforms/Vectorize.h
new file mode 100644
index 000000000000..9e7c7540d766
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/Transforms/Vectorize.h
@@ -0,0 +1,48 @@
+/*===---------------------------Vectorize.h --------------------- -*- C -*-===*\
+|*===----------- Vectorization Transformation Library C Interface ---------===*|
+|* *|
+|* 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 libLLVMVectorize.a, which *|
+|* implements various vectorization transformations of the LLVM IR. *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_TRANSFORMS_VECTORIZE_H
+#define LLVM_C_TRANSFORMS_VECTORIZE_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LLVMCTransformsVectorize Vectorization transformations
+ * @ingroup LLVMCTransforms
+ *
+ * @{
+ */
+
+/** See llvm::createBBVectorizePass function. */
+void LLVMAddBBVectorizePass(LLVMPassManagerRef PM);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif
+
diff --git a/contrib/llvm/include/llvm-c/lto.h b/contrib/llvm/include/llvm-c/lto.h
new file mode 100644
index 000000000000..f43d365e3dbe
--- /dev/null
+++ b/contrib/llvm/include/llvm-c/lto.h
@@ -0,0 +1,302 @@
+/*===-- llvm-c/lto.h - LTO Public 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 provides public interface to an abstract link time optimization*|
+|* library. LLVM provides an implementation of this interface for use with *|
+|* llvm bitcode files. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LTO_H
+#define LTO_H 1
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+
+/**
+ * @defgroup LLVMCLTO LTO
+ * @ingroup LLVMC
+ *
+ * @{
+ */
+
+#define LTO_API_VERSION 4
+
+typedef enum {
+ LTO_SYMBOL_ALIGNMENT_MASK = 0x0000001F, /* log2 of alignment */
+ LTO_SYMBOL_PERMISSIONS_MASK = 0x000000E0,
+ LTO_SYMBOL_PERMISSIONS_CODE = 0x000000A0,
+ LTO_SYMBOL_PERMISSIONS_DATA = 0x000000C0,
+ LTO_SYMBOL_PERMISSIONS_RODATA = 0x00000080,
+ LTO_SYMBOL_DEFINITION_MASK = 0x00000700,
+ LTO_SYMBOL_DEFINITION_REGULAR = 0x00000100,
+ LTO_SYMBOL_DEFINITION_TENTATIVE = 0x00000200,
+ LTO_SYMBOL_DEFINITION_WEAK = 0x00000300,
+ LTO_SYMBOL_DEFINITION_UNDEFINED = 0x00000400,
+ LTO_SYMBOL_DEFINITION_WEAKUNDEF = 0x00000500,
+ LTO_SYMBOL_SCOPE_MASK = 0x00003800,
+ LTO_SYMBOL_SCOPE_INTERNAL = 0x00000800,
+ LTO_SYMBOL_SCOPE_HIDDEN = 0x00001000,
+ LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000,
+ LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800,
+ LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800
+} lto_symbol_attributes;
+
+typedef enum {
+ LTO_DEBUG_MODEL_NONE = 0,
+ LTO_DEBUG_MODEL_DWARF = 1
+} lto_debug_model;
+
+typedef enum {
+ LTO_CODEGEN_PIC_MODEL_STATIC = 0,
+ LTO_CODEGEN_PIC_MODEL_DYNAMIC = 1,
+ LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC = 2
+} lto_codegen_model;
+
+
+/** opaque reference to a loaded object module */
+typedef struct LTOModule* lto_module_t;
+
+/** opaque reference to a code generator */
+typedef struct LTOCodeGenerator* lto_code_gen_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns a printable string.
+ */
+extern const char*
+lto_get_version(void);
+
+
+/**
+ * Returns the last error string or NULL if last operation was successful.
+ */
+extern const char*
+lto_get_error_message(void);
+
+/**
+ * Checks if a file is a loadable object file.
+ */
+extern bool
+lto_module_is_object_file(const char* path);
+
+
+/**
+ * Checks if a file is a loadable object compiled for requested target.
+ */
+extern bool
+lto_module_is_object_file_for_target(const char* path,
+ const char* target_triple_prefix);
+
+
+/**
+ * Checks if a buffer is a loadable object file.
+ */
+extern bool
+lto_module_is_object_file_in_memory(const void* mem, size_t length);
+
+
+/**
+ * Checks if a buffer is a loadable object compiled for requested target.
+ */
+extern bool
+lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length,
+ const char* target_triple_prefix);
+
+
+/**
+ * Loads an object file from disk.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ */
+extern lto_module_t
+lto_module_create(const char* path);
+
+
+/**
+ * Loads an object file from memory.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ */
+extern lto_module_t
+lto_module_create_from_memory(const void* mem, size_t length);
+
+/**
+ * Loads an object file from disk. The seek point of fd is not preserved.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ */
+extern lto_module_t
+lto_module_create_from_fd(int fd, const char *path, size_t file_size);
+
+/**
+ * Loads an object file from disk. The seek point of fd is not preserved.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ */
+extern lto_module_t
+lto_module_create_from_fd_at_offset(int fd, const char *path, size_t file_size,
+ size_t map_size, off_t offset);
+
+
+/**
+ * Frees all memory internally allocated by the module.
+ * Upon return the lto_module_t is no longer valid.
+ */
+extern void
+lto_module_dispose(lto_module_t mod);
+
+
+/**
+ * Returns triple string which the object module was compiled under.
+ */
+extern const char*
+lto_module_get_target_triple(lto_module_t mod);
+
+/**
+ * Sets triple string with which the object will be codegened.
+ */
+extern void
+lto_module_set_target_triple(lto_module_t mod, const char *triple);
+
+
+/**
+ * Returns the number of symbols in the object module.
+ */
+extern unsigned int
+lto_module_get_num_symbols(lto_module_t mod);
+
+
+/**
+ * Returns the name of the ith symbol in the object module.
+ */
+extern const char*
+lto_module_get_symbol_name(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Returns the attributes of the ith symbol in the object module.
+ */
+extern lto_symbol_attributes
+lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Instantiates a code generator.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ */
+extern lto_code_gen_t
+lto_codegen_create(void);
+
+
+/**
+ * Frees all code generator and all memory it internally allocated.
+ * Upon return the lto_code_gen_t is no longer valid.
+ */
+extern void
+lto_codegen_dispose(lto_code_gen_t);
+
+
+
+/**
+ * Add an object module to the set of modules for which code will be generated.
+ * Returns true on error (check lto_get_error_message() for details).
+ */
+extern bool
+lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod);
+
+
+
+/**
+ * Sets if debug info should be generated.
+ * Returns true on error (check lto_get_error_message() for details).
+ */
+extern bool
+lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model);
+
+
+/**
+ * Sets which PIC code model to generated.
+ * Returns true on error (check lto_get_error_message() for details).
+ */
+extern bool
+lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model);
+
+
+/**
+ * Sets the cpu to generate code for.
+ */
+extern void
+lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu);
+
+
+/**
+ * Sets the location of the assembler tool to run. If not set, libLTO
+ * will use gcc to invoke the assembler.
+ */
+extern void
+lto_codegen_set_assembler_path(lto_code_gen_t cg, const char* path);
+
+/**
+ * Sets extra arguments that libLTO should pass to the assembler.
+ */
+extern void
+lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
+ int nargs);
+
+/**
+ * Adds to a list of all global symbols that must exist in the final
+ * generated code. If a function is not listed, it might be
+ * inlined into every usage and optimized away.
+ */
+extern void
+lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
+
+/**
+ * Writes a new object file at the specified path that contains the
+ * merged contents of all modules added so far.
+ * Returns true on error (check lto_get_error_message() for details).
+ */
+extern bool
+lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
+
+/**
+ * Generates code for all added modules into one native object file.
+ * On success returns a pointer to a generated mach-o/ELF buffer and
+ * length set to the buffer size. The buffer is owned by the
+ * lto_code_gen_t and will be freed when lto_codegen_dispose()
+ * is called, or lto_codegen_compile() is called again.
+ * On failure, returns NULL (check lto_get_error_message() for details).
+ */
+extern const void*
+lto_codegen_compile(lto_code_gen_t cg, size_t* length);
+
+/**
+ * Generates code for all added modules into one native object file.
+ * The name of the file is written to name. Returns true on error.
+ */
+extern bool
+lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
+
+
+/**
+ * Sets options to help debug codegen bugs.
+ */
+extern void
+lto_codegen_debug_options(lto_code_gen_t cg, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/APFloat.h b/contrib/llvm/include/llvm/ADT/APFloat.h
new file mode 100644
index 000000000000..2b466f900c81
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/APFloat.h
@@ -0,0 +1,467 @@
+//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a class to represent arbitrary precision floating
+// point values and provide a variety of arithmetic operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+/* A self-contained host- and target-independent arbitrary-precision
+ floating-point software implementation. It uses bignum integer
+ arithmetic as provided by static functions in the APInt class.
+ The library will work with bignum integers whose parts are any
+ unsigned type at least 16 bits wide, but 64 bits is recommended.
+
+ Written for clarity rather than speed, in particular with a view
+ to use in the front-end of a cross compiler so that target
+ arithmetic can be correctly performed on the host. Performance
+ should nonetheless be reasonable, particularly for its intended
+ use. It may be useful as a base implementation for a run-time
+ library during development of a faster target-specific one.
+
+ All 5 rounding modes in the IEEE-754R draft are handled correctly
+ for all implemented operations. Currently implemented operations
+ are add, subtract, multiply, divide, fused-multiply-add,
+ conversion-to-float, conversion-to-integer and
+ conversion-from-integer. New rounding modes (e.g. away from zero)
+ can be added with three or four lines of code.
+
+ Four formats are built-in: IEEE single precision, double
+ precision, quadruple precision, and x87 80-bit extended double
+ (when operating with full extended precision). Adding a new
+ format that obeys IEEE semantics only requires adding two lines of
+ code: a declaration and definition of the format.
+
+ All operations return the status of that operation as an exception
+ bit-mask, so multiple operations can be done consecutively with
+ their results or-ed together. The returned status can be useful
+ for compiler diagnostics; e.g., inexact, underflow and overflow
+ can be easily diagnosed on constant folding, and compiler
+ optimizers can determine what exceptions would be raised by
+ folding operations and optimize, or perhaps not optimize,
+ accordingly.
+
+ At present, underflow tininess is detected after rounding; it
+ should be straight forward to add support for the before-rounding
+ case too.
+
+ The library reads hexadecimal floating point numbers as per C99,
+ and correctly rounds if necessary according to the specified
+ rounding mode. Syntax is required to have been validated by the
+ caller. It also converts floating point numbers to hexadecimal
+ text as per the C99 %a and %A conversions. The output precision
+ (or alternatively the natural minimal precision) can be specified;
+ if the requested precision is less than the natural precision the
+ output is correctly rounded for the specified rounding mode.
+
+ It also reads decimal floating point numbers and correctly rounds
+ according to the specified rounding mode.
+
+ Conversion to decimal text is not currently implemented.
+
+ Non-zero finite numbers are represented internally as a sign bit,
+ a 16-bit signed exponent, and the significand as an array of
+ integer parts. After normalization of a number of precision P the
+ exponent is within the range of the format, and if the number is
+ not denormal the P-th bit of the significand is set as an explicit
+ integer bit. For denormals the most significant bit is shifted
+ right so that the exponent is maintained at the format's minimum,
+ so that the smallest denormal has just the least significant bit
+ of the significand set. The sign of zeroes and infinities is
+ significant; the exponent and significand of such numbers is not
+ stored, but has a known implicit (deterministic) value: 0 for the
+ significands, 0 for zero exponent, all 1 bits for infinity
+ exponent. For NaNs the sign and significand are deterministic,
+ although not really meaningful, and preserved in non-conversion
+ operations. The exponent is implicitly all 1 bits.
+
+ TODO
+ ====
+
+ Some features that may or may not be worth adding:
+
+ Binary to decimal conversion (hard).
+
+ Optional ability to detect underflow tininess before rounding.
+
+ New formats: x87 in single and double precision mode (IEEE apart
+ from extended exponent range) (hard).
+
+ New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
+ nexttoward.
+*/
+
+#ifndef LLVM_FLOAT_H
+#define LLVM_FLOAT_H
+
+// APInt contains static functions implementing bignum arithmetic.
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+ /* Exponents are stored as signed numbers. */
+ typedef signed short exponent_t;
+
+ struct fltSemantics;
+ class APSInt;
+ class StringRef;
+
+ /* When bits of a floating point number are truncated, this enum is
+ used to indicate what fraction of the LSB those bits represented.
+ It essentially combines the roles of guard and sticky bits. */
+ enum lostFraction { // Example of truncated bits:
+ lfExactlyZero, // 000000
+ lfLessThanHalf, // 0xxxxx x's not all zero
+ lfExactlyHalf, // 100000
+ lfMoreThanHalf // 1xxxxx x's not all zero
+ };
+
+ class APFloat {
+ public:
+
+ /* We support the following floating point semantics. */
+ static const fltSemantics IEEEhalf;
+ static const fltSemantics IEEEsingle;
+ static const fltSemantics IEEEdouble;
+ static const fltSemantics IEEEquad;
+ static const fltSemantics PPCDoubleDouble;
+ static const fltSemantics x87DoubleExtended;
+ /* And this pseudo, used to construct APFloats that cannot
+ conflict with anything real. */
+ static const fltSemantics Bogus;
+
+ static unsigned int semanticsPrecision(const fltSemantics &);
+
+ /* Floating point numbers have a four-state comparison relation. */
+ enum cmpResult {
+ cmpLessThan,
+ cmpEqual,
+ cmpGreaterThan,
+ cmpUnordered
+ };
+
+ /* IEEE-754R gives five rounding modes. */
+ enum roundingMode {
+ rmNearestTiesToEven,
+ rmTowardPositive,
+ rmTowardNegative,
+ rmTowardZero,
+ rmNearestTiesToAway
+ };
+
+ // Operation status. opUnderflow or opOverflow are always returned
+ // or-ed with opInexact.
+ enum opStatus {
+ opOK = 0x00,
+ opInvalidOp = 0x01,
+ opDivByZero = 0x02,
+ opOverflow = 0x04,
+ opUnderflow = 0x08,
+ opInexact = 0x10
+ };
+
+ // Category of internally-represented number.
+ enum fltCategory {
+ fcInfinity,
+ fcNaN,
+ fcNormal,
+ fcZero
+ };
+
+ enum uninitializedTag {
+ uninitialized
+ };
+
+ // Constructors.
+ APFloat(const fltSemantics &); // Default construct to 0.0
+ APFloat(const fltSemantics &, StringRef);
+ APFloat(const fltSemantics &, integerPart);
+ APFloat(const fltSemantics &, fltCategory, bool negative);
+ APFloat(const fltSemantics &, uninitializedTag);
+ explicit APFloat(double d);
+ explicit APFloat(float f);
+ explicit APFloat(const APInt &, bool isIEEE = false);
+ APFloat(const APFloat &);
+ ~APFloat();
+
+ // Convenience "constructors"
+ static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
+ return APFloat(Sem, fcZero, Negative);
+ }
+ static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
+ return APFloat(Sem, fcInfinity, Negative);
+ }
+
+ /// getNaN - Factory for QNaN values.
+ ///
+ /// \param Negative - True iff the NaN generated should be negative.
+ /// \param type - The unspecified fill bits for creating the NaN, 0 by
+ /// default. The value is truncated as necessary.
+ static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+ unsigned type = 0) {
+ if (type) {
+ APInt fill(64, type);
+ return getQNaN(Sem, Negative, &fill);
+ } else {
+ return getQNaN(Sem, Negative, 0);
+ }
+ }
+
+ /// getQNan - Factory for QNaN values.
+ static APFloat getQNaN(const fltSemantics &Sem,
+ bool Negative = false,
+ const APInt *payload = 0) {
+ return makeNaN(Sem, false, Negative, payload);
+ }
+
+ /// getSNan - Factory for SNaN values.
+ static APFloat getSNaN(const fltSemantics &Sem,
+ bool Negative = false,
+ const APInt *payload = 0) {
+ return makeNaN(Sem, true, Negative, payload);
+ }
+
+ /// getLargest - Returns the largest finite number in the given
+ /// semantics.
+ ///
+ /// \param Negative - True iff the number should be negative
+ static APFloat getLargest(const fltSemantics &Sem, bool Negative = false);
+
+ /// getSmallest - Returns the smallest (by magnitude) finite number
+ /// in the given semantics. Might be denormalized, which implies a
+ /// relative loss of precision.
+ ///
+ /// \param Negative - True iff the number should be negative
+ static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false);
+
+ /// getSmallestNormalized - Returns the smallest (by magnitude)
+ /// normalized finite number in the given semantics.
+ ///
+ /// \param Negative - True iff the number should be negative
+ static APFloat getSmallestNormalized(const fltSemantics &Sem,
+ bool Negative = false);
+
+ /// getAllOnesValue - Returns a float which is bitcasted from
+ /// an all one value int.
+ ///
+ /// \param BitWidth - Select float type
+ /// \param isIEEE - If 128 bit number, select between PPC and IEEE
+ static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
+
+ /// Profile - Used to insert APFloat objects, or objects that contain
+ /// APFloat objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& NID) const;
+
+ /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+ void Emit(Serializer& S) const;
+
+ /// @brief Used by the Bitcode deserializer to deserialize APInts.
+ static APFloat ReadVal(Deserializer& D);
+
+ /* Arithmetic. */
+ opStatus add(const APFloat &, roundingMode);
+ opStatus subtract(const APFloat &, roundingMode);
+ opStatus multiply(const APFloat &, roundingMode);
+ opStatus divide(const APFloat &, roundingMode);
+ /* IEEE remainder. */
+ opStatus remainder(const APFloat &);
+ /* C fmod, or llvm frem. */
+ opStatus mod(const APFloat &, roundingMode);
+ opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
+
+ /* Sign operations. */
+ void changeSign();
+ void clearSign();
+ void copySign(const APFloat &);
+
+ /* Conversions. */
+ opStatus convert(const fltSemantics &, roundingMode, bool *);
+ opStatus convertToInteger(integerPart *, unsigned int, bool,
+ roundingMode, bool *) const;
+ opStatus convertToInteger(APSInt&, roundingMode, bool *) const;
+ opStatus convertFromAPInt(const APInt &,
+ bool, roundingMode);
+ opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
+ bool, roundingMode);
+ opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
+ bool, roundingMode);
+ opStatus convertFromString(StringRef, roundingMode);
+ APInt bitcastToAPInt() const;
+ double convertToDouble() const;
+ float convertToFloat() const;
+
+ /* The definition of equality is not straightforward for floating point,
+ so we won't use operator==. Use one of the following, or write
+ whatever it is you really mean. */
+ // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
+
+ /* IEEE comparison with another floating point number (NaNs
+ compare unordered, 0==-0). */
+ cmpResult compare(const APFloat &) const;
+
+ /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
+ bool bitwiseIsEqual(const APFloat &) const;
+
+ /* Write out a hexadecimal representation of the floating point
+ value to DST, which must be of sufficient size, in the C99 form
+ [-]0xh.hhhhp[+-]d. Return the number of characters written,
+ excluding the terminating NUL. */
+ unsigned int convertToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase, roundingMode) const;
+
+ /* Simple queries. */
+ fltCategory getCategory() const { return category; }
+ const fltSemantics &getSemantics() const { return *semantics; }
+ bool isZero() const { return category == fcZero; }
+ bool isNonZero() const { return category != fcZero; }
+ bool isNormal() const { return category == fcNormal; }
+ bool isNaN() const { return category == fcNaN; }
+ bool isInfinity() const { return category == fcInfinity; }
+ bool isNegative() const { return sign; }
+ bool isPosZero() const { return isZero() && !isNegative(); }
+ bool isNegZero() const { return isZero() && isNegative(); }
+
+ APFloat& operator=(const APFloat &);
+
+ /// \brief Overload to compute a hash code for an APFloat value.
+ ///
+ /// Note that the use of hash codes for floating point values is in general
+ /// frought with peril. Equality is hard to define for these values. For
+ /// example, should negative and positive zero hash to different codes? Are
+ /// they equal or not? This hash value implementation specifically
+ /// emphasizes producing different codes for different inputs in order to
+ /// be used in canonicalization and memoization. As such, equality is
+ /// bitwiseIsEqual, and 0 != -0.
+ friend hash_code hash_value(const APFloat &Arg);
+
+ /// Converts this value into a decimal string.
+ ///
+ /// \param FormatPrecision The maximum number of digits of
+ /// precision to output. If there are fewer digits available,
+ /// zero padding will not be used unless the value is
+ /// integral and small enough to be expressed in
+ /// FormatPrecision digits. 0 means to use the natural
+ /// precision of the number.
+ /// \param FormatMaxPadding The maximum number of zeros to
+ /// consider inserting before falling back to scientific
+ /// notation. 0 means to always use scientific notation.
+ ///
+ /// Number Precision MaxPadding Result
+ /// ------ --------- ---------- ------
+ /// 1.01E+4 5 2 10100
+ /// 1.01E+4 4 2 1.01E+4
+ /// 1.01E+4 5 1 1.01E+4
+ /// 1.01E-2 5 2 0.0101
+ /// 1.01E-2 4 2 0.0101
+ /// 1.01E-2 4 1 1.01E-2
+ void toString(SmallVectorImpl<char> &Str,
+ unsigned FormatPrecision = 0,
+ unsigned FormatMaxPadding = 3) const;
+
+ /// getExactInverse - If this value has an exact multiplicative inverse,
+ /// store it in inv and return true.
+ bool getExactInverse(APFloat *inv) const;
+
+ private:
+
+ /* Trivial queries. */
+ integerPart *significandParts();
+ const integerPart *significandParts() const;
+ unsigned int partCount() const;
+
+ /* Significand operations. */
+ integerPart addSignificand(const APFloat &);
+ integerPart subtractSignificand(const APFloat &, integerPart);
+ lostFraction addOrSubtractSignificand(const APFloat &, bool subtract);
+ lostFraction multiplySignificand(const APFloat &, const APFloat *);
+ lostFraction divideSignificand(const APFloat &);
+ void incrementSignificand();
+ void initialize(const fltSemantics *);
+ void shiftSignificandLeft(unsigned int);
+ lostFraction shiftSignificandRight(unsigned int);
+ unsigned int significandLSB() const;
+ unsigned int significandMSB() const;
+ void zeroSignificand();
+
+ /* Arithmetic on special values. */
+ opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
+ opStatus divideSpecials(const APFloat &);
+ opStatus multiplySpecials(const APFloat &);
+ opStatus modSpecials(const APFloat &);
+
+ /* Miscellany. */
+ static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
+ const APInt *fill);
+ void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0);
+ opStatus normalize(roundingMode, lostFraction);
+ opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
+ cmpResult compareAbsoluteValue(const APFloat &) const;
+ opStatus handleOverflow(roundingMode);
+ bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
+ opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+ roundingMode, bool *) const;
+ opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+ roundingMode);
+ opStatus convertFromHexadecimalString(StringRef, roundingMode);
+ opStatus convertFromDecimalString(StringRef, roundingMode);
+ char *convertNormalToHexString(char *, unsigned int, bool,
+ roundingMode) const;
+ opStatus roundSignificandWithExponent(const integerPart *, unsigned int,
+ int, roundingMode);
+
+ APInt convertHalfAPFloatToAPInt() const;
+ APInt convertFloatAPFloatToAPInt() const;
+ APInt convertDoubleAPFloatToAPInt() const;
+ APInt convertQuadrupleAPFloatToAPInt() const;
+ APInt convertF80LongDoubleAPFloatToAPInt() const;
+ APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
+ void initFromAPInt(const APInt& api, bool isIEEE = false);
+ void initFromHalfAPInt(const APInt& api);
+ void initFromFloatAPInt(const APInt& api);
+ void initFromDoubleAPInt(const APInt& api);
+ void initFromQuadrupleAPInt(const APInt &api);
+ void initFromF80LongDoubleAPInt(const APInt& api);
+ void initFromPPCDoubleDoubleAPInt(const APInt& api);
+
+ void assign(const APFloat &);
+ void copySignificand(const APFloat &);
+ void freeSignificand();
+
+ /* What kind of semantics does this value obey? */
+ const fltSemantics *semantics;
+
+ /* Significand - the fraction with an explicit integer bit. Must be
+ at least one bit wider than the target precision. */
+ union Significand
+ {
+ integerPart part;
+ integerPart *parts;
+ } significand;
+
+ /* The exponent - a signed number. */
+ exponent_t exponent;
+
+ /* What kind of floating point number this is. */
+ /* Only 2 bits are required, but VisualStudio incorrectly sign extends
+ it. Using the extra bit keeps it from failing under VisualStudio */
+ fltCategory category: 3;
+
+ /* 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;
+ };
+} /* namespace llvm */
+
+#endif /* LLVM_FLOAT_H */
diff --git a/contrib/llvm/include/llvm/ADT/APInt.h b/contrib/llvm/include/llvm/ADT/APInt.h
new file mode 100644
index 000000000000..41019899766b
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/APInt.h
@@ -0,0 +1,1755 @@
+//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- 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 class to represent arbitrary precision integral
+// constant values and operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APINT_H
+#define LLVM_APINT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <climits>
+#include <cstring>
+#include <string>
+
+namespace llvm {
+ class Deserializer;
+ class FoldingSetNodeID;
+ class Serializer;
+ class StringRef;
+ class hash_code;
+ class raw_ostream;
+
+ template<typename T>
+ class SmallVectorImpl;
+
+ // An unsigned host type used as a single part of a multi-part
+ // bignum.
+ typedef uint64_t integerPart;
+
+ const unsigned int host_char_bit = 8;
+ const unsigned int integerPartWidth = host_char_bit *
+ static_cast<unsigned int>(sizeof(integerPart));
+
+//===----------------------------------------------------------------------===//
+// APInt Class
+//===----------------------------------------------------------------------===//
+
+/// APInt - This class represents arbitrary precision constant integral values.
+/// It is a functional replacement for common case unsigned integer type like
+/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
+/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
+/// than 64-bits of precision. APInt provides a variety of arithmetic operators
+/// and methods to manipulate integer values of any bit-width. It supports both
+/// the typical integer arithmetic and comparison operations as well as bitwise
+/// manipulation.
+///
+/// The class has several invariants worth noting:
+/// * All bit, byte, and word positions are zero-based.
+/// * Once the bit width is set, it doesn't change except by the Truncate,
+/// SignExtend, or ZeroExtend operations.
+/// * All binary operators must be on APInt instances of the same bit width.
+/// Attempting to use these operators on instances with different bit
+/// widths will yield an assertion.
+/// * The value is stored canonically as an unsigned value. For operations
+/// where it makes a difference, there are both signed and unsigned variants
+/// of the operation. For example, sdiv and udiv. However, because the bit
+/// widths must be the same, operations such as Mul and Add produce the same
+/// results regardless of whether the values are interpreted as signed or
+/// not.
+/// * In general, the class tries to follow the style of computation that LLVM
+/// uses in its IR. This simplifies its use for LLVM.
+///
+/// @brief Class for arbitrary precision integers.
+class APInt {
+ unsigned BitWidth; ///< The number of bits in this APInt.
+
+ /// This union is used to store the integer value. When the
+ /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+
+ /// This enum is used to hold the constants we needed for APInt.
+ enum {
+ /// Bits in a word
+ APINT_BITS_PER_WORD = static_cast<unsigned int>(sizeof(uint64_t)) *
+ CHAR_BIT,
+ /// Byte size of a word
+ APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
+ };
+
+ /// This constructor is used only internally for speed of construction of
+ /// temporaries. It is unsafe for general use so it is not public.
+ /// @brief Fast internal constructor
+ APInt(uint64_t* val, unsigned bits) : BitWidth(bits), pVal(val) { }
+
+ /// @returns true if the number of bits <= 64, false otherwise.
+ /// @brief Determine if this APInt just has one word to store value.
+ bool isSingleWord() const {
+ return BitWidth <= APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the word position for the specified bit position.
+ /// @brief Determine which word a bit is in.
+ static unsigned whichWord(unsigned bitPosition) {
+ return bitPosition / APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the bit position in a word for the specified bit position
+ /// in the APInt.
+ /// @brief Determine which bit in a word a bit is in.
+ static unsigned whichBit(unsigned bitPosition) {
+ return bitPosition % APINT_BITS_PER_WORD;
+ }
+
+ /// This method generates and returns a uint64_t (word) mask for a single
+ /// bit at a specific bit position. This is used to mask the bit in the
+ /// corresponding word.
+ /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set
+ /// @brief Get a single bit mask.
+ static uint64_t maskBit(unsigned bitPosition) {
+ return 1ULL << whichBit(bitPosition);
+ }
+
+ /// This method is used internally to clear the to "N" bits in the high order
+ /// word that are not used by the APInt. This is needed after the most
+ /// significant word is assigned a value to ensure that those bits are
+ /// zero'd out.
+ /// @brief Clear unused high order bits
+ APInt& clearUnusedBits() {
+ // Compute how many bits are used in the final word
+ unsigned wordBits = BitWidth % APINT_BITS_PER_WORD;
+ if (wordBits == 0)
+ // If all bits are used, we want to leave the value alone. This also
+ // avoids the undefined behavior of >> when the shift is the same size as
+ // the word size (64).
+ return *this;
+
+ // Mask out the high bits.
+ uint64_t mask = ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - wordBits);
+ if (isSingleWord())
+ VAL &= mask;
+ else
+ pVal[getNumWords() - 1] &= mask;
+ return *this;
+ }
+
+ /// @returns the corresponding word for the specified bit position.
+ /// @brief Get the word corresponding to a bit position
+ uint64_t getWord(unsigned bitPosition) const {
+ return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+ }
+
+ /// Converts a string into a number. The string must be non-empty
+ /// and well-formed as a number of the given base. The bit-width
+ /// must be sufficient to hold the result.
+ ///
+ /// This is used by the constructors that take string arguments.
+ ///
+ /// StringRef::getAsInteger is superficially similar but (1) does
+ /// not assume that the string is well-formed and (2) grows the
+ /// result to hold the input.
+ ///
+ /// @param radix 2, 8, 10, 16, or 36
+ /// @brief Convert a char array into an APInt
+ void fromString(unsigned numBits, StringRef str, uint8_t radix);
+
+ /// This is used by the toString method to divide by the radix. It simply
+ /// provides a more convenient form of divide for internal use since KnuthDiv
+ /// has specific constraints on its inputs. If those constraints are not met
+ /// then it provides a simpler form of divide.
+ /// @brief An internal division function for dividing APInts.
+ static void divide(const APInt LHS, unsigned lhsWords,
+ const APInt &RHS, unsigned rhsWords,
+ APInt *Quotient, APInt *Remainder);
+
+ /// out-of-line slow case for inline constructor
+ void initSlowCase(unsigned numBits, uint64_t val, bool isSigned);
+
+ /// shared code between two array constructors
+ void initFromArray(ArrayRef<uint64_t> array);
+
+ /// out-of-line slow case for inline copy constructor
+ void initSlowCase(const APInt& that);
+
+ /// out-of-line slow case for shl
+ APInt shlSlowCase(unsigned shiftAmt) const;
+
+ /// out-of-line slow case for operator&
+ APInt AndSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator|
+ APInt OrSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator^
+ APInt XorSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator=
+ APInt& AssignSlowCase(const APInt& RHS);
+
+ /// out-of-line slow case for operator==
+ bool EqualSlowCase(const APInt& RHS) const;
+
+ /// out-of-line slow case for operator==
+ bool EqualSlowCase(uint64_t Val) const;
+
+ /// out-of-line slow case for countLeadingZeros
+ unsigned countLeadingZerosSlowCase() const;
+
+ /// out-of-line slow case for countTrailingOnes
+ unsigned countTrailingOnesSlowCase() const;
+
+ /// out-of-line slow case for countPopulation
+ unsigned countPopulationSlowCase() const;
+
+public:
+ /// @name Constructors
+ /// @{
+ /// If isSigned is true then val is treated as if it were a signed value
+ /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
+ /// will be done. Otherwise, no sign extension occurs (high order bits beyond
+ /// the range of val are zero filled).
+ /// @param numBits the bit width of the constructed APInt
+ /// @param val the initial value of the APInt
+ /// @param isSigned how to treat signedness of val
+ /// @brief Create a new APInt of numBits width, initialized as val.
+ APInt(unsigned numBits, uint64_t val, bool isSigned = false)
+ : BitWidth(numBits), VAL(0) {
+ assert(BitWidth && "bitwidth too small");
+ if (isSingleWord())
+ VAL = val;
+ else
+ initSlowCase(numBits, val, isSigned);
+ clearUnusedBits();
+ }
+
+ /// Note that bigVal.size() can be smaller or larger than the corresponding
+ /// bit width but any extraneous bits will be dropped.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param bigVal a sequence of words to form the initial value of the APInt
+ /// @brief Construct an APInt of numBits width, initialized as bigVal[].
+ APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
+ /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
+ /// deprecated because this constructor is prone to ambiguity with the
+ /// APInt(unsigned, uint64_t, bool) constructor.
+ ///
+ /// If this overload is ever deleted, care should be taken to prevent calls
+ /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
+ /// constructor.
+ APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
+
+ /// This constructor interprets the string \arg 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
+ /// string to require more bits than numBits.
+ ///
+ /// @param numBits the bit width of the constructed APInt
+ /// @param str the string to be interpreted
+ /// @param radix the radix to use for the conversion
+ /// @brief Construct an APInt from a string representation.
+ APInt(unsigned numBits, StringRef str, uint8_t radix);
+
+ /// Simply makes *this a copy of that.
+ /// @brief Copy Constructor.
+ APInt(const APInt& that)
+ : BitWidth(that.BitWidth), VAL(0) {
+ assert(BitWidth && "bitwidth too small");
+ if (isSingleWord())
+ VAL = that.VAL;
+ else
+ initSlowCase(that);
+ }
+
+ /// @brief Destructor.
+ ~APInt() {
+ if (!isSingleWord())
+ delete [] pVal;
+ }
+
+ /// Default constructor that creates an uninitialized APInt. This is useful
+ /// for object deserialization (pair this with the static method Read).
+ explicit APInt() : BitWidth(1) {}
+
+ /// Profile - Used to insert APInt objects, or objects that contain APInt
+ /// objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& id) const;
+
+ /// @}
+ /// @name Value Tests
+ /// @{
+ /// This tests the high bit of this APInt to determine if it is set.
+ /// @returns true if this APInt is negative, false otherwise
+ /// @brief Determine sign of this APInt.
+ bool isNegative() const {
+ return (*this)[BitWidth - 1];
+ }
+
+ /// This tests the high bit of the APInt to determine if it is unset.
+ /// @brief Determine if this APInt Value is non-negative (>= 0)
+ bool isNonNegative() const {
+ return !isNegative();
+ }
+
+ /// This tests if the value of this APInt is positive (> 0). Note
+ /// that 0 is not a positive value.
+ /// @returns true if this APInt is positive.
+ /// @brief Determine if this APInt Value is positive.
+ bool isStrictlyPositive() const {
+ return isNonNegative() && !!*this;
+ }
+
+ /// This checks to see if the value has all bits of the APInt are set or not.
+ /// @brief Determine if all bits are set
+ bool isAllOnesValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest unsigned value.
+ bool isMaxValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest signed value.
+ bool isMaxSignedValue() const {
+ return BitWidth == 1 ? VAL == 0 :
+ !isNegative() && countPopulation() == BitWidth - 1;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest unsigned value.
+ bool isMinValue() const {
+ return !*this;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest signed value.
+ bool isMinSignedValue() const {
+ return BitWidth == 1 ? VAL == 1 : isNegative() && isPowerOf2();
+ }
+
+ /// @brief Check if this APInt has an N-bits unsigned integer value.
+ bool isIntN(unsigned N) const {
+ assert(N && "N == 0 ???");
+ if (N >= getBitWidth())
+ return true;
+
+ if (isSingleWord())
+ return isUIntN(N, VAL);
+ return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth())
+ == (*this);
+ }
+
+ /// @brief Check if this APInt has an N-bits signed integer value.
+ bool isSignedIntN(unsigned N) const {
+ assert(N && "N == 0 ???");
+ return getMinSignedBits() <= N;
+ }
+
+ /// @returns true if the argument APInt value is a power of two > 0.
+ bool isPowerOf2() const {
+ if (isSingleWord())
+ return isPowerOf2_64(VAL);
+ return countPopulationSlowCase() == 1;
+ }
+
+ /// isSignBit - Return true if this is the value returned by getSignBit.
+ bool isSignBit() const { return isMinSignedValue(); }
+
+ /// This converts the APInt to a boolean value as a test against zero.
+ /// @brief Boolean conversion function.
+ bool getBoolValue() const {
+ return !!*this;
+ }
+
+ /// getLimitedValue - If this value is smaller than the specified limit,
+ /// return it, otherwise return the limit value. This causes the value
+ /// to saturate to the limit.
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return (getActiveBits() > 64 || getZExtValue() > Limit) ?
+ Limit : getZExtValue();
+ }
+
+ /// @}
+ /// @name Value Generators
+ /// @{
+ /// @brief Gets maximum unsigned value of APInt for specific bit width.
+ static APInt getMaxValue(unsigned numBits) {
+ return getAllOnesValue(numBits);
+ }
+
+ /// @brief Gets maximum signed value of APInt for a specific bit width.
+ static APInt getSignedMaxValue(unsigned numBits) {
+ APInt API = getAllOnesValue(numBits);
+ API.clearBit(numBits - 1);
+ return API;
+ }
+
+ /// @brief Gets minimum unsigned value of APInt for a specific bit width.
+ static APInt getMinValue(unsigned numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// @brief Gets minimum signed value of APInt for a specific bit width.
+ static APInt getSignedMinValue(unsigned numBits) {
+ APInt API(numBits, 0);
+ API.setBit(numBits - 1);
+ return API;
+ }
+
+ /// getSignBit - This is just a wrapper function of getSignedMinValue(), and
+ /// it helps code readability when we want to get a SignBit.
+ /// @brief Get the SignBit for a specific bit width.
+ static APInt getSignBit(unsigned BitWidth) {
+ return getSignedMinValue(BitWidth);
+ }
+
+ /// @returns the all-ones value for an APInt of the specified bit-width.
+ /// @brief Get the all-ones value.
+ static APInt getAllOnesValue(unsigned numBits) {
+ return APInt(numBits, -1ULL, true);
+ }
+
+ /// @returns the '0' value for an APInt of the specified bit-width.
+ /// @brief Get the '0' value.
+ static APInt getNullValue(unsigned numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the low bits and right shift to the least significant bit.
+ /// @returns the high "numBits" bits of this APInt.
+ APInt getHiBits(unsigned numBits) const;
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the high bits.
+ /// @returns the low "numBits" bits of this APInt.
+ APInt getLoBits(unsigned numBits) const;
+
+ /// getOneBitSet - Return an APInt with exactly one bit set in the result.
+ static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
+ APInt Res(numBits, 0);
+ Res.setBit(BitNo);
+ return Res;
+ }
+
+ /// Constructs an APInt value that has a contiguous range of bits set. The
+ /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
+ /// bits will be zero. For example, with parameters(32, 0, 16) you would get
+ /// 0x0000FFFF. If hiBit is less than loBit then the set bits "wrap". For
+ /// example, with parameters (32, 28, 4), you would get 0xF000000F.
+ /// @param numBits the intended bit width of the result
+ /// @param loBit the index of the lowest bit set.
+ /// @param hiBit the index of the highest bit set.
+ /// @returns An APInt value with the requested bits set.
+ /// @brief Get a value with a block of bits set.
+ static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
+ assert(hiBit <= numBits && "hiBit out of range");
+ assert(loBit < numBits && "loBit out of range");
+ if (hiBit < loBit)
+ return getLowBitsSet(numBits, hiBit) |
+ getHighBitsSet(numBits, numBits-loBit);
+ return getLowBitsSet(numBits, hiBit-loBit).shl(loBit);
+ }
+
+ /// Constructs an APInt value that has the top hiBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param hiBitsSet the number of high-order bits set in the result.
+ /// @brief Get a value with high bits set
+ static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
+ assert(hiBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (hiBitsSet == 0)
+ return APInt(numBits, 0);
+ unsigned shiftAmt = numBits - hiBitsSet;
+ // For small values, return quickly
+ if (numBits <= APINT_BITS_PER_WORD)
+ return APInt(numBits, ~0ULL << shiftAmt);
+ return getAllOnesValue(numBits).shl(shiftAmt);
+ }
+
+ /// Constructs an APInt value that has the bottom loBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param loBitsSet the number of low-order bits set in the result.
+ /// @brief Get a value with low bits set
+ static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
+ assert(loBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (loBitsSet == 0)
+ return APInt(numBits, 0);
+ if (loBitsSet == APINT_BITS_PER_WORD)
+ return APInt(numBits, -1ULL);
+ // For small values, return quickly.
+ if (loBitsSet <= APINT_BITS_PER_WORD)
+ return APInt(numBits, -1ULL >> (APINT_BITS_PER_WORD - loBitsSet));
+ return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
+ }
+
+ /// \brief Overload to compute a hash_code for an APInt value.
+ friend hash_code hash_value(const APInt &Arg);
+
+ /// This function returns a pointer to the internal storage of the APInt.
+ /// This is useful for writing out the APInt in binary form without any
+ /// conversions.
+ const uint64_t* getRawData() const {
+ if (isSingleWord())
+ return &VAL;
+ return &pVal[0];
+ }
+
+ /// @}
+ /// @name Unary Operators
+ /// @{
+ /// @returns a new APInt value representing *this incremented by one
+ /// @brief Postfix increment operator.
+ const APInt operator++(int) {
+ APInt API(*this);
+ ++(*this);
+ return API;
+ }
+
+ /// @returns *this incremented by one
+ /// @brief Prefix increment operator.
+ APInt& operator++();
+
+ /// @returns a new APInt representing *this decremented by one.
+ /// @brief Postfix decrement operator.
+ const APInt operator--(int) {
+ APInt API(*this);
+ --(*this);
+ return API;
+ }
+
+ /// @returns *this decremented by one.
+ /// @brief Prefix decrement operator.
+ APInt& operator--();
+
+ /// Performs a bitwise complement operation on this APInt.
+ /// @returns an APInt that is the bitwise complement of *this
+ /// @brief Unary bitwise complement operator.
+ APInt operator~() const {
+ APInt Result(*this);
+ Result.flipAllBits();
+ return Result;
+ }
+
+ /// Negates *this using two's complement logic.
+ /// @returns An APInt value representing the negation of *this.
+ /// @brief Unary negation operator
+ APInt operator-() const {
+ return APInt(BitWidth, 0) - (*this);
+ }
+
+ /// Performs logical negation operation on this APInt.
+ /// @returns true if *this is zero, false otherwise.
+ /// @brief Logical negation operator.
+ bool operator!() const {
+ if (isSingleWord())
+ return !VAL;
+
+ for (unsigned i = 0; i != getNumWords(); ++i)
+ if (pVal[i])
+ return false;
+ return true;
+ }
+
+ /// @}
+ /// @name Assignment Operators
+ /// @{
+ /// @returns *this after assignment of RHS.
+ /// @brief Copy assignment operator.
+ APInt& operator=(const APInt& RHS) {
+ // If the bitwidths are the same, we can avoid mucking with memory
+ if (isSingleWord() && RHS.isSingleWord()) {
+ VAL = RHS.VAL;
+ BitWidth = RHS.BitWidth;
+ return clearUnusedBits();
+ }
+
+ return AssignSlowCase(RHS);
+ }
+
+ /// The RHS value is assigned to *this. If the significant bits in RHS exceed
+ /// the bit width, the excess bits are truncated. If the bit width is larger
+ /// than 64, the value is zero filled in the unspecified high order bits.
+ /// @returns *this after assignment of RHS value.
+ /// @brief Assignment operator.
+ APInt& operator=(uint64_t RHS);
+
+ /// Performs a bitwise AND operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after ANDing with RHS.
+ /// @brief Bitwise AND assignment operator.
+ APInt& operator&=(const APInt& RHS);
+
+ /// Performs a bitwise OR operation on this APInt and RHS. The result is
+ /// assigned *this;
+ /// @returns *this after ORing with RHS.
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(const APInt& RHS);
+
+ /// Performs a bitwise OR operation on this APInt and RHS. RHS is
+ /// logically zero-extended or truncated to match the bit-width of
+ /// the LHS.
+ ///
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(uint64_t RHS) {
+ if (isSingleWord()) {
+ VAL |= RHS;
+ clearUnusedBits();
+ } else {
+ pVal[0] |= RHS;
+ }
+ return *this;
+ }
+
+ /// Performs a bitwise XOR operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after XORing with RHS.
+ /// @brief Bitwise XOR assignment operator.
+ APInt& operator^=(const APInt& RHS);
+
+ /// Multiplies this APInt by RHS and assigns the result to *this.
+ /// @returns *this
+ /// @brief Multiplication assignment operator.
+ APInt& operator*=(const APInt& RHS);
+
+ /// Adds RHS to *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Addition assignment operator.
+ APInt& operator+=(const APInt& RHS);
+
+ /// Subtracts RHS from *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Subtraction assignment operator.
+ APInt& operator-=(const APInt& RHS);
+
+ /// Shifts *this left by shiftAmt and assigns the result to *this.
+ /// @returns *this after shifting left by shiftAmt
+ /// @brief Left-shift assignment function.
+ APInt& operator<<=(unsigned shiftAmt) {
+ *this = shl(shiftAmt);
+ return *this;
+ }
+
+ /// @}
+ /// @name Binary Operators
+ /// @{
+ /// Performs a bitwise AND operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise AND of *this and RHS.
+ /// @brief Bitwise AND operator.
+ APInt operator&(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(getBitWidth(), VAL & RHS.VAL);
+ return AndSlowCase(RHS);
+ }
+ APInt And(const APInt& RHS) const {
+ return this->operator&(RHS);
+ }
+
+ /// Performs a bitwise OR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise OR of *this and RHS.
+ /// @brief Bitwise OR operator.
+ APInt operator|(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(getBitWidth(), VAL | RHS.VAL);
+ return OrSlowCase(RHS);
+ }
+ APInt Or(const APInt& RHS) const {
+ return this->operator|(RHS);
+ }
+
+ /// Performs a bitwise XOR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise XOR of *this and RHS.
+ /// @brief Bitwise XOR operator.
+ APInt operator^(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
+ if (isSingleWord())
+ return APInt(BitWidth, VAL ^ RHS.VAL);
+ return XorSlowCase(RHS);
+ }
+ APInt Xor(const APInt& RHS) const {
+ return this->operator^(RHS);
+ }
+
+ /// Multiplies this APInt by RHS and returns the result.
+ /// @brief Multiplication operator.
+ APInt operator*(const APInt& RHS) const;
+
+ /// Adds RHS to this APInt and returns the result.
+ /// @brief Addition operator.
+ APInt operator+(const APInt& RHS) const;
+ APInt operator+(uint64_t RHS) const {
+ return (*this) + APInt(BitWidth, RHS);
+ }
+
+ /// Subtracts RHS from this APInt and returns the result.
+ /// @brief Subtraction operator.
+ APInt operator-(const APInt& RHS) const;
+ APInt operator-(uint64_t RHS) const {
+ return (*this) - APInt(BitWidth, RHS);
+ }
+
+ APInt operator<<(unsigned Bits) const {
+ return shl(Bits);
+ }
+
+ APInt operator<<(const APInt &Bits) const {
+ return shl(Bits);
+ }
+
+ /// Arithmetic right-shift this APInt by shiftAmt.
+ /// @brief Arithmetic right-shift function.
+ APInt ashr(unsigned shiftAmt) const;
+
+ /// Logical right-shift this APInt by shiftAmt.
+ /// @brief Logical right-shift function.
+ APInt lshr(unsigned shiftAmt) const;
+
+ /// Left-shift this APInt by shiftAmt.
+ /// @brief Left-shift function.
+ APInt shl(unsigned shiftAmt) const {
+ assert(shiftAmt <= BitWidth && "Invalid shift amount");
+ if (isSingleWord()) {
+ if (shiftAmt == BitWidth)
+ return APInt(BitWidth, 0); // avoid undefined shift results
+ return APInt(BitWidth, VAL << shiftAmt);
+ }
+ return shlSlowCase(shiftAmt);
+ }
+
+ /// @brief Rotate left by rotateAmt.
+ APInt rotl(unsigned rotateAmt) const;
+
+ /// @brief Rotate right by rotateAmt.
+ APInt rotr(unsigned rotateAmt) const;
+
+ /// Arithmetic right-shift this APInt by shiftAmt.
+ /// @brief Arithmetic right-shift function.
+ APInt ashr(const APInt &shiftAmt) const;
+
+ /// Logical right-shift this APInt by shiftAmt.
+ /// @brief Logical right-shift function.
+ APInt lshr(const APInt &shiftAmt) const;
+
+ /// Left-shift this APInt by shiftAmt.
+ /// @brief Left-shift function.
+ APInt shl(const APInt &shiftAmt) const;
+
+ /// @brief Rotate left by rotateAmt.
+ APInt rotl(const APInt &rotateAmt) const;
+
+ /// @brief Rotate right by rotateAmt.
+ APInt rotr(const APInt &rotateAmt) const;
+
+ /// Perform an unsigned divide operation on this APInt by RHS. Both this and
+ /// RHS are treated as unsigned quantities for purposes of this division.
+ /// @returns a new APInt value containing the division result
+ /// @brief Unsigned division operation.
+ APInt udiv(const APInt &RHS) const;
+
+ /// Signed divide this APInt by APInt RHS.
+ /// @brief Signed division function for APInt.
+ APInt sdiv(const APInt &RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return (-(*this)).udiv(-RHS);
+ else
+ return -((-(*this)).udiv(RHS));
+ else if (RHS.isNegative())
+ return -(this->udiv(-RHS));
+ return this->udiv(RHS);
+ }
+
+ /// Perform an unsigned remainder operation on this APInt with RHS being the
+ /// divisor. Both this and RHS are treated as unsigned quantities for purposes
+ /// of this operation. Note that this is a true remainder operation and not
+ /// a modulo operation because the sign follows the sign of the dividend
+ /// which is *this.
+ /// @returns a new APInt value containing the remainder result
+ /// @brief Unsigned remainder operation.
+ APInt urem(const APInt &RHS) const;
+
+ /// Signed remainder operation on APInt.
+ /// @brief Function for signed remainder operation.
+ APInt srem(const APInt &RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return -((-(*this)).urem(-RHS));
+ else
+ return -((-(*this)).urem(RHS));
+ else if (RHS.isNegative())
+ return this->urem(-RHS);
+ return this->urem(RHS);
+ }
+
+ /// Sometimes it is convenient to divide two APInt values and obtain both the
+ /// quotient and remainder. This function does both operations in the same
+ /// computation making it a little more efficient. The pair of input arguments
+ /// may overlap with the pair of output arguments. It is safe to call
+ /// udivrem(X, Y, X, Y), for example.
+ /// @brief Dual division/remainder interface.
+ static void udivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder);
+
+ static void sdivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder) {
+ if (LHS.isNegative()) {
+ if (RHS.isNegative())
+ APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
+ else
+ APInt::udivrem(-LHS, RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ Remainder = -Remainder;
+ } else if (RHS.isNegative()) {
+ APInt::udivrem(LHS, -RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ } else {
+ APInt::udivrem(LHS, RHS, Quotient, Remainder);
+ }
+ }
+
+
+ // Operations that return overflow indicators.
+ APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
+ APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
+ APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
+ APInt usub_ov(const APInt &RHS, bool &Overflow) const;
+ APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
+ APInt smul_ov(const APInt &RHS, bool &Overflow) const;
+ APInt umul_ov(const APInt &RHS, bool &Overflow) const;
+ APInt sshl_ov(unsigned Amt, bool &Overflow) const;
+
+ /// @returns the bit value at bitPosition
+ /// @brief Array-indexing support.
+ bool operator[](unsigned bitPosition) const {
+ assert(bitPosition < getBitWidth() && "Bit position out of bounds!");
+ return (maskBit(bitPosition) &
+ (isSingleWord() ? VAL : pVal[whichWord(bitPosition)])) != 0;
+ }
+
+ /// @}
+ /// @name Comparison Operators
+ /// @{
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @brief Equality operator.
+ bool operator==(const APInt& RHS) const {
+ assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths");
+ if (isSingleWord())
+ return VAL == RHS.VAL;
+ return EqualSlowCase(RHS);
+ }
+
+ /// Compares this APInt with a uint64_t for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality operator.
+ bool operator==(uint64_t Val) const {
+ if (isSingleWord())
+ return VAL == Val;
+ return EqualSlowCase(Val);
+ }
+
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality comparison.
+ bool eq(const APInt &RHS) const {
+ return (*this) == RHS;
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ bool operator!=(const APInt& RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Compares this APInt with a uint64_t for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ bool operator!=(uint64_t Val) const {
+ return !((*this) == Val);
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality comparison
+ bool ne(const APInt &RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered unsigned.
+ /// @brief Unsigned less than comparison
+ bool ult(const APInt &RHS) const;
+
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when considered unsigned.
+ /// @brief Unsigned less than comparison
+ bool ult(uint64_t RHS) const {
+ return ult(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered signed.
+ /// @brief Signed less than comparison
+ bool slt(const APInt& RHS) const;
+
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when considered signed.
+ /// @brief Signed less than comparison
+ bool slt(uint64_t RHS) const {
+ return slt(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered unsigned.
+ /// @brief Unsigned less or equal comparison
+ bool ule(const APInt& RHS) const {
+ return ult(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when considered unsigned.
+ /// @brief Unsigned less or equal comparison
+ bool ule(uint64_t RHS) const {
+ return ule(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered signed.
+ /// @brief Signed less or equal comparison
+ bool sle(const APInt& RHS) const {
+ return slt(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when considered signed.
+ /// @brief Signed less or equal comparison
+ bool sle(uint64_t RHS) const {
+ return sle(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered unsigned.
+ /// @brief Unsigned greather than comparison
+ bool ugt(const APInt& RHS) const {
+ return !ult(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when considered unsigned.
+ /// @brief Unsigned greater than comparison
+ bool ugt(uint64_t RHS) const {
+ return ugt(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered signed.
+ /// @brief Signed greather than comparison
+ bool sgt(const APInt& RHS) const {
+ return !slt(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when considered signed.
+ /// @brief Signed greater than comparison
+ bool sgt(uint64_t RHS) const {
+ return sgt(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered unsigned.
+ /// @brief Unsigned greater or equal comparison
+ bool uge(const APInt& RHS) const {
+ return !ult(RHS);
+ }
+
+ /// Regards both *this as an unsigned quantity and compares it with RHS for
+ /// the validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when considered unsigned.
+ /// @brief Unsigned greater or equal comparison
+ bool uge(uint64_t RHS) const {
+ return uge(APInt(getBitWidth(), RHS));
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered signed.
+ /// @brief Signed greather or equal comparison
+ bool sge(const APInt& RHS) const {
+ return !slt(RHS);
+ }
+
+ /// Regards both *this as a signed quantity and compares it with RHS for
+ /// the validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when considered signed.
+ /// @brief Signed greater or equal comparison
+ bool sge(uint64_t RHS) const {
+ return sge(APInt(getBitWidth(), RHS));
+ }
+
+
+
+
+ /// This operation tests if there are any pairs of corresponding bits
+ /// between this APInt and RHS that are both set.
+ bool intersects(const APInt &RHS) const {
+ return (*this & RHS) != 0;
+ }
+
+ /// @}
+ /// @name Resizing Operators
+ /// @{
+ /// Truncate the APInt to a specified width. It is an error to specify a width
+ /// that is greater than or equal to the current width.
+ /// @brief Truncate to new width.
+ APInt trunc(unsigned width) const;
+
+ /// This operation sign extends the APInt to a new width. If the high order
+ /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
+ /// It is an error to specify a width that is less than or equal to the
+ /// current width.
+ /// @brief Sign extend to a new width.
+ APInt sext(unsigned width) const;
+
+ /// This operation zero extends the APInt to a new width. The high order bits
+ /// are filled with 0 bits. It is an error to specify a width that is less
+ /// than or equal to the current width.
+ /// @brief Zero extend to a new width.
+ APInt zext(unsigned width) const;
+
+ /// Make this APInt have the bit width given by \p width. The value is sign
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Sign extend or truncate to width
+ APInt sextOrTrunc(unsigned width) const;
+
+ /// Make this APInt have the bit width given by \p width. The value is zero
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Zero extend or truncate to width
+ APInt zextOrTrunc(unsigned width) const;
+
+ /// Make this APInt have the bit width given by \p width. The value is sign
+ /// extended, or left alone to make it that width.
+ /// @brief Sign extend or truncate to width
+ APInt sextOrSelf(unsigned width) const;
+
+ /// Make this APInt have the bit width given by \p width. The value is zero
+ /// extended, or left alone to make it that width.
+ /// @brief Zero extend or truncate to width
+ APInt zextOrSelf(unsigned width) const;
+
+ /// @}
+ /// @name Bit Manipulation Operators
+ /// @{
+ /// @brief Set every bit to 1.
+ void setAllBits() {
+ if (isSingleWord())
+ VAL = -1ULL;
+ else {
+ // Set all the bits in all the words.
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] = -1ULL;
+ }
+ // Clear the unused ones
+ clearUnusedBits();
+ }
+
+ /// Set the given bit to 1 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 1.
+ void setBit(unsigned bitPosition);
+
+ /// @brief Set every bit to 0.
+ void clearAllBits() {
+ if (isSingleWord())
+ VAL = 0;
+ else
+ memset(pVal, 0, getNumWords() * APINT_WORD_SIZE);
+ }
+
+ /// Set the given bit to 0 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 0.
+ void clearBit(unsigned bitPosition);
+
+ /// @brief Toggle every bit to its opposite value.
+ void flipAllBits() {
+ if (isSingleWord())
+ VAL ^= -1ULL;
+ else {
+ for (unsigned i = 0; i < getNumWords(); ++i)
+ pVal[i] ^= -1ULL;
+ }
+ clearUnusedBits();
+ }
+
+ /// Toggle a given bit to its opposite value whose position is given
+ /// as "bitPosition".
+ /// @brief Toggles a given bit to its opposite value.
+ void flipBit(unsigned bitPosition);
+
+ /// @}
+ /// @name Value Characterization Functions
+ /// @{
+
+ /// @returns the total number of bits.
+ unsigned getBitWidth() const {
+ return BitWidth;
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value of this APInt.
+ /// @brief Get the number of words.
+ unsigned getNumWords() const {
+ return getNumWords(BitWidth);
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value with a
+ /// given bit width.
+ /// @brief Get the number of words.
+ static unsigned getNumWords(unsigned BitWidth) {
+ return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ }
+
+ /// This function returns the number of active bits which is defined as the
+ /// bit width minus the number of leading zeros. This is used in several
+ /// computations to see how "wide" the value is.
+ /// @brief Compute the number of active bits in the value
+ unsigned getActiveBits() const {
+ return BitWidth - countLeadingZeros();
+ }
+
+ /// This function returns the number of active words in the value of this
+ /// APInt. This is used in conjunction with getActiveData to extract the raw
+ /// value of the APInt.
+ unsigned getActiveWords() const {
+ return whichWord(getActiveBits()-1) + 1;
+ }
+
+ /// Computes the minimum bit width for this APInt while considering it to be
+ /// a signed (and probably negative) value. If the value is not negative,
+ /// this function returns the same value as getActiveBits()+1. Otherwise, it
+ /// returns the smallest bit width that will retain the negative value. For
+ /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
+ /// for -1, this function will always return 1.
+ /// @brief Get the minimum bit size for this signed APInt
+ unsigned getMinSignedBits() const {
+ if (isNegative())
+ return BitWidth - countLeadingOnes() + 1;
+ return getActiveBits()+1;
+ }
+
+ /// This method attempts to return the value of this APInt as a zero extended
+ /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
+ /// uint64_t. Otherwise an assertion will result.
+ /// @brief Get zero extended value
+ uint64_t getZExtValue() const {
+ if (isSingleWord())
+ return VAL;
+ assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
+ return pVal[0];
+ }
+
+ /// This method attempts to return the value of this APInt as a sign extended
+ /// int64_t. The bit width must be <= 64 or the value must fit within an
+ /// int64_t. Otherwise an assertion will result.
+ /// @brief Get sign extended value
+ int64_t getSExtValue() const {
+ if (isSingleWord())
+ return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >>
+ (APINT_BITS_PER_WORD - BitWidth);
+ assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
+ return int64_t(pVal[0]);
+ }
+
+ /// This method determines how many bits are required to hold the APInt
+ /// equivalent of the string given by \arg str.
+ /// @brief Get bits required for string value.
+ static unsigned getBitsNeeded(StringRef str, uint8_t radix);
+
+ /// countLeadingZeros - This function is an APInt version of the
+ /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
+ /// of zeros from the most significant bit to the first one bit.
+ /// @returns BitWidth if the value is zero.
+ /// @returns the number of zeros from the most significant bit to the first
+ /// one bits.
+ unsigned countLeadingZeros() const {
+ if (isSingleWord()) {
+ unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
+ return CountLeadingZeros_64(VAL) - unusedBits;
+ }
+ return countLeadingZerosSlowCase();
+ }
+
+ /// countLeadingOnes - This function is an APInt version of the
+ /// countLeadingOnes_{32,64} functions in MathExtras.h. It counts the number
+ /// of ones from the most significant bit to the first zero bit.
+ /// @returns 0 if the high order bit is not set
+ /// @returns the number of 1 bits from the most significant to the least
+ /// @brief Count the number of leading one bits.
+ unsigned countLeadingOnes() const;
+
+ /// Computes the number of leading bits of this APInt that are equal to its
+ /// sign bit.
+ unsigned getNumSignBits() const {
+ return isNegative() ? countLeadingOnes() : countLeadingZeros();
+ }
+
+ /// countTrailingZeros - This function is an APInt version of the
+ /// countTrailingZeros_{32,64} functions in MathExtras.h. It counts
+ /// the number of zeros from the least significant bit to the first set bit.
+ /// @returns BitWidth if the value is zero.
+ /// @returns the number of zeros from the least significant bit to the first
+ /// one bit.
+ /// @brief Count the number of trailing zero bits.
+ unsigned countTrailingZeros() const;
+
+ /// countTrailingOnes - This function is an APInt version of the
+ /// countTrailingOnes_{32,64} functions in MathExtras.h. It counts
+ /// the number of ones from the least significant bit to the first zero bit.
+ /// @returns BitWidth if the value is all ones.
+ /// @returns the number of ones from the least significant bit to the first
+ /// zero bit.
+ /// @brief Count the number of trailing one bits.
+ unsigned countTrailingOnes() const {
+ if (isSingleWord())
+ return CountTrailingOnes_64(VAL);
+ return countTrailingOnesSlowCase();
+ }
+
+ /// countPopulation - This function is an APInt version of the
+ /// countPopulation_{32,64} functions in MathExtras.h. It counts the number
+ /// of 1 bits in the APInt value.
+ /// @returns 0 if the value is zero.
+ /// @returns the number of set bits.
+ /// @brief Count the number of bits set.
+ unsigned countPopulation() const {
+ if (isSingleWord())
+ return CountPopulation_64(VAL);
+ return countPopulationSlowCase();
+ }
+
+ /// @}
+ /// @name Conversion Functions
+ /// @{
+ void print(raw_ostream &OS, bool isSigned) const;
+
+ /// toString - Converts an APInt to a string and append it to Str. Str is
+ /// commonly a SmallString.
+ void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
+ bool formatAsCLiteral = false) const;
+
+ /// Considers the APInt to be unsigned and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 16, or 36.
+ void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+ toString(Str, Radix, false, false);
+ }
+
+ /// Considers the APInt to be signed and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10, 16, or 36.
+ void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+ toString(Str, Radix, true, false);
+ }
+
+ /// toString - This returns the APInt as a std::string. Note that this is an
+ /// inefficient method. It is better to pass in a SmallVector/SmallString
+ /// to the methods above to avoid thrashing the heap for the string.
+ std::string toString(unsigned Radix, bool Signed) const;
+
+
+ /// @returns a byte-swapped representation of this APInt Value.
+ APInt byteSwap() const;
+
+ /// @brief Converts this APInt to a double value.
+ double roundToDouble(bool isSigned) const;
+
+ /// @brief Converts this unsigned APInt to a double value.
+ double roundToDouble() const {
+ return roundToDouble(false);
+ }
+
+ /// @brief Converts this signed APInt to a double value.
+ double signedRoundToDouble() const {
+ return roundToDouble(true);
+ }
+
+ /// The conversion does not do a translation from integer to double, it just
+ /// re-interprets the bits as a double. Note that it is valid to do this on
+ /// any bit width. Exactly 64 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ double bitsToDouble() const {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.I = (isSingleWord() ? VAL : pVal[0]);
+ return T.D;
+ }
+
+ /// The conversion does not do a translation from integer to float, it just
+ /// re-interprets the bits as a float. Note that it is valid to do this on
+ /// any bit width. Exactly 32 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ float bitsToFloat() const {
+ union {
+ unsigned I;
+ float F;
+ } T;
+ T.I = unsigned((isSingleWord() ? VAL : pVal[0]));
+ return T.F;
+ }
+
+ /// The conversion does not do a translation from double to integer, it just
+ /// re-interprets the bits of the double.
+ /// @brief Converts a double to APInt bits.
+ static APInt doubleToBits(double V) {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.D = V;
+ return APInt(sizeof T * CHAR_BIT, T.I);
+ }
+
+ /// The conversion does not do a translation from float to integer, it just
+ /// re-interprets the bits of the float.
+ /// @brief Converts a float to APInt bits.
+ static APInt floatToBits(float V) {
+ union {
+ unsigned I;
+ float F;
+ } T;
+ T.F = V;
+ return APInt(sizeof T * CHAR_BIT, T.I);
+ }
+
+ /// @}
+ /// @name Mathematics Operations
+ /// @{
+
+ /// @returns the floor log base 2 of this APInt.
+ unsigned logBase2() const {
+ return BitWidth - 1 - countLeadingZeros();
+ }
+
+ /// @returns the ceil log base 2 of this APInt.
+ unsigned ceilLogBase2() const {
+ return BitWidth - (*this - 1).countLeadingZeros();
+ }
+
+ /// @returns the log base 2 of this APInt if its an exact power of two, -1
+ /// otherwise
+ int32_t exactLogBase2() const {
+ if (!isPowerOf2())
+ return -1;
+ return logBase2();
+ }
+
+ /// @brief Compute the square root
+ APInt sqrt() const;
+
+ /// If *this is < 0 then return -(*this), otherwise *this;
+ /// @brief Get the absolute value;
+ APInt abs() const {
+ if (isNegative())
+ return -(*this);
+ return *this;
+ }
+
+ /// @returns the multiplicative inverse for a given modulo.
+ APInt multiplicativeInverse(const APInt& modulo) const;
+
+ /// @}
+ /// @name Support for division by constant
+ /// @{
+
+ /// Calculate the magic number for signed division by a constant.
+ struct ms;
+ ms magic() const;
+
+ /// Calculate the magic number for unsigned division by a constant.
+ struct mu;
+ mu magicu(unsigned LeadingZeros = 0) const;
+
+ /// @}
+ /// @name Building-block Operations for APInt and APFloat
+ /// @{
+
+ // These building block operations operate on a representation of
+ // arbitrary precision, two's-complement, bignum integer values.
+ // They should be sufficient to implement APInt and APFloat bignum
+ // requirements. Inputs are generally a pointer to the base of an
+ // array of integer parts, representing an unsigned bignum, and a
+ // count of how many parts there are.
+
+ /// Sets the least significant part of a bignum to the input value,
+ /// and zeroes out higher parts. */
+ static void tcSet(integerPart *, integerPart, unsigned int);
+
+ /// Assign one bignum to another.
+ static void tcAssign(integerPart *, const integerPart *, unsigned int);
+
+ /// Returns true if a bignum is zero, false otherwise.
+ static bool tcIsZero(const integerPart *, unsigned int);
+
+ /// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
+ static int tcExtractBit(const integerPart *, unsigned int bit);
+
+ /// Copy the bit vector of width srcBITS from SRC, starting at bit
+ /// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB
+ /// becomes the least significant bit of DST. All high bits above
+ /// srcBITS in DST are zero-filled.
+ static void tcExtract(integerPart *, unsigned int dstCount,
+ const integerPart *,
+ unsigned int srcBits, unsigned int srcLSB);
+
+ /// Set the given bit of a bignum. Zero-based.
+ static void tcSetBit(integerPart *, unsigned int bit);
+
+ /// Clear the given bit of a bignum. Zero-based.
+ static void tcClearBit(integerPart *, unsigned int bit);
+
+ /// Returns the bit number of the least or most significant set bit
+ /// of a number. If the input number has no bits set -1U is
+ /// returned.
+ static unsigned int tcLSB(const integerPart *, unsigned int);
+ static unsigned int tcMSB(const integerPart *parts, unsigned int n);
+
+ /// Negate a bignum in-place.
+ static void tcNegate(integerPart *, unsigned int);
+
+ /// DST += RHS + CARRY where CARRY is zero or one. Returns the
+ /// carry flag.
+ static integerPart tcAdd(integerPart *, const integerPart *,
+ integerPart carry, unsigned);
+
+ /// DST -= RHS + CARRY where CARRY is zero or one. Returns the
+ /// carry flag.
+ static integerPart tcSubtract(integerPart *, const integerPart *,
+ integerPart carry, unsigned);
+
+ /// DST += SRC * MULTIPLIER + PART if add is true
+ /// DST = SRC * MULTIPLIER + PART if add is false
+ ///
+ /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC
+ /// they must start at the same point, i.e. DST == SRC.
+ ///
+ /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is
+ /// returned. Otherwise DST is filled with the least significant
+ /// DSTPARTS parts of the result, and if all of the omitted higher
+ /// parts were zero return zero, otherwise overflow occurred and
+ /// return one.
+ static int tcMultiplyPart(integerPart *dst, const integerPart *src,
+ integerPart multiplier, integerPart carry,
+ unsigned int srcParts, unsigned int dstParts,
+ bool add);
+
+ /// DST = LHS * RHS, where DST has the same width as the operands
+ /// and is filled with the least significant parts of the result.
+ /// Returns one if overflow occurred, otherwise zero. DST must be
+ /// disjoint from both operands.
+ static int tcMultiply(integerPart *, const integerPart *,
+ const integerPart *, unsigned);
+
+ /// DST = LHS * RHS, where DST has width the sum of the widths of
+ /// the operands. No overflow occurs. DST must be disjoint from
+ /// both operands. Returns the number of parts required to hold the
+ /// result.
+ static unsigned int tcFullMultiply(integerPart *, const integerPart *,
+ const integerPart *, unsigned, unsigned);
+
+ /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
+ /// Otherwise set LHS to LHS / RHS with the fractional part
+ /// discarded, set REMAINDER to the remainder, return zero. i.e.
+ ///
+ /// OLD_LHS = RHS * LHS + REMAINDER
+ ///
+ /// SCRATCH is a bignum of the same size as the operands and result
+ /// for use by the routine; its contents need not be initialized
+ /// and are destroyed. LHS, REMAINDER and SCRATCH must be
+ /// distinct.
+ static int tcDivide(integerPart *lhs, const integerPart *rhs,
+ integerPart *remainder, integerPart *scratch,
+ unsigned int parts);
+
+ /// Shift a bignum left COUNT bits. Shifted in bits are zero.
+ /// There are no restrictions on COUNT.
+ static void tcShiftLeft(integerPart *, unsigned int parts,
+ unsigned int count);
+
+ /// Shift a bignum right COUNT bits. Shifted in bits are zero.
+ /// There are no restrictions on COUNT.
+ static void tcShiftRight(integerPart *, unsigned int parts,
+ unsigned int count);
+
+ /// The obvious AND, OR and XOR and complement operations.
+ static void tcAnd(integerPart *, const integerPart *, unsigned int);
+ static void tcOr(integerPart *, const integerPart *, unsigned int);
+ static void tcXor(integerPart *, const integerPart *, unsigned int);
+ static void tcComplement(integerPart *, unsigned int);
+
+ /// Comparison (unsigned) of two bignums.
+ static int tcCompare(const integerPart *, const integerPart *,
+ unsigned int);
+
+ /// Increment a bignum in-place. Return the carry flag.
+ static integerPart tcIncrement(integerPart *, unsigned int);
+
+ /// Set the least significant BITS and clear the rest.
+ static void tcSetLeastSignificantBits(integerPart *, unsigned int,
+ unsigned int bits);
+
+ /// @brief debug method
+ void dump() const;
+
+ /// @}
+};
+
+/// Magic data for optimising signed division by a constant.
+struct APInt::ms {
+ APInt m; ///< magic number
+ unsigned s; ///< shift amount
+};
+
+/// Magic data for optimising unsigned division by a constant.
+struct APInt::mu {
+ APInt m; ///< magic number
+ bool a; ///< add indicator
+ unsigned s; ///< shift amount
+};
+
+inline bool operator==(uint64_t V1, const APInt& V2) {
+ return V2 == V1;
+}
+
+inline bool operator!=(uint64_t V1, const APInt& V2) {
+ return V2 != V1;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
+ I.print(OS, true);
+ return OS;
+}
+
+namespace APIntOps {
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt smin(const APInt &A, const APInt &B) {
+ return A.slt(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be signed.
+inline APInt smax(const APInt &A, const APInt &B) {
+ return A.sgt(B) ? A : B;
+}
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt umin(const APInt &A, const APInt &B) {
+ return A.ult(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be unsigned.
+inline APInt umax(const APInt &A, const APInt &B) {
+ return A.ugt(B) ? A : B;
+}
+
+/// @brief Check if the specified APInt has a N-bits unsigned integer value.
+inline bool isIntN(unsigned N, const APInt& APIVal) {
+ return APIVal.isIntN(N);
+}
+
+/// @brief Check if the specified APInt has a N-bits signed integer value.
+inline bool isSignedIntN(unsigned N, const APInt& APIVal) {
+ return APIVal.isSignedIntN(N);
+}
+
+/// @returns true if the argument APInt value is a sequence of ones
+/// starting at the least significant bit with the remainder zero.
+inline bool isMask(unsigned numBits, const APInt& APIVal) {
+ return numBits <= APIVal.getBitWidth() &&
+ APIVal == APInt::getLowBitsSet(APIVal.getBitWidth(), numBits);
+}
+
+/// @returns true if the argument APInt value contains a sequence of ones
+/// with the remainder zero.
+inline bool isShiftedMask(unsigned numBits, const APInt& APIVal) {
+ return isMask(numBits, (APIVal - APInt(numBits,1)) | APIVal);
+}
+
+/// @returns a byte-swapped representation of the specified APInt Value.
+inline APInt byteSwap(const APInt& APIVal) {
+ return APIVal.byteSwap();
+}
+
+/// @returns the floor log base 2 of the specified APInt value.
+inline unsigned logBase2(const APInt& APIVal) {
+ return APIVal.logBase2();
+}
+
+/// GreatestCommonDivisor - This function returns the greatest common
+/// divisor of the two APInt values using Euclid's algorithm.
+/// @returns the greatest common divisor of Val1 and Val2
+/// @brief Compute GCD of two APInt values.
+APInt GreatestCommonDivisor(const APInt& Val1, const APInt& Val2);
+
+/// Treats the APInt as an unsigned value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundAPIntToDouble(const APInt& APIVal) {
+ return APIVal.roundToDouble();
+}
+
+/// Treats the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundSignedAPIntToDouble(const APInt& APIVal) {
+ return APIVal.signedRoundToDouble();
+}
+
+/// @brief Converts the given APInt to a float vlalue.
+inline float RoundAPIntToFloat(const APInt& APIVal) {
+ return float(RoundAPIntToDouble(APIVal));
+}
+
+/// Treast the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a float value.
+inline float RoundSignedAPIntToFloat(const APInt& APIVal) {
+ return float(APIVal.signedRoundToDouble());
+}
+
+/// RoundDoubleToAPInt - This function convert a double value to an APInt value.
+/// @brief Converts the given double value into a APInt.
+APInt RoundDoubleToAPInt(double Double, unsigned width);
+
+/// RoundFloatToAPInt - Converts a float value into an APInt value.
+/// @brief Converts a float value into a APInt.
+inline APInt RoundFloatToAPInt(float Float, unsigned width) {
+ return RoundDoubleToAPInt(double(Float), width);
+}
+
+/// Arithmetic right-shift the APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+inline APInt ashr(const APInt& LHS, unsigned shiftAmt) {
+ return LHS.ashr(shiftAmt);
+}
+
+/// Logical right-shift the APInt by shiftAmt.
+/// @brief Logical right-shift function.
+inline APInt lshr(const APInt& LHS, unsigned shiftAmt) {
+ return LHS.lshr(shiftAmt);
+}
+
+/// Left-shift the APInt by shiftAmt.
+/// @brief Left-shift function.
+inline APInt shl(const APInt& LHS, unsigned shiftAmt) {
+ return LHS.shl(shiftAmt);
+}
+
+/// Signed divide APInt LHS by APInt RHS.
+/// @brief Signed division function for APInt.
+inline APInt sdiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.sdiv(RHS);
+}
+
+/// Unsigned divide APInt LHS by APInt RHS.
+/// @brief Unsigned division function for APInt.
+inline APInt udiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.udiv(RHS);
+}
+
+/// Signed remainder operation on APInt.
+/// @brief Function for signed remainder operation.
+inline APInt srem(const APInt& LHS, const APInt& RHS) {
+ return LHS.srem(RHS);
+}
+
+/// Unsigned remainder operation on APInt.
+/// @brief Function for unsigned remainder operation.
+inline APInt urem(const APInt& LHS, const APInt& RHS) {
+ return LHS.urem(RHS);
+}
+
+/// Performs multiplication on APInt values.
+/// @brief Function for multiplication operation.
+inline APInt mul(const APInt& LHS, const APInt& RHS) {
+ return LHS * RHS;
+}
+
+/// Performs addition on APInt values.
+/// @brief Function for addition operation.
+inline APInt add(const APInt& LHS, const APInt& RHS) {
+ return LHS + RHS;
+}
+
+/// Performs subtraction on APInt values.
+/// @brief Function for subtraction operation.
+inline APInt sub(const APInt& LHS, const APInt& RHS) {
+ return LHS - RHS;
+}
+
+/// Performs bitwise AND operation on APInt LHS and
+/// APInt RHS.
+/// @brief Bitwise AND function for APInt.
+inline APInt And(const APInt& LHS, const APInt& RHS) {
+ return LHS & RHS;
+}
+
+/// Performs bitwise OR operation on APInt LHS and APInt RHS.
+/// @brief Bitwise OR function for APInt.
+inline APInt Or(const APInt& LHS, const APInt& RHS) {
+ return LHS | RHS;
+}
+
+/// Performs bitwise XOR operation on APInt.
+/// @brief Bitwise XOR function for APInt.
+inline APInt Xor(const APInt& LHS, const APInt& RHS) {
+ return LHS ^ RHS;
+}
+
+/// Performs a bitwise complement operation on APInt.
+/// @brief Bitwise complement function.
+inline APInt Not(const APInt& APIVal) {
+ return ~APIVal;
+}
+
+} // End of APIntOps namespace
+
+} // End of llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/APSInt.h b/contrib/llvm/include/llvm/ADT/APSInt.h
new file mode 100644
index 000000000000..54a7b601d1f1
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/APSInt.h
@@ -0,0 +1,266 @@
+//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the APSInt class, which is a simple class that
+// represents an arbitrary sized integer that knows its signedness.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APSINT_H
+#define LLVM_APSINT_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+class APSInt : public APInt {
+ bool IsUnsigned;
+public:
+ /// Default constructor that creates an uninitialized APInt.
+ explicit APSInt() {}
+
+ /// APSInt ctor - Create an APSInt with the specified width, default to
+ /// unsigned.
+ explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
+ : APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
+
+ explicit APSInt(const APInt &I, bool isUnsigned = true)
+ : APInt(I), IsUnsigned(isUnsigned) {}
+
+ APSInt &operator=(const APSInt &RHS) {
+ APInt::operator=(RHS);
+ IsUnsigned = RHS.IsUnsigned;
+ return *this;
+ }
+
+ APSInt &operator=(const APInt &RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ APSInt &operator=(uint64_t RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ // Query sign information.
+ bool isSigned() const { return !IsUnsigned; }
+ bool isUnsigned() const { return IsUnsigned; }
+ void setIsUnsigned(bool Val) { IsUnsigned = Val; }
+ void setIsSigned(bool Val) { IsUnsigned = !Val; }
+
+ /// toString - Append this APSInt to the specified SmallString.
+ void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
+ APInt::toString(Str, Radix, isSigned());
+ }
+ /// toString - Converts an APInt to a std::string. This is an inefficient
+ /// method, your should prefer passing in a SmallString instead.
+ std::string toString(unsigned Radix) const {
+ return APInt::toString(Radix, isSigned());
+ }
+ using APInt::toString;
+
+ APSInt trunc(uint32_t width) const {
+ return APSInt(APInt::trunc(width), IsUnsigned);
+ }
+
+ APSInt extend(uint32_t width) const {
+ if (IsUnsigned)
+ return APSInt(zext(width), IsUnsigned);
+ else
+ return APSInt(sext(width), IsUnsigned);
+ }
+
+ APSInt extOrTrunc(uint32_t width) const {
+ if (IsUnsigned)
+ return APSInt(zextOrTrunc(width), IsUnsigned);
+ else
+ return APSInt(sextOrTrunc(width), IsUnsigned);
+ }
+
+ const APSInt &operator%=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = urem(RHS);
+ else
+ *this = srem(RHS);
+ return *this;
+ }
+ const APSInt &operator/=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = udiv(RHS);
+ else
+ *this = sdiv(RHS);
+ return *this;
+ }
+ APSInt operator%(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? APSInt(urem(RHS), true) : APSInt(srem(RHS), false);
+ }
+ APSInt operator/(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? APSInt(udiv(RHS), true) : APSInt(sdiv(RHS), false);
+ }
+
+ APSInt operator>>(unsigned Amt) const {
+ return IsUnsigned ? APSInt(lshr(Amt), true) : APSInt(ashr(Amt), false);
+ }
+ APSInt& operator>>=(unsigned Amt) {
+ *this = *this >> Amt;
+ return *this;
+ }
+
+ inline bool operator<(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ult(RHS) : slt(RHS);
+ }
+ inline bool operator>(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ugt(RHS) : sgt(RHS);
+ }
+ inline bool operator<=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ule(RHS) : sle(RHS);
+ }
+ inline bool operator>=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? uge(RHS) : sge(RHS);
+ }
+
+ // The remaining operators just wrap the logic of APInt, but retain the
+ // signedness information.
+
+ APSInt operator<<(unsigned Bits) const {
+ return APSInt(static_cast<const APInt&>(*this) << Bits, IsUnsigned);
+ }
+ APSInt& operator<<=(unsigned Amt) {
+ *this = *this << Amt;
+ return *this;
+ }
+
+ APSInt& operator++() {
+ static_cast<APInt&>(*this)++;
+ return *this;
+ }
+ APSInt& operator--() {
+ static_cast<APInt&>(*this)--;
+ return *this;
+ }
+ APSInt operator++(int) {
+ return APSInt(++static_cast<APInt&>(*this), IsUnsigned);
+ }
+ APSInt operator--(int) {
+ return APSInt(--static_cast<APInt&>(*this), IsUnsigned);
+ }
+ APSInt operator-() const {
+ return APSInt(-static_cast<const APInt&>(*this), IsUnsigned);
+ }
+ APSInt& operator+=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) += RHS;
+ return *this;
+ }
+ APSInt& operator-=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) -= RHS;
+ return *this;
+ }
+ APSInt& operator*=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) *= RHS;
+ return *this;
+ }
+ APSInt& operator&=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) &= RHS;
+ return *this;
+ }
+ APSInt& operator|=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) |= RHS;
+ return *this;
+ }
+ APSInt& operator^=(const APSInt& RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ static_cast<APInt&>(*this) ^= RHS;
+ return *this;
+ }
+
+ APSInt operator&(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned);
+ }
+ APSInt And(const APSInt& RHS) const {
+ return this->operator&(RHS);
+ }
+
+ APSInt operator|(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned);
+ }
+ APSInt Or(const APSInt& RHS) const {
+ return this->operator|(RHS);
+ }
+
+
+ APSInt operator^(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
+ }
+ APSInt Xor(const APSInt& RHS) const {
+ return this->operator^(RHS);
+ }
+
+ APSInt operator*(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) * RHS, IsUnsigned);
+ }
+ APSInt operator+(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) + RHS, IsUnsigned);
+ }
+ APSInt operator-(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return APSInt(static_cast<const APInt&>(*this) - RHS, IsUnsigned);
+ }
+ APSInt operator~() const {
+ return APSInt(~static_cast<const APInt&>(*this), IsUnsigned);
+ }
+
+ /// getMaxValue - Return the APSInt representing the maximum integer value
+ /// with the given bit width and signedness.
+ static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
+ return APSInt(Unsigned ? APInt::getMaxValue(numBits)
+ : APInt::getSignedMaxValue(numBits), Unsigned);
+ }
+
+ /// getMinValue - Return the APSInt representing the minimum integer value
+ /// with the given bit width and signedness.
+ static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
+ return APSInt(Unsigned ? APInt::getMinValue(numBits)
+ : APInt::getSignedMinValue(numBits), Unsigned);
+ }
+
+ /// Profile - Used to insert APSInt objects, or objects that contain APSInt
+ /// objects, into FoldingSets.
+ void Profile(FoldingSetNodeID& ID) const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
+ I.print(OS, I.isSigned());
+ return OS;
+}
+
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ArrayRef.h b/contrib/llvm/include/llvm/ADT/ArrayRef.h
new file mode 100644
index 000000000000..f4c8e5586213
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ArrayRef.h
@@ -0,0 +1,300 @@
+//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ARRAYREF_H
+#define LLVM_ADT_ARRAYREF_H
+
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace llvm {
+
+ /// ArrayRef - Represent a constant reference to an array (0 or more elements
+ /// consecutively in memory), i.e. a start pointer and a length. It allows
+ /// various APIs to take consecutive elements easily and conveniently.
+ ///
+ /// This class does not own the underlying data, it is expected to be used in
+ /// situations where the data resides in some other buffer, whose lifetime
+ /// extends past that of the ArrayRef. For this reason, it is not in general
+ /// safe to store an ArrayRef.
+ ///
+ /// This is intended to be trivially copyable, so it should be passed by
+ /// value.
+ template<typename T>
+ class ArrayRef {
+ public:
+ typedef const T *iterator;
+ typedef const T *const_iterator;
+ typedef size_t size_type;
+
+ private:
+ /// The start of the array, in an external buffer.
+ const T *Data;
+
+ /// The number of elements.
+ size_type Length;
+
+ public:
+ /// @name Constructors
+ /// @{
+
+ /// Construct an empty ArrayRef.
+ /*implicit*/ ArrayRef() : Data(0), Length(0) {}
+
+ /// Construct an ArrayRef from a single element.
+ /*implicit*/ ArrayRef(const T &OneElt)
+ : Data(&OneElt), Length(1) {}
+
+ /// Construct an ArrayRef from a pointer and length.
+ /*implicit*/ ArrayRef(const T *data, size_t length)
+ : Data(data), Length(length) {}
+
+ /// Construct an ArrayRef from a range.
+ ArrayRef(const T *begin, const T *end)
+ : Data(begin), Length(end - begin) {}
+
+ /// Construct an ArrayRef from a SmallVector.
+ /*implicit*/ ArrayRef(const SmallVectorImpl<T> &Vec)
+ : Data(Vec.data()), Length(Vec.size()) {}
+
+ /// Construct an ArrayRef from a std::vector.
+ /*implicit*/ ArrayRef(const std::vector<T> &Vec)
+ : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
+
+ /// Construct an ArrayRef from a C array.
+ template <size_t N>
+ /*implicit*/ ArrayRef(const T (&Arr)[N])
+ : Data(Arr), Length(N) {}
+
+ /// @}
+ /// @name Simple Operations
+ /// @{
+
+ iterator begin() const { return Data; }
+ iterator end() const { return Data + Length; }
+
+ /// empty - Check if the array is empty.
+ bool empty() const { return Length == 0; }
+
+ const T *data() const { return Data; }
+
+ /// size - Get the array size.
+ size_t size() const { return Length; }
+
+ /// front - Get the first element.
+ const T &front() const {
+ assert(!empty());
+ return Data[0];
+ }
+
+ /// back - Get the last element.
+ const T &back() const {
+ assert(!empty());
+ return Data[Length-1];
+ }
+
+ /// equals - Check for element-wise equality.
+ bool equals(ArrayRef RHS) const {
+ if (Length != RHS.Length)
+ return false;
+ for (size_type i = 0; i != Length; i++)
+ if (Data[i] != RHS.Data[i])
+ return false;
+ return true;
+ }
+
+ /// slice(n) - Chop off the first N elements of the array.
+ ArrayRef<T> slice(unsigned N) const {
+ assert(N <= size() && "Invalid specifier");
+ return ArrayRef<T>(data()+N, size()-N);
+ }
+
+ /// slice(n, m) - Chop off the first N elements of the array, and keep M
+ /// elements in the array.
+ ArrayRef<T> slice(unsigned N, unsigned M) const {
+ assert(N+M <= size() && "Invalid specifier");
+ return ArrayRef<T>(data()+N, M);
+ }
+
+ /// @}
+ /// @name Operator Overloads
+ /// @{
+ const T &operator[](size_t Index) const {
+ assert(Index < Length && "Invalid index!");
+ return Data[Index];
+ }
+
+ /// @}
+ /// @name Expensive Operations
+ /// @{
+ std::vector<T> vec() const {
+ return std::vector<T>(Data, Data+Length);
+ }
+
+ /// @}
+ /// @name Conversion operators
+ /// @{
+ operator std::vector<T>() const {
+ return std::vector<T>(Data, Data+Length);
+ }
+
+ /// @}
+ };
+
+ /// MutableArrayRef - Represent a mutable reference to an array (0 or more
+ /// elements consecutively in memory), i.e. a start pointer and a length. It
+ /// allows various APIs to take and modify consecutive elements easily and
+ /// conveniently.
+ ///
+ /// This class does not own the underlying data, it is expected to be used in
+ /// situations where the data resides in some other buffer, whose lifetime
+ /// extends past that of the MutableArrayRef. For this reason, it is not in
+ /// general safe to store a MutableArrayRef.
+ ///
+ /// This is intended to be trivially copyable, so it should be passed by
+ /// value.
+ template<typename T>
+ class MutableArrayRef : public ArrayRef<T> {
+ public:
+ typedef T *iterator;
+
+ /// Construct an empty ArrayRef.
+ /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
+
+ /// Construct an MutableArrayRef from a single element.
+ /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
+
+ /// Construct an MutableArrayRef from a pointer and length.
+ /*implicit*/ MutableArrayRef(T *data, size_t length)
+ : ArrayRef<T>(data, length) {}
+
+ /// Construct an MutableArrayRef from a range.
+ MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
+
+ /// Construct an MutableArrayRef from a SmallVector.
+ /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
+ : ArrayRef<T>(Vec) {}
+
+ /// Construct a MutableArrayRef from a std::vector.
+ /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
+ : ArrayRef<T>(Vec) {}
+
+ /// Construct an MutableArrayRef from a C array.
+ template <size_t N>
+ /*implicit*/ MutableArrayRef(T (&Arr)[N])
+ : ArrayRef<T>(Arr) {}
+
+ T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
+
+ iterator begin() const { return data(); }
+ iterator end() const { return data() + this->size(); }
+
+ /// front - Get the first element.
+ T &front() const {
+ assert(!this->empty());
+ return data()[0];
+ }
+
+ /// back - Get the last element.
+ T &back() const {
+ assert(!this->empty());
+ return data()[this->size()-1];
+ }
+
+ /// slice(n) - Chop off the first N elements of the array.
+ MutableArrayRef<T> slice(unsigned N) const {
+ assert(N <= this->size() && "Invalid specifier");
+ return MutableArrayRef<T>(data()+N, this->size()-N);
+ }
+
+ /// slice(n, m) - Chop off the first N elements of the array, and keep M
+ /// elements in the array.
+ MutableArrayRef<T> slice(unsigned N, unsigned M) const {
+ assert(N+M <= this->size() && "Invalid specifier");
+ return MutableArrayRef<T>(data()+N, M);
+ }
+
+ /// @}
+ /// @name Operator Overloads
+ /// @{
+ T &operator[](size_t Index) const {
+ assert(Index < this->size() && "Invalid index!");
+ return data()[Index];
+ }
+ };
+
+ /// @name ArrayRef Convenience constructors
+ /// @{
+
+ /// Construct an ArrayRef from a single element.
+ template<typename T>
+ ArrayRef<T> makeArrayRef(const T &OneElt) {
+ return OneElt;
+ }
+
+ /// Construct an ArrayRef from a pointer and length.
+ template<typename T>
+ ArrayRef<T> makeArrayRef(const T *data, size_t length) {
+ return ArrayRef<T>(data, length);
+ }
+
+ /// Construct an ArrayRef from a range.
+ template<typename T>
+ ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
+ return ArrayRef<T>(begin, end);
+ }
+
+ /// Construct an ArrayRef from a SmallVector.
+ template <typename T>
+ ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
+ return Vec;
+ }
+
+ /// Construct an ArrayRef from a SmallVector.
+ template <typename T, unsigned N>
+ ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
+ return Vec;
+ }
+
+ /// Construct an ArrayRef from a std::vector.
+ template<typename T>
+ ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
+ return Vec;
+ }
+
+ /// Construct an ArrayRef from a C array.
+ template<typename T, size_t N>
+ ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
+ return ArrayRef<T>(Arr);
+ }
+
+ /// @}
+ /// @name ArrayRef Comparison Operators
+ /// @{
+
+ template<typename T>
+ inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
+ return LHS.equals(RHS);
+ }
+
+ template<typename T>
+ inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
+ return !(LHS == RHS);
+ }
+
+ /// @}
+
+ // ArrayRefs can be treated like a POD type.
+ template <typename T> struct isPodLike;
+ template <typename T> struct isPodLike<ArrayRef<T> > {
+ static const bool value = true;
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/BitVector.h b/contrib/llvm/include/llvm/ADT/BitVector.h
new file mode 100644
index 000000000000..7e0b5ba37196
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/BitVector.h
@@ -0,0 +1,503 @@
+//===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the BitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BITVECTOR_H
+#define LLVM_ADT_BITVECTOR_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <climits>
+#include <cstdlib>
+
+namespace llvm {
+
+class BitVector {
+ typedef unsigned long BitWord;
+
+ enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
+
+ BitWord *Bits; // Actual bits.
+ unsigned Size; // Size of bitvector in bits.
+ unsigned Capacity; // Size of allocated memory in BitWord.
+
+public:
+ // Encapsulation of a single bit.
+ class reference {
+ friend class BitVector;
+
+ BitWord *WordRef;
+ unsigned BitPos;
+
+ reference(); // Undefined
+
+ public:
+ reference(BitVector &b, unsigned Idx) {
+ WordRef = &b.Bits[Idx / BITWORD_SIZE];
+ BitPos = Idx % BITWORD_SIZE;
+ }
+
+ ~reference() {}
+
+ reference &operator=(reference t) {
+ *this = bool(t);
+ return *this;
+ }
+
+ reference& operator=(bool t) {
+ if (t)
+ *WordRef |= 1L << BitPos;
+ else
+ *WordRef &= ~(1L << BitPos);
+ return *this;
+ }
+
+ operator bool() const {
+ return ((*WordRef) & (1L << BitPos)) ? true : false;
+ }
+ };
+
+
+ /// BitVector default ctor - Creates an empty bitvector.
+ BitVector() : Size(0), Capacity(0) {
+ Bits = 0;
+ }
+
+ /// BitVector ctor - Creates a bitvector of specified number of bits. All
+ /// bits are initialized to the specified value.
+ explicit BitVector(unsigned s, bool t = false) : Size(s) {
+ Capacity = NumBitWords(s);
+ Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+ init_words(Bits, Capacity, t);
+ if (t)
+ clear_unused_bits();
+ }
+
+ /// BitVector copy ctor.
+ BitVector(const BitVector &RHS) : Size(RHS.size()) {
+ if (Size == 0) {
+ Bits = 0;
+ Capacity = 0;
+ return;
+ }
+
+ Capacity = NumBitWords(RHS.size());
+ Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+ std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
+ }
+
+ ~BitVector() {
+ std::free(Bits);
+ }
+
+ /// empty - Tests whether there are no bits in this bitvector.
+ bool empty() const { return Size == 0; }
+
+ /// size - Returns the number of bits in this bitvector.
+ unsigned size() const { return Size; }
+
+ /// count - Returns the number of bits which are set.
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32((uint32_t)Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ llvm_unreachable("Unsupported!");
+ return NumBits;
+ }
+
+ /// any - Returns true if any bit is set.
+ bool any() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0)
+ return true;
+ return false;
+ }
+
+ /// all - Returns true if all bits are set.
+ bool all() const {
+ // TODO: Optimize this.
+ return count() == size();
+ }
+
+ /// none - Returns true if none of the bits are set.
+ bool none() const {
+ return !any();
+ }
+
+ /// find_first - Returns the index of the first set bit, -1 if none
+ /// of the bits are set.
+ int find_first() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
+ if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ llvm_unreachable("Unsupported!");
+ }
+ return -1;
+ }
+
+ /// find_next - Returns the index of the next set bit following the
+ /// "Prev" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Prev) const {
+ ++Prev;
+ if (Prev >= Size)
+ return -1;
+
+ unsigned WordPos = Prev / BITWORD_SIZE;
+ unsigned BitPos = Prev % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy);
+ if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ llvm_unreachable("Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
+ if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ llvm_unreachable("Unsupported!");
+ }
+ return -1;
+ }
+
+ /// clear - Clear all bits.
+ void clear() {
+ Size = 0;
+ }
+
+ /// resize - Grow or shrink the bitvector.
+ void resize(unsigned N, bool t = false) {
+ if (N > Capacity * BITWORD_SIZE) {
+ unsigned OldCapacity = Capacity;
+ grow(N);
+ init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+ }
+
+ // Set any old unused bits that are now included in the BitVector. This
+ // may set bits that are not included in the new vector, but we will clear
+ // them back out below.
+ if (N > Size)
+ set_unused_bits(t);
+
+ // Update the size, and clear out any bits that are now unused
+ unsigned OldSize = Size;
+ Size = N;
+ if (t || N < OldSize)
+ clear_unused_bits();
+ }
+
+ void reserve(unsigned N) {
+ if (N > Capacity * BITWORD_SIZE)
+ grow(N);
+ }
+
+ // Set, reset, flip
+ BitVector &set() {
+ init_words(Bits, Capacity, true);
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ BitVector &reset() {
+ init_words(Bits, Capacity, false);
+ return *this;
+ }
+
+ BitVector &reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ return *this;
+ }
+
+ BitVector &flip() {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] = ~Bits[i];
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &flip(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ // No argument flip.
+ BitVector operator~() const {
+ return BitVector(*this).flip();
+ }
+
+ // Indexing.
+ reference operator[](unsigned Idx) {
+ assert (Idx < Size && "Out-of-bounds Bit access.");
+ return reference(*this, Idx);
+ }
+
+ bool operator[](unsigned Idx) const {
+ assert (Idx < Size && "Out-of-bounds Bit access.");
+ BitWord Mask = 1L << (Idx % BITWORD_SIZE);
+ return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
+ }
+
+ bool test(unsigned Idx) const {
+ return (*this)[Idx];
+ }
+
+ // Comparison operators.
+ bool operator==(const BitVector &RHS) const {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+
+ // Verify that any extra words are all zeros.
+ if (i != ThisWords) {
+ for (; i != ThisWords; ++i)
+ if (Bits[i])
+ return false;
+ } else if (i != RHSWords) {
+ for (; i != RHSWords; ++i)
+ if (RHS.Bits[i])
+ return false;
+ }
+ return true;
+ }
+
+ bool operator!=(const BitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Intersection, union, disjoint union.
+ BitVector &operator&=(const BitVector &RHS) {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ Bits[i] &= RHS.Bits[i];
+
+ // Any bits that are just in this bitvector become zero, because they aren't
+ // in the RHS bit vector. Any words only in RHS are ignored because they
+ // are already zero in the LHS.
+ for (; i != ThisWords; ++i)
+ Bits[i] = 0;
+
+ return *this;
+ }
+
+ // reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
+ BitVector &reset(const BitVector &RHS) {
+ unsigned ThisWords = NumBitWords(size());
+ unsigned RHSWords = NumBitWords(RHS.size());
+ unsigned i;
+ for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
+ Bits[i] &= ~RHS.Bits[i];
+ return *this;
+ }
+
+ BitVector &operator|=(const BitVector &RHS) {
+ if (size() < RHS.size())
+ resize(RHS.size());
+ for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
+ Bits[i] |= RHS.Bits[i];
+ return *this;
+ }
+
+ BitVector &operator^=(const BitVector &RHS) {
+ if (size() < RHS.size())
+ resize(RHS.size());
+ for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
+ Bits[i] ^= RHS.Bits[i];
+ return *this;
+ }
+
+ // Assignment operator.
+ const BitVector &operator=(const BitVector &RHS) {
+ if (this == &RHS) return *this;
+
+ Size = RHS.size();
+ unsigned RHSWords = NumBitWords(Size);
+ if (Size <= Capacity * BITWORD_SIZE) {
+ if (Size)
+ std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
+ clear_unused_bits();
+ return *this;
+ }
+
+ // Grow the bitvector to have enough elements.
+ Capacity = RHSWords;
+ BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
+ std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
+
+ // Destroy the old bits.
+ std::free(Bits);
+ Bits = NewBits;
+
+ return *this;
+ }
+
+ void swap(BitVector &RHS) {
+ std::swap(Bits, RHS.Bits);
+ std::swap(Size, RHS.Size);
+ std::swap(Capacity, RHS.Capacity);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Portable bit mask operations.
+ //===--------------------------------------------------------------------===//
+ //
+ // These methods all operate on arrays of uint32_t, each holding 32 bits. The
+ // fixed word size makes it easier to work with literal bit vector constants
+ // in portable code.
+ //
+ // The LSB in each word is the lowest numbered bit. The size of a portable
+ // bit mask is always a whole multiple of 32 bits. If no bit mask size is
+ // given, the bit mask is assumed to cover the entire BitVector.
+
+ /// setBitsInMask - Add '1' bits from Mask to this vector. Don't resize.
+ /// This computes "*this |= Mask".
+ void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ applyMask<true, false>(Mask, MaskWords);
+ }
+
+ /// clearBitsInMask - Clear any bits in this vector that are set in Mask.
+ /// Don't resize. This computes "*this &= ~Mask".
+ void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ applyMask<false, false>(Mask, MaskWords);
+ }
+
+ /// setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
+ /// Don't resize. This computes "*this |= ~Mask".
+ void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ applyMask<true, true>(Mask, MaskWords);
+ }
+
+ /// clearBitsNotInMask - Clear a bit in this vector for every '0' bit in Mask.
+ /// Don't resize. This computes "*this &= Mask".
+ void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
+ applyMask<false, true>(Mask, MaskWords);
+ }
+
+private:
+ unsigned NumBitWords(unsigned S) const {
+ return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
+ }
+
+ // Set the unused bits in the high words.
+ void set_unused_bits(bool t = true) {
+ // Set high words first.
+ unsigned UsedWords = NumBitWords(Size);
+ if (Capacity > UsedWords)
+ init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
+
+ // Then set any stray high bits of the last used word.
+ unsigned ExtraBits = Size % BITWORD_SIZE;
+ if (ExtraBits) {
+ Bits[UsedWords-1] &= ~(~0L << ExtraBits);
+ Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
+ }
+ }
+
+ // Clear the unused bits in the high words.
+ void clear_unused_bits() {
+ set_unused_bits(false);
+ }
+
+ void grow(unsigned NewSize) {
+ Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
+ Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
+
+ clear_unused_bits();
+ }
+
+ void init_words(BitWord *B, unsigned NumWords, bool t) {
+ memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+ }
+
+ template<bool AddBits, bool InvertMask>
+ void applyMask(const uint32_t *Mask, unsigned MaskWords) {
+ assert(BITWORD_SIZE % 32 == 0 && "Unsupported BitWord size.");
+ MaskWords = std::min(MaskWords, (size() + 31) / 32);
+ const unsigned Scale = BITWORD_SIZE / 32;
+ unsigned i;
+ for (i = 0; MaskWords >= Scale; ++i, MaskWords -= Scale) {
+ BitWord BW = Bits[i];
+ // This inner loop should unroll completely when BITWORD_SIZE > 32.
+ for (unsigned b = 0; b != BITWORD_SIZE; b += 32) {
+ uint32_t M = *Mask++;
+ if (InvertMask) M = ~M;
+ if (AddBits) BW |= BitWord(M) << b;
+ else BW &= ~(BitWord(M) << b);
+ }
+ Bits[i] = BW;
+ }
+ for (unsigned b = 0; MaskWords; b += 32, --MaskWords) {
+ uint32_t M = *Mask++;
+ if (InvertMask) M = ~M;
+ if (AddBits) Bits[i] |= BitWord(M) << b;
+ else Bits[i] &= ~(BitWord(M) << b);
+ }
+ if (AddBits)
+ clear_unused_bits();
+ }
+};
+
+inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result ^= RHS;
+ return Result;
+}
+
+} // End llvm namespace
+
+namespace std {
+ /// Implement std::swap in terms of BitVector swap.
+ inline void
+ swap(llvm::BitVector &LHS, llvm::BitVector &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h b/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
new file mode 100644
index 000000000000..e502ac4348d0
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
@@ -0,0 +1,76 @@
+//===--- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DAGDELTAALGORITHM_H
+#define LLVM_ADT_DAGDELTAALGORITHM_H
+
+#include <vector>
+#include <set>
+
+namespace llvm {
+
+/// DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimizing
+/// directed acyclic graphs using a predicate function.
+///
+/// The result of the algorithm is a subset of the input change set which is
+/// guaranteed to satisfy the predicate, assuming that the input set did. For
+/// well formed predicates, the result set is guaranteed to be such that
+/// removing any single element not required by the dependencies on the other
+/// elements would falsify the predicate.
+///
+/// The DAG should be used to represent dependencies in the changes which are
+/// likely to hold across the predicate function. That is, for a particular
+/// changeset S and predicate P:
+///
+/// P(S) => P(S union pred(S))
+///
+/// The minization algorithm uses this dependency information to attempt to
+/// eagerly prune large subsets of changes. As with \see DeltaAlgorithm, the DAG
+/// is not required to satisfy this property, but the algorithm will run
+/// substantially fewer tests with appropriate dependencies. \see DeltaAlgorithm
+/// for more information on the properties which the predicate function itself
+/// should satisfy.
+class DAGDeltaAlgorithm {
+ virtual void anchor();
+public:
+ typedef unsigned change_ty;
+ typedef std::pair<change_ty, change_ty> edge_ty;
+
+ // FIXME: Use a decent data structure.
+ typedef std::set<change_ty> changeset_ty;
+ typedef std::vector<changeset_ty> changesetlist_ty;
+
+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
+ /// changes and returning the smallest set which still satisfies the test
+ /// predicate and the input \arg 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.
+ changeset_ty Run(const changeset_ty &Changes,
+ const std::vector<edge_ty> &Dependencies);
+
+ /// UpdatedSearchState - Callback used when the search state changes.
+ virtual void UpdatedSearchState(const changeset_ty &Changes,
+ const changesetlist_ty &Sets,
+ const changeset_ty &Required) {}
+
+ /// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
+ virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h b/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h
new file mode 100644
index 000000000000..45ba19891d4f
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/DeltaAlgorithm.h
@@ -0,0 +1,91 @@
+//===--- DeltaAlgorithm.h - A Set Minimization Algorithm -------*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DELTAALGORITHM_H
+#define LLVM_ADT_DELTAALGORITHM_H
+
+#include <vector>
+#include <set>
+
+namespace llvm {
+
+/// DeltaAlgorithm - Implements the delta debugging algorithm (A. Zeller '99)
+/// for minimizing arbitrary sets using a predicate function.
+///
+/// The result of the algorithm is a subset of the input change set which is
+/// guaranteed to satisfy the predicate, assuming that the input set did. For
+/// well formed predicates, the result set is guaranteed to be such that
+/// removing any single element would falsify the predicate.
+///
+/// For best results the predicate function *should* (but need not) satisfy
+/// certain properties, in particular:
+/// (1) The predicate should return false on an empty set and true on the full
+/// set.
+/// (2) If the predicate returns true for a set of changes, it should return
+/// true for all supersets of that set.
+///
+/// It is not an error to provide a predicate that does not satisfy these
+/// requirements, and the algorithm will generally produce reasonable
+/// results. However, it may run substantially more tests than with a good
+/// predicate.
+class DeltaAlgorithm {
+public:
+ typedef unsigned change_ty;
+ // FIXME: Use a decent data structure.
+ typedef std::set<change_ty> changeset_ty;
+ typedef std::vector<changeset_ty> changesetlist_ty;
+
+private:
+ /// Cache of failed test results. Successful test results are never cached
+ /// since we always reduce following a success.
+ std::set<changeset_ty> FailedTestsCache;
+
+ /// GetTestResult - Get the test result for the \arg 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.
+ void Split(const changeset_ty &S, changesetlist_ty &Res);
+
+ /// Delta - Minimize a set of \arg 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.
+ ///
+ /// \param Res - On success, a subset of Changes which satisfies the
+ /// predicate.
+ /// \return - True on success.
+ bool Search(const changeset_ty &Changes, const changesetlist_ty &Sets,
+ changeset_ty &Res);
+
+protected:
+ /// UpdatedSearchState - Callback used when the search state changes.
+ virtual void UpdatedSearchState(const changeset_ty &Changes,
+ const changesetlist_ty &Sets) {}
+
+ /// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
+ virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
+
+public:
+ virtual ~DeltaAlgorithm();
+
+ /// Run - Minimize the set \arg 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);
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/DenseMap.h b/contrib/llvm/include/llvm/ADT/DenseMap.h
new file mode 100644
index 000000000000..8d4a19d0919c
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/DenseMap.h
@@ -0,0 +1,576 @@
+//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- 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 DenseMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAP_H
+#define LLVM_ADT_DENSEMAP_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 <cstddef>
+#include <cstring>
+
+namespace llvm {
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT>,
+ bool IsConst = false>
+class DenseMapIterator;
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapInfo<KeyT> >
+class DenseMap {
+ typedef std::pair<KeyT, ValueT> BucketT;
+ unsigned NumBuckets;
+ BucketT *Buckets;
+
+ unsigned NumEntries;
+ unsigned NumTombstones;
+public:
+ typedef KeyT key_type;
+ typedef ValueT mapped_type;
+ typedef BucketT value_type;
+
+ DenseMap(const DenseMap &other) {
+ NumBuckets = 0;
+ CopyFrom(other);
+ }
+
+ explicit DenseMap(unsigned NumInitBuckets = 0) {
+ init(NumInitBuckets);
+ }
+
+ template<typename InputIt>
+ DenseMap(const InputIt &I, const InputIt &E) {
+ init(NextPowerOf2(std::distance(I, E)));
+ insert(I, E);
+ }
+
+ ~DenseMap() {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+#ifndef NDEBUG
+ if (NumBuckets)
+ memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
+#endif
+ operator delete(Buckets);
+ }
+
+ typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
+ typedef DenseMapIterator<KeyT, ValueT,
+ KeyInfoT, true> const_iterator;
+ inline iterator begin() {
+ // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
+ return empty() ? end() : iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline iterator end() {
+ return iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
+ }
+ inline const_iterator begin() const {
+ return empty() ? end() : const_iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline const_iterator end() const {
+ return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets, true);
+ }
+
+ bool empty() const { return NumEntries == 0; }
+ unsigned size() const { return NumEntries; }
+
+ /// Grow the densemap so that it has at least Size buckets. Does not shrink
+ void resize(size_t Size) {
+ if (Size > NumBuckets)
+ grow(Size);
+ }
+
+ void clear() {
+ if (NumEntries == 0 && NumTombstones == 0) return;
+
+ // If the capacity of the array is huge, and the # elements used is small,
+ // shrink the array.
+ if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
+ shrink_and_clear();
+ return;
+ }
+
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey)) {
+ if (!KeyInfoT::isEqual(P->first, TombstoneKey)) {
+ P->second.~ValueT();
+ --NumEntries;
+ }
+ P->first = EmptyKey;
+ }
+ }
+ assert(NumEntries == 0 && "Node count imbalance!");
+ NumTombstones = 0;
+ }
+
+ /// count - Return true if the specified key is in the map.
+ bool count(const KeyT &Val) const {
+ BucketT *TheBucket;
+ return LookupBucketFor(Val, TheBucket);
+ }
+
+ iterator find(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return iterator(TheBucket, Buckets+NumBuckets, true);
+ return end();
+ }
+ const_iterator find(const KeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return const_iterator(TheBucket, Buckets+NumBuckets, true);
+ return end();
+ }
+
+ /// Alternate version of find() which allows a different, and possibly
+ /// less expensive, key type.
+ /// The DenseMapInfo is responsible for supplying methods
+ /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
+ /// type used.
+ template<class LookupKeyT>
+ iterator find_as(const LookupKeyT &Val) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return iterator(TheBucket, Buckets+NumBuckets, true);
+ return end();
+ }
+ template<class LookupKeyT>
+ const_iterator find_as(const LookupKeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return const_iterator(TheBucket, Buckets+NumBuckets, true);
+ return end();
+ }
+
+ /// lookup - Return the entry for the specified key, or a default
+ /// constructed value if no such entry exists.
+ ValueT lookup(const KeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return TheBucket->second;
+ return ValueT();
+ }
+
+ // Inserts key,value pair into the map if the key isn't already in the map.
+ // If the key is already in the map, it returns false and doesn't update the
+ // value.
+ std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(KV.first, TheBucket))
+ return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true),
+ false); // Already in map.
+
+ // Otherwise, insert the new element.
+ TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
+ return std::make_pair(iterator(TheBucket, Buckets+NumBuckets, true), true);
+ }
+
+ /// insert - Range insertion of pairs.
+ template<typename InputIt>
+ void insert(InputIt I, InputIt E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+
+ bool erase(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (!LookupBucketFor(Val, TheBucket))
+ return false; // not in map.
+
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+ void erase(iterator I) {
+ BucketT *TheBucket = &*I;
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ }
+
+ void swap(DenseMap& RHS) {
+ std::swap(NumBuckets, RHS.NumBuckets);
+ std::swap(Buckets, RHS.Buckets);
+ std::swap(NumEntries, RHS.NumEntries);
+ std::swap(NumTombstones, RHS.NumTombstones);
+ }
+
+ value_type& FindAndConstruct(const KeyT &Key) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Key, TheBucket))
+ return *TheBucket;
+
+ return *InsertIntoBucket(Key, ValueT(), TheBucket);
+ }
+
+ ValueT &operator[](const KeyT &Key) {
+ return FindAndConstruct(Key).second;
+ }
+
+ DenseMap& operator=(const DenseMap& other) {
+ CopyFrom(other);
+ return *this;
+ }
+
+ /// isPointerIntoBucketsArray - Return true if the specified pointer points
+ /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
+ /// value in the DenseMap).
+ bool isPointerIntoBucketsArray(const void *Ptr) const {
+ return Ptr >= Buckets && Ptr < Buckets+NumBuckets;
+ }
+
+ /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
+ /// array. In conjunction with the previous method, this can be used to
+ /// determine whether an insertion caused the DenseMap to reallocate.
+ const void *getPointerIntoBucketsArray() const { return Buckets; }
+
+private:
+ void CopyFrom(const DenseMap& other) {
+ if (NumBuckets != 0 &&
+ (!isPodLike<KeyT>::value || !isPodLike<ValueT>::value)) {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (!KeyInfoT::isEqual(P->first, EmptyKey) &&
+ !KeyInfoT::isEqual(P->first, TombstoneKey))
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+ }
+
+ NumEntries = other.NumEntries;
+ NumTombstones = other.NumTombstones;
+
+ if (NumBuckets) {
+#ifndef NDEBUG
+ memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
+#endif
+ operator delete(Buckets);
+ }
+
+ NumBuckets = other.NumBuckets;
+
+ if (NumBuckets == 0) {
+ Buckets = 0;
+ return;
+ }
+
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
+
+ if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
+ memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT));
+ else
+ for (size_t i = 0; i < NumBuckets; ++i) {
+ new (&Buckets[i].first) KeyT(other.Buckets[i].first);
+ if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) &&
+ !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey()))
+ new (&Buckets[i].second) ValueT(other.Buckets[i].second);
+ }
+ }
+
+ BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
+ BucketT *TheBucket) {
+ // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow the table.
+ //
+ // The later case is tricky. For example, if we had one empty bucket with
+ // tons of tombstones, failing lookups (e.g. for insertion) would have to
+ // probe almost the entire table until it found the empty bucket. If the
+ // table completely filled with tombstones, no lookup would ever succeed,
+ // causing infinite loops in lookup.
+ ++NumEntries;
+ if (NumEntries*4 >= NumBuckets*3) {
+ this->grow(NumBuckets * 2);
+ LookupBucketFor(Key, TheBucket);
+ }
+ if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+ this->grow(NumBuckets);
+ LookupBucketFor(Key, TheBucket);
+ }
+
+ // If we are writing over a tombstone, remember this.
+ if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey()))
+ --NumTombstones;
+
+ TheBucket->first = Key;
+ new (&TheBucket->second) ValueT(Value);
+ return TheBucket;
+ }
+
+ static unsigned getHashValue(const KeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ template<typename LookupKeyT>
+ static unsigned getHashValue(const LookupKeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ static const KeyT getEmptyKey() {
+ return KeyInfoT::getEmptyKey();
+ }
+ static const KeyT getTombstoneKey() {
+ return KeyInfoT::getTombstoneKey();
+ }
+
+ /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
+ /// FoundBucket. If the bucket contains the key and a value, this returns
+ /// true, otherwise it returns a bucket with an empty marker or tombstone and
+ /// returns false.
+ template<typename LookupKeyT>
+ bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) const {
+ unsigned BucketNo = getHashValue(Val);
+ unsigned ProbeAmt = 1;
+ BucketT *BucketsPtr = Buckets;
+
+ if (NumBuckets == 0) {
+ FoundBucket = 0;
+ return false;
+ }
+
+ // FoundTombstone - Keep track of whether we find a tombstone while probing.
+ BucketT *FoundTombstone = 0;
+ const KeyT EmptyKey = getEmptyKey();
+ const KeyT TombstoneKey = getTombstoneKey();
+ assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
+ !KeyInfoT::isEqual(Val, TombstoneKey) &&
+ "Empty/Tombstone value shouldn't be inserted into map!");
+
+ while (1) {
+ BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
+ // Found Val's bucket? If so, return it.
+ if (KeyInfoT::isEqual(Val, ThisBucket->first)) {
+ FoundBucket = ThisBucket;
+ return true;
+ }
+
+ // If we found an empty bucket, the key doesn't exist in the set.
+ // Insert it and return the default value.
+ if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
+ // If we've already seen a tombstone while probing, fill it in instead
+ // of the empty bucket we eventually probed to.
+ if (FoundTombstone) ThisBucket = FoundTombstone;
+ FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
+ return false;
+ }
+
+ // If this is a tombstone, remember it. If Val ends up not in the map, we
+ // prefer to return it than something that would require more probing.
+ if (KeyInfoT::isEqual(ThisBucket->first, TombstoneKey) && !FoundTombstone)
+ FoundTombstone = ThisBucket; // Remember the first tombstone found.
+
+ // Otherwise, it's a hash collision or a tombstone, continue quadratic
+ // probing.
+ BucketNo += ProbeAmt++;
+ }
+ }
+
+ void init(unsigned InitBuckets) {
+ NumEntries = 0;
+ NumTombstones = 0;
+ NumBuckets = InitBuckets;
+
+ if (InitBuckets == 0) {
+ Buckets = 0;
+ return;
+ }
+
+ assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
+ "# initial buckets must be a power of two!");
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0; i != InitBuckets; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+ }
+
+ void grow(unsigned AtLeast) {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ if (NumBuckets < 64)
+ NumBuckets = 64;
+
+ // Double the number of buckets.
+ while (NumBuckets < AtLeast)
+ NumBuckets <<= 1;
+ NumTombstones = 0;
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Insert all the old elements.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Insert the key/value into the new table.
+ BucketT *DestBucket;
+ bool FoundVal = LookupBucketFor(B->first, DestBucket);
+ (void)FoundVal; // silence warning.
+ assert(!FoundVal && "Key already in new map?");
+ DestBucket->first = B->first;
+ new (&DestBucket->second) ValueT(B->second);
+
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+#ifndef NDEBUG
+ if (OldNumBuckets)
+ memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+#endif
+ // Free the old table.
+ operator delete(OldBuckets);
+ }
+
+ void shrink_and_clear() {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ // Reduce the number of buckets.
+ NumBuckets = NumEntries > 32 ? 1 << (Log2_32_Ceil(NumEntries) + 1)
+ : 64;
+ NumTombstones = 0;
+ Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Free the old buckets.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (!KeyInfoT::isEqual(B->first, EmptyKey) &&
+ !KeyInfoT::isEqual(B->first, TombstoneKey)) {
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+#ifndef NDEBUG
+ memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+#endif
+ // Free the old table.
+ operator delete(OldBuckets);
+
+ NumEntries = 0;
+ }
+
+public:
+ /// Return the approximate size (in bytes) of the actual map.
+ /// This is just the raw memory used by DenseMap.
+ /// If entries are pointers to objects, the size of the referenced objects
+ /// are not included.
+ size_t getMemorySize() const {
+ return NumBuckets * sizeof(BucketT);
+ }
+};
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT, bool IsConst>
+class DenseMapIterator {
+ typedef std::pair<KeyT, ValueT> Bucket;
+ typedef DenseMapIterator<KeyT, ValueT,
+ KeyInfoT, true> ConstIterator;
+ friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
+public:
+ typedef ptrdiff_t difference_type;
+ typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef std::forward_iterator_tag iterator_category;
+private:
+ pointer Ptr, End;
+public:
+ DenseMapIterator() : Ptr(0), End(0) {}
+
+ DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
+ : Ptr(Pos), End(E) {
+ if (!NoAdvance) AdvancePastEmptyBuckets();
+ }
+
+ // If IsConst is true this is a converting constructor from iterator to
+ // const_iterator and the default copy constructor is used.
+ // Otherwise this is a copy constructor for iterator.
+ DenseMapIterator(const DenseMapIterator<KeyT, ValueT,
+ KeyInfoT, false>& I)
+ : Ptr(I.Ptr), End(I.End) {}
+
+ reference operator*() const {
+ return *Ptr;
+ }
+ pointer operator->() const {
+ return Ptr;
+ }
+
+ bool operator==(const ConstIterator &RHS) const {
+ return Ptr == RHS.operator->();
+ }
+ bool operator!=(const ConstIterator &RHS) const {
+ return Ptr != RHS.operator->();
+ }
+
+ inline DenseMapIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ DenseMapIterator operator++(int) { // Postincrement
+ DenseMapIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ const KeyT Empty = KeyInfoT::getEmptyKey();
+ const KeyT Tombstone = KeyInfoT::getTombstoneKey();
+
+ while (Ptr != End &&
+ (KeyInfoT::isEqual(Ptr->first, Empty) ||
+ KeyInfoT::isEqual(Ptr->first, Tombstone)))
+ ++Ptr;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT>
+static inline size_t
+capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
+ return X.getMemorySize();
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/DenseMapInfo.h b/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
new file mode 100644
index 000000000000..1559a35c39f9
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -0,0 +1,168 @@
+//===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- 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 DenseMapInfo traits for DenseMap.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAPINFO_H
+#define LLVM_ADT_DENSEMAPINFO_H
+
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo {
+ //static inline T getEmptyKey();
+ //static inline T getTombstoneKey();
+ //static unsigned getHashValue(const T &Val);
+ //static bool isEqual(const T &LHS, const T &RHS);
+};
+
+// Provide DenseMapInfo for all pointers.
+template<typename T>
+struct DenseMapInfo<T*> {
+ static inline T* getEmptyKey() {
+ intptr_t Val = -1;
+ Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+ return reinterpret_cast<T*>(Val);
+ }
+ static inline T* getTombstoneKey() {
+ intptr_t Val = -2;
+ Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+ return reinterpret_cast<T*>(Val);
+ }
+ static unsigned getHashValue(const T *PtrVal) {
+ return (unsigned((uintptr_t)PtrVal) >> 4) ^
+ (unsigned((uintptr_t)PtrVal) >> 9);
+ }
+ static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
+};
+
+// Provide DenseMapInfo for chars.
+template<> struct DenseMapInfo<char> {
+ static inline char getEmptyKey() { return ~0; }
+ static inline char getTombstoneKey() { return ~0 - 1; }
+ static unsigned getHashValue(const char& Val) { return Val * 37U; }
+ static bool isEqual(const char &LHS, const char &RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for unsigned ints.
+template<> struct DenseMapInfo<unsigned> {
+ static inline unsigned getEmptyKey() { return ~0U; }
+ static inline unsigned getTombstoneKey() { return ~0U - 1; }
+ static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
+ static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for unsigned longs.
+template<> struct DenseMapInfo<unsigned long> {
+ static inline unsigned long getEmptyKey() { return ~0UL; }
+ static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
+ static unsigned getHashValue(const unsigned long& Val) {
+ return (unsigned)(Val * 37UL);
+ }
+ static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for unsigned long longs.
+template<> struct DenseMapInfo<unsigned long long> {
+ static inline unsigned long long getEmptyKey() { return ~0ULL; }
+ static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
+ static unsigned getHashValue(const unsigned long long& Val) {
+ return (unsigned)(Val * 37ULL);
+ }
+ static bool isEqual(const unsigned long long& LHS,
+ const unsigned long long& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for ints.
+template<> struct DenseMapInfo<int> {
+ static inline int getEmptyKey() { return 0x7fffffff; }
+ static inline int getTombstoneKey() { return -0x7fffffff - 1; }
+ static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
+ static bool isEqual(const int& LHS, const int& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for longs.
+template<> struct DenseMapInfo<long> {
+ static inline long getEmptyKey() {
+ return (1UL << (sizeof(long) * 8 - 1)) - 1L;
+ }
+ static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
+ static unsigned getHashValue(const long& Val) {
+ return (unsigned)(Val * 37UL);
+ }
+ static bool isEqual(const long& LHS, const long& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for long longs.
+template<> struct DenseMapInfo<long long> {
+ static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
+ static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
+ static unsigned getHashValue(const long long& Val) {
+ return (unsigned)(Val * 37ULL);
+ }
+ static bool isEqual(const long long& LHS,
+ const long long& RHS) {
+ return LHS == RHS;
+ }
+};
+
+// Provide DenseMapInfo for all pairs whose members have info.
+template<typename T, typename U>
+struct DenseMapInfo<std::pair<T, U> > {
+ typedef std::pair<T, U> Pair;
+ typedef DenseMapInfo<T> FirstInfo;
+ typedef DenseMapInfo<U> SecondInfo;
+
+ static inline Pair getEmptyKey() {
+ return std::make_pair(FirstInfo::getEmptyKey(),
+ SecondInfo::getEmptyKey());
+ }
+ static inline Pair getTombstoneKey() {
+ return std::make_pair(FirstInfo::getTombstoneKey(),
+ SecondInfo::getTombstoneKey());
+ }
+ static unsigned getHashValue(const Pair& PairVal) {
+ uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
+ | (uint64_t)SecondInfo::getHashValue(PairVal.second);
+ key += ~(key << 32);
+ key ^= (key >> 22);
+ key += ~(key << 13);
+ key ^= (key >> 8);
+ key += (key << 3);
+ key ^= (key >> 15);
+ key += ~(key << 27);
+ key ^= (key >> 31);
+ return (unsigned)key;
+ }
+ static bool isEqual(const Pair &LHS, const Pair &RHS) {
+ return FirstInfo::isEqual(LHS.first, RHS.first) &&
+ SecondInfo::isEqual(LHS.second, RHS.second);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/DenseSet.h b/contrib/llvm/include/llvm/ADT/DenseSet.h
new file mode 100644
index 000000000000..8ab9a33200c3
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/DenseSet.h
@@ -0,0 +1,129 @@
+//===- llvm/ADT/DenseSet.h - Dense probed hash table ------------*- 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 DenseSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSESET_H
+#define LLVM_ADT_DENSESET_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+/// DenseSet - This implements a dense probed hash-table based set.
+///
+/// FIXME: This is currently implemented directly in terms of DenseMap, this
+/// should be optimized later if there is a need.
+template<typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT> >
+class DenseSet {
+ typedef DenseMap<ValueT, char, ValueInfoT> MapTy;
+ MapTy TheMap;
+public:
+ DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
+ explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
+
+ bool empty() const { return TheMap.empty(); }
+ unsigned size() const { return TheMap.size(); }
+
+ /// Grow the denseset so that it has at least Size buckets. Does not shrink
+ void resize(size_t Size) { TheMap.resize(Size); }
+
+ void clear() {
+ TheMap.clear();
+ }
+
+ bool count(const ValueT &V) const {
+ return TheMap.count(V);
+ }
+
+ bool erase(const ValueT &V) {
+ return TheMap.erase(V);
+ }
+
+ void swap(DenseSet& RHS) {
+ TheMap.swap(RHS.TheMap);
+ }
+
+ DenseSet &operator=(const DenseSet &RHS) {
+ TheMap = RHS.TheMap;
+ return *this;
+ }
+
+ // Iterators.
+
+ class Iterator {
+ typename MapTy::iterator I;
+ friend class DenseSet;
+ public:
+ typedef typename MapTy::iterator::difference_type difference_type;
+ typedef ValueT value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef std::forward_iterator_tag iterator_category;
+
+ Iterator(const typename MapTy::iterator &i) : I(i) {}
+
+ ValueT& operator*() { return I->first; }
+ ValueT* operator->() { return &I->first; }
+
+ Iterator& operator++() { ++I; return *this; }
+ bool operator==(const Iterator& X) const { return I == X.I; }
+ bool operator!=(const Iterator& X) const { return I != X.I; }
+ };
+
+ class ConstIterator {
+ typename MapTy::const_iterator I;
+ friend class DenseSet;
+ public:
+ typedef typename MapTy::const_iterator::difference_type difference_type;
+ typedef ValueT value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef std::forward_iterator_tag iterator_category;
+
+ ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
+
+ const ValueT& operator*() { return I->first; }
+ const ValueT* operator->() { return &I->first; }
+
+ ConstIterator& operator++() { ++I; return *this; }
+ bool operator==(const ConstIterator& X) const { return I == X.I; }
+ bool operator!=(const ConstIterator& X) const { return I != X.I; }
+ };
+
+ typedef Iterator iterator;
+ typedef ConstIterator const_iterator;
+
+ iterator begin() { return Iterator(TheMap.begin()); }
+ iterator end() { return Iterator(TheMap.end()); }
+
+ const_iterator begin() const { return ConstIterator(TheMap.begin()); }
+ const_iterator end() const { return ConstIterator(TheMap.end()); }
+
+ iterator find(const ValueT &V) { return Iterator(TheMap.find(V)); }
+ void erase(Iterator I) { return TheMap.erase(I.I); }
+ void erase(ConstIterator CI) { return TheMap.erase(CI.I); }
+
+ std::pair<iterator, bool> insert(const ValueT &V) {
+ return TheMap.insert(std::make_pair(V, 0));
+ }
+
+ // Range insertion of values.
+ template<typename InputIt>
+ void insert(InputIt I, InputIt E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h b/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h
new file mode 100644
index 000000000000..dd13a2c02053
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/DepthFirstIterator.h
@@ -0,0 +1,268 @@
+//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build generic depth
+// first graph iterator. This file exposes the following functions/types:
+//
+// df_begin/df_end/df_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+//
+// idf_begin/idf_end/idf_iterator
+// * Depth-first iteration on the 'inverse' graph.
+//
+// df_ext_begin/df_ext_end/df_ext_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+// idf_ext_begin/idf_ext_end/idf_ext_iterator
+// * Depth-first iteration on the 'inverse' graph.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
+#define LLVM_ADT_DEPTHFIRSTITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+// df_iterator_storage - A private class which is used to figure out where to
+// store the visited set.
+template<class SetType, bool External> // Non-external set
+class df_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class df_iterator_storage<SetType, true> {
+public:
+ df_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+
+// Generic Depth First Iterator
+template<class GraphT,
+class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+ bool ExtStorage = false, class GT = GraphTraits<GraphT> >
+class df_iterator : public std::iterator<std::forward_iterator_tag,
+ typename GT::NodeType, ptrdiff_t>,
+ public df_iterator_storage<SetType, ExtStorage> {
+ typedef std::iterator<std::forward_iterator_tag,
+ typename GT::NodeType, ptrdiff_t> super;
+
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+ typedef PointerIntPair<NodeType*, 1> PointerIntTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is node pointer, second is the 'next child' to visit
+ // if the int in PointerIntTy is 0, the 'next child' to visit is invalid
+ std::vector<std::pair<PointerIntTy, ChildItTy> > VisitStack;
+private:
+ inline df_iterator(NodeType *Node) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(PointerIntTy(Node, 0),
+ GT::child_begin(Node)));
+ }
+ inline df_iterator() {
+ // End is when stack is empty
+ }
+ inline df_iterator(NodeType *Node, SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ if (!S.count(Node)) {
+ VisitStack.push_back(std::make_pair(PointerIntTy(Node, 0),
+ GT::child_begin(Node)));
+ this->Visited.insert(Node);
+ }
+ }
+ inline df_iterator(SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ // End is when stack is empty
+ }
+
+ inline void toNext() {
+ do {
+ std::pair<PointerIntTy, ChildItTy> &Top = VisitStack.back();
+ NodeType *Node = Top.first.getPointer();
+ ChildItTy &It = Top.second;
+ if (!Top.first.getInt()) {
+ // now retrieve the real begin of the children before we dive in
+ It = GT::child_begin(Node);
+ Top.first.setInt(1);
+ }
+
+ while (It != GT::child_end(Node)) {
+ NodeType *Next = *It++;
+ // Has our next sibling been visited?
+ if (Next && !this->Visited.count(Next)) {
+ // No, do it now.
+ this->Visited.insert(Next);
+ VisitStack.push_back(std::make_pair(PointerIntTy(Next, 0),
+ GT::child_begin(Next)));
+ return;
+ }
+ }
+
+ // Oops, ran out of successors... go up a level on the stack.
+ VisitStack.pop_back();
+ } while (!VisitStack.empty());
+ }
+
+public:
+ typedef typename super::pointer pointer;
+ typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+ // Provide static begin and end methods as our public "constructors"
+ static inline _Self begin(const GraphT& G) {
+ return _Self(GT::getEntryNode(G));
+ }
+ static inline _Self end(const GraphT& G) { return _Self(); }
+
+ // Static begin and end methods as our public ctors for external iterators
+ static inline _Self begin(const GraphT& G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.back().first.getPointer();
+ }
+
+ // This is a nonstandard operator-> that dereferences the pointer an extra
+ // time... so that you can actually call methods ON the Node, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ toNext();
+ return *this;
+ }
+
+ // skips all children of the current node and traverses to next node
+ //
+ inline _Self& skipChildren() {
+ VisitStack.pop_back();
+ if (!VisitStack.empty())
+ toNext();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // nodeVisited - return true if this iterator has already visited the
+ // specified node. This is public, and will probably be used to iterate over
+ // nodes that a depth first iteration did not find: ie unreachable nodes.
+ //
+ inline bool nodeVisited(NodeType *Node) const {
+ return this->Visited.count(Node) != 0;
+ }
+
+ /// getPathLength - Return the length of the path from the entry node to the
+ /// current node, counting both nodes.
+ unsigned getPathLength() const { return VisitStack.size(); }
+
+ /// getPath - Return the n'th node in the path from the the entry node to the
+ /// current node.
+ NodeType *getPath(unsigned n) const {
+ return VisitStack[n].first.getPointer();
+ }
+};
+
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+df_iterator<T> df_begin(const T& G) {
+ return df_iterator<T>::begin(G);
+}
+
+template <class T>
+df_iterator<T> df_end(const T& G) {
+ return df_iterator<T>::end(G);
+}
+
+// Provide global definitions of external depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct df_ext_iterator : public df_iterator<T, SetTy, true> {
+ df_ext_iterator(const df_iterator<T, SetTy, true> &V)
+ : df_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_begin(const T& G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_end(const T& G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::end(G, S);
+}
+
+
+// Provide global definitions of inverse depth first iterators...
+template <class T,
+ class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
+ bool External = false>
+struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
+ idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
+ : df_iterator<Inverse<T>, SetTy, External>(V) {}
+};
+
+template <class T>
+idf_iterator<T> idf_begin(const T& G) {
+ return idf_iterator<T>::begin(Inverse<T>(G));
+}
+
+template <class T>
+idf_iterator<T> idf_end(const T& G){
+ return idf_iterator<T>::end(Inverse<T>(G));
+}
+
+// Provide global definitions of external inverse depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
+ idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+ idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_begin(const T& G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::begin(Inverse<T>(G), S);
+}
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_end(const T& G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::end(Inverse<T>(G), S);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h b/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h
new file mode 100644
index 000000000000..771476c30361
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/EquivalenceClasses.h
@@ -0,0 +1,281 @@
+//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic implementation of equivalence classes through the use Tarjan's
+// efficient union-find algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
+#define LLVM_ADT_EQUIVALENCECLASSES_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <set>
+
+namespace llvm {
+
+/// EquivalenceClasses - This represents a collection of equivalence classes and
+/// supports three efficient operations: insert an element into a class of its
+/// own, union two classes, and find the class for a given element. In
+/// addition to these modification methods, it is possible to iterate over all
+/// of the equivalence classes and all of the elements in a class.
+///
+/// This implementation is an efficient implementation that only stores one copy
+/// of the element being indexed per entry in the set, and allows any arbitrary
+/// type to be indexed (as long as it can be ordered with operator<).
+///
+/// Here is a simple example using integers:
+///
+/// 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
+/// EC.unionSets(5, 1); // merge the set for 1 with 5's set.
+///
+/// for (EquivalenceClasses<int>::iterator I = EC.begin(), E = EC.end();
+/// I != E; ++I) { // Iterate over all of the equivalence sets.
+/// if (!I->isLeader()) continue; // Ignore non-leader sets.
+/// for (EquivalenceClasses<int>::member_iterator MI = EC.member_begin(I);
+/// MI != EC.member_end(); ++MI) // Loop over members in this set.
+/// cerr << *MI << " "; // Print member.
+/// cerr << "\n"; // Finish set.
+/// }
+///
+/// This example prints:
+/// 4
+/// 5 1 2
+///
+template <class ElemTy>
+class EquivalenceClasses {
+ /// ECValue - The EquivalenceClasses data structure is just a set of these.
+ /// Each of these represents a relation for a value. First it stores the
+ /// value itself, which provides the ordering that the set queries. Next, it
+ /// provides a "next pointer", which is used to enumerate all of the elements
+ /// in the unioned set. Finally, it defines either a "end of list pointer" or
+ /// "leader pointer" depending on whether the value itself is a leader. A
+ /// "leader pointer" points to the node that is the leader for this element,
+ /// if the node is not a leader. A "end of list pointer" points to the last
+ /// node in the list of members of this list. Whether or not a node is a
+ /// leader is determined by a bit stolen from one of the pointers.
+ class ECValue {
+ friend class EquivalenceClasses;
+ mutable const ECValue *Leader, *Next;
+ ElemTy Data;
+ // ECValue ctor - Start out with EndOfList pointing to this node, Next is
+ // Null, isLeader = true.
+ ECValue(const ElemTy &Elt)
+ : Leader(this), Next((ECValue*)(intptr_t)1), Data(Elt) {}
+
+ const ECValue *getLeader() const {
+ if (isLeader()) return this;
+ if (Leader->isLeader()) return Leader;
+ // Path compression.
+ return Leader = Leader->getLeader();
+ }
+ const ECValue *getEndOfList() const {
+ assert(isLeader() && "Cannot get the end of a list for a non-leader!");
+ return Leader;
+ }
+
+ void setNext(const ECValue *NewNext) const {
+ assert(getNext() == 0 && "Already has a next pointer!");
+ Next = (const ECValue*)((intptr_t)NewNext | (intptr_t)isLeader());
+ }
+ public:
+ ECValue(const ECValue &RHS) : Leader(this), Next((ECValue*)(intptr_t)1),
+ Data(RHS.Data) {
+ // Only support copying of singleton nodes.
+ assert(RHS.isLeader() && RHS.getNext() == 0 && "Not a singleton!");
+ }
+
+ bool operator<(const ECValue &UFN) const { return Data < UFN.Data; }
+
+ bool isLeader() const { return (intptr_t)Next & 1; }
+ const ElemTy &getData() const { return Data; }
+
+ const ECValue *getNext() const {
+ return (ECValue*)((intptr_t)Next & ~(intptr_t)1);
+ }
+
+ template<typename T>
+ bool operator<(const T &Val) const { return Data < Val; }
+ };
+
+ /// TheMapping - This implicitly provides a mapping from ElemTy values to the
+ /// ECValues, it just keeps the key as part of the value.
+ std::set<ECValue> TheMapping;
+
+public:
+ EquivalenceClasses() {}
+ EquivalenceClasses(const EquivalenceClasses &RHS) {
+ operator=(RHS);
+ }
+
+ const EquivalenceClasses &operator=(const EquivalenceClasses &RHS) {
+ TheMapping.clear();
+ for (iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
+ if (I->isLeader()) {
+ member_iterator MI = RHS.member_begin(I);
+ member_iterator LeaderIt = member_begin(insert(*MI));
+ for (++MI; MI != member_end(); ++MI)
+ unionSets(LeaderIt, member_begin(insert(*MI)));
+ }
+ return *this;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inspection methods
+ //
+
+ /// iterator* - Provides a way to iterate over all values in the set.
+ typedef typename std::set<ECValue>::const_iterator iterator;
+ iterator begin() const { return TheMapping.begin(); }
+ iterator end() const { return TheMapping.end(); }
+
+ bool empty() const { return TheMapping.empty(); }
+
+ /// member_* Iterate over the members of an equivalence class.
+ ///
+ class member_iterator;
+ member_iterator member_begin(iterator I) const {
+ // Only leaders provide anything to iterate over.
+ return member_iterator(I->isLeader() ? &*I : 0);
+ }
+ member_iterator member_end() const {
+ return member_iterator(0);
+ }
+
+ /// findValue - Return an iterator to the specified value. If it does not
+ /// exist, end() is returned.
+ iterator findValue(const ElemTy &V) const {
+ return TheMapping.find(V);
+ }
+
+ /// getLeaderValue - Return the leader for the specified value that is in the
+ /// set. It is an error to call this method for a value that is not yet in
+ /// the set. For that, call getOrInsertLeaderValue(V).
+ const ElemTy &getLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(V);
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getOrInsertLeaderValue - Return the leader for the specified value that is
+ /// in the set. If the member is not in the set, it is inserted, then
+ /// returned.
+ const ElemTy &getOrInsertLeaderValue(const ElemTy &V) {
+ member_iterator MI = findLeader(insert(V));
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getNumClasses - Return the number of equivalence classes in this set.
+ /// Note that this is a linear time operation.
+ unsigned getNumClasses() const {
+ unsigned NC = 0;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (I->isLeader()) ++NC;
+ return NC;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Mutation methods
+
+ /// insert - Insert a new value into the union/find set, ignoring the request
+ /// if the value already exists.
+ iterator insert(const ElemTy &Data) {
+ return TheMapping.insert(ECValue(Data)).first;
+ }
+
+ /// findLeader - Given a value in the set, return a member iterator for the
+ /// equivalence class it is in. This does the path-compression part that
+ /// makes union-find "union findy". This returns an end iterator if the value
+ /// is not in the equivalence class.
+ ///
+ member_iterator findLeader(iterator I) const {
+ if (I == TheMapping.end()) return member_end();
+ return member_iterator(I->getLeader());
+ }
+ member_iterator findLeader(const ElemTy &V) const {
+ return findLeader(TheMapping.find(V));
+ }
+
+
+ /// union - Merge the two equivalence sets for the specified values, inserting
+ /// them if they do not already exist in the equivalence set.
+ member_iterator unionSets(const ElemTy &V1, const ElemTy &V2) {
+ iterator V1I = insert(V1), V2I = insert(V2);
+ return unionSets(findLeader(V1I), findLeader(V2I));
+ }
+ member_iterator unionSets(member_iterator L1, member_iterator L2) {
+ assert(L1 != member_end() && L2 != member_end() && "Illegal inputs!");
+ if (L1 == L2) return L1; // Unifying the same two sets, noop.
+
+ // Otherwise, this is a real union operation. Set the end of the L1 list to
+ // point to the L2 leader node.
+ const ECValue &L1LV = *L1.Node, &L2LV = *L2.Node;
+ L1LV.getEndOfList()->setNext(&L2LV);
+
+ // Update L1LV's end of list pointer.
+ L1LV.Leader = L2LV.getEndOfList();
+
+ // Clear L2's leader flag:
+ L2LV.Next = L2LV.getNext();
+
+ // L2's leader is now L1.
+ L2LV.Leader = &L1LV;
+ return L1;
+ }
+
+ class member_iterator : public std::iterator<std::forward_iterator_tag,
+ const ElemTy, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag,
+ const ElemTy, ptrdiff_t> super;
+ const ECValue *Node;
+ friend class EquivalenceClasses;
+ public:
+ typedef size_t size_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+ explicit member_iterator() {}
+ explicit member_iterator(const ECValue *N) : Node(N) {}
+ member_iterator(const member_iterator &I) : Node(I.Node) {}
+
+ reference operator*() const {
+ assert(Node != 0 && "Dereferencing end()!");
+ return Node->getData();
+ }
+ reference operator->() const { return operator*(); }
+
+ member_iterator &operator++() {
+ assert(Node != 0 && "++'d off the end of the list!");
+ Node = Node->getNext();
+ return *this;
+ }
+
+ member_iterator operator++(int) { // postincrement operators.
+ member_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(const member_iterator &RHS) const {
+ return Node == RHS.Node;
+ }
+ bool operator!=(const member_iterator &RHS) const {
+ return Node != RHS.Node;
+ }
+ };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/FoldingSet.h b/contrib/llvm/include/llvm/ADT/FoldingSet.h
new file mode 100644
index 000000000000..7d7c77770020
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/FoldingSet.h
@@ -0,0 +1,680 @@
+//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- 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 hash set that can be used to remove duplication of nodes
+// in a graph. This code was originally created by Chris Lattner for use with
+// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+ class APFloat;
+ class APInt;
+ class BumpPtrAllocator;
+
+/// This folding set used for two purposes:
+/// 1. Given information about a node we want to create, look up the unique
+/// instance of the node in the set. If the node already exists, return
+/// it, otherwise return the bucket it should be inserted into.
+/// 2. Given a node that has already been created, remove it from the set.
+///
+/// This class is implemented as a single-link chained hash table, where the
+/// "buckets" are actually the nodes themselves (the next pointer is in the
+/// node). The last node points back to the bucket to simplify node removal.
+///
+/// Any node that is to be included in the folding set must be a subclass of
+/// FoldingSetNode. The node class must also define a Profile method used to
+/// establish the unique bits of data for the node. The Profile method is
+/// passed a FoldingSetNodeID object which is used to gather the bits. Just
+/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
+/// NOTE: That the folding set does not own the nodes and it is the
+/// responsibility of the user to dispose of the nodes.
+///
+/// Eg.
+/// class MyNode : public FoldingSetNode {
+/// private:
+/// std::string Name;
+/// unsigned Value;
+/// public:
+/// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
+/// ...
+/// void Profile(FoldingSetNodeID &ID) const {
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// }
+/// ...
+/// };
+///
+/// To define the folding set itself use the FoldingSet template;
+///
+/// Eg.
+/// FoldingSet<MyNode> MyFoldingSet;
+///
+/// Four public methods are available to manipulate the folding set;
+///
+/// 1) If you have an existing node that you want add to the set but unsure
+/// that the node might already exist then call;
+///
+/// MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///
+/// If The result is equal to the input then the node has been inserted.
+/// Otherwise, the result is the node existing in the folding set, and the
+/// input can be discarded (use the result instead.)
+///
+/// 2) If you are ready to construct a node but want to check if it already
+/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
+/// check;
+///
+/// FoldingSetNodeID ID;
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// void *InsertPoint;
+///
+/// MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///
+/// If found then M with be non-NULL, else InsertPoint will point to where it
+/// should be inserted using InsertNode.
+///
+/// 3) If you get a NULL result from FindNodeOrInsertPos then you can as a new
+/// node with FindNodeOrInsertPos;
+///
+/// InsertNode(N, InsertPoint);
+///
+/// 4) Finally, if you want to remove a node from the folding set call;
+///
+/// bool WasRemoved = RemoveNode(N);
+///
+/// The result indicates whether the node existed in the folding set.
+
+class FoldingSetNodeID;
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetImpl - Implements the folding set functionality. The main
+/// structure is an array of buckets. Each bucket is indexed by the hash of
+/// the nodes it contains. The bucket itself points to the nodes contained
+/// in the bucket via a singly linked list. The last node in the list points
+/// back to the bucket to facilitate node removal.
+///
+class FoldingSetImpl {
+protected:
+ /// Buckets - Array of bucket chains.
+ ///
+ void **Buckets;
+
+ /// NumBuckets - Length of the Buckets array. Always a power of 2.
+ ///
+ unsigned NumBuckets;
+
+ /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
+ /// is greater than twice the number of buckets.
+ unsigned NumNodes;
+
+public:
+ explicit FoldingSetImpl(unsigned Log2InitSize = 6);
+ virtual ~FoldingSetImpl();
+
+ //===--------------------------------------------------------------------===//
+ /// Node - This class is used to maintain the singly linked bucket list in
+ /// a folding set.
+ ///
+ class Node {
+ private:
+ // NextInFoldingSetBucket - next link in the bucket list.
+ void *NextInFoldingSetBucket;
+
+ public:
+
+ Node() : NextInFoldingSetBucket(0) {}
+
+ // Accessors
+ void *getNextInBucket() const { return NextInFoldingSetBucket; }
+ void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
+ };
+
+ /// clear - Remove all nodes from the folding set.
+ void clear();
+
+ /// RemoveNode - Remove a node from the folding set, returning true if one
+ /// was removed or false if the node was not in the folding set.
+ bool RemoveNode(Node *N);
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and return
+ /// it instead.
+ Node *GetOrInsertNode(Node *N);
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set. InsertPos must be obtained from
+ /// FindNodeOrInsertPos.
+ void InsertNode(Node *N, void *InsertPos);
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set.
+ void InsertNode(Node *N) {
+ Node *Inserted = GetOrInsertNode(N);
+ (void)Inserted;
+ assert(Inserted == N && "Node already inserted!");
+ }
+
+ /// size - Returns the number of nodes in the folding set.
+ unsigned size() const { return NumNodes; }
+
+ /// empty - Returns true if there are no nodes in the folding set.
+ bool empty() const { return NumNodes == 0; }
+
+private:
+
+ /// GrowHashTable - Double the size of the hash table and rehash everything.
+ ///
+ void GrowHashTable();
+
+protected:
+
+ /// GetNodeProfile - Instantiations of the FoldingSet template implement
+ /// this function to gather data bits for the given node.
+ virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
+ /// NodeEquals - Instantiations of the FoldingSet template implement
+ /// this function to compare the given node with the given ID.
+ virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) const=0;
+ /// ComputeNodeHash - Instantiations of the FoldingSet template implement
+ /// this function to compute a hash value for the given node.
+ virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0;
+};
+
+//===----------------------------------------------------------------------===//
+
+template<typename T> struct FoldingSetTrait;
+
+/// DefaultFoldingSetTrait - This class provides default implementations
+/// for FoldingSetTrait implementations.
+///
+template<typename T> struct DefaultFoldingSetTrait {
+ static void Profile(const T &X, FoldingSetNodeID &ID) {
+ X.Profile(ID);
+ }
+ static void Profile(T &X, FoldingSetNodeID &ID) {
+ X.Profile(ID);
+ }
+
+ // Equals - Test if the profile for X would match ID, using TempID
+ // to compute a temporary ID if necessary. The default implementation
+ // just calls Profile and does a regular comparison. Implementations
+ // can override this to provide more efficient implementations.
+ static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID);
+
+ // ComputeHash - Compute a hash value for X, using TempID to
+ // compute a temporary ID if necessary. The default implementation
+ // just calls Profile and does a regular hash computation.
+ // Implementations can override this to provide more efficient
+ // implementations.
+ static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID);
+};
+
+/// FoldingSetTrait - This trait class is used to define behavior of how
+/// to "profile" (in the FoldingSet parlance) an object of a given type.
+/// The default behavior is to invoke a 'Profile' method on an object, but
+/// through template specialization the behavior can be tailored for specific
+/// types. Combined with the FoldingSetNodeWrapper class, one can add objects
+/// to FoldingSets that were not originally designed to have that behavior.
+template<typename T> struct FoldingSetTrait
+ : public DefaultFoldingSetTrait<T> {};
+
+template<typename T, typename Ctx> struct ContextualFoldingSetTrait;
+
+/// DefaultContextualFoldingSetTrait - Like DefaultFoldingSetTrait, but
+/// for ContextualFoldingSets.
+template<typename T, typename Ctx>
+struct DefaultContextualFoldingSetTrait {
+ static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
+ X.Profile(ID, Context);
+ }
+ static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID, Ctx Context);
+ static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID,
+ Ctx Context);
+};
+
+/// ContextualFoldingSetTrait - Like FoldingSetTrait, but for
+/// ContextualFoldingSets.
+template<typename T, typename Ctx> struct ContextualFoldingSetTrait
+ : public DefaultContextualFoldingSetTrait<T, Ctx> {};
+
+//===--------------------------------------------------------------------===//
+/// FoldingSetNodeIDRef - This class describes a reference to an interned
+/// FoldingSetNodeID, which can be a useful to store node id data rather
+/// than using plain FoldingSetNodeIDs, since the 32-element SmallVector
+/// is often much larger than necessary, and the possibility of heap
+/// allocation means it requires a non-trivial destructor call.
+class FoldingSetNodeIDRef {
+ const unsigned *Data;
+ size_t Size;
+public:
+ FoldingSetNodeIDRef() : Data(0), Size(0) {}
+ FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
+
+ /// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
+ /// used to lookup the node in the FoldingSetImpl.
+ unsigned ComputeHash() const;
+
+ bool operator==(FoldingSetNodeIDRef) const;
+
+ const unsigned *getData() const { return Data; }
+ size_t getSize() const { return Size; }
+};
+
+//===--------------------------------------------------------------------===//
+/// FoldingSetNodeID - This class is used to gather all the unique data bits of
+/// a node. When all the bits are gathered this class is used to produce a
+/// hash value for the node.
+///
+class FoldingSetNodeID {
+ /// Bits - Vector of all the data bits that make the node unique.
+ /// Use a SmallVector to avoid a heap allocation in the common case.
+ SmallVector<unsigned, 32> Bits;
+
+public:
+ FoldingSetNodeID() {}
+
+ FoldingSetNodeID(FoldingSetNodeIDRef Ref)
+ : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
+
+ /// Add* - Add various data types to Bit data.
+ ///
+ void AddPointer(const void *Ptr);
+ void AddInteger(signed I);
+ void AddInteger(unsigned I);
+ void AddInteger(long I);
+ void AddInteger(unsigned long I);
+ void AddInteger(long long I);
+ void AddInteger(unsigned long long I);
+ void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
+ void AddString(StringRef String);
+ void AddNodeID(const FoldingSetNodeID &ID);
+
+ template <typename T>
+ inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); }
+
+ /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
+ /// object to be used to compute a new profile.
+ inline void clear() { Bits.clear(); }
+
+ /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
+ /// to lookup the node in the FoldingSetImpl.
+ unsigned ComputeHash() const;
+
+ /// operator== - Used to compare two nodes to each other.
+ ///
+ bool operator==(const FoldingSetNodeID &RHS) const;
+ bool operator==(const FoldingSetNodeIDRef RHS) const;
+
+ /// Intern - Copy this node's data to a memory region allocated from the
+ /// given allocator and return a FoldingSetNodeIDRef describing the
+ /// interned data.
+ FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
+};
+
+// Convenience type to hide the implementation of the folding set.
+typedef FoldingSetImpl::Node FoldingSetNode;
+template<class T> class FoldingSetIterator;
+template<class T> class FoldingSetBucketIterator;
+
+// Definitions of FoldingSetTrait and ContextualFoldingSetTrait functions, which
+// require the definition of FoldingSetNodeID.
+template<typename T>
+inline bool
+DefaultFoldingSetTrait<T>::Equals(T &X, const FoldingSetNodeID &ID,
+ unsigned IDHash, FoldingSetNodeID &TempID) {
+ FoldingSetTrait<T>::Profile(X, TempID);
+ return TempID == ID;
+}
+template<typename T>
+inline unsigned
+DefaultFoldingSetTrait<T>::ComputeHash(T &X, FoldingSetNodeID &TempID) {
+ FoldingSetTrait<T>::Profile(X, TempID);
+ return TempID.ComputeHash();
+}
+template<typename T, typename Ctx>
+inline bool
+DefaultContextualFoldingSetTrait<T, Ctx>::Equals(T &X,
+ const FoldingSetNodeID &ID,
+ unsigned IDHash,
+ FoldingSetNodeID &TempID,
+ Ctx Context) {
+ ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
+ return TempID == ID;
+}
+template<typename T, typename Ctx>
+inline unsigned
+DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
+ FoldingSetNodeID &TempID,
+ Ctx Context) {
+ ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
+ return TempID.ComputeHash();
+}
+
+//===----------------------------------------------------------------------===//
+/// FoldingSet - This template class is used to instantiate a specialized
+/// implementation of the folding set to the node class T. T must be a
+/// subclass of FoldingSetNode and implement a Profile function.
+///
+template<class T> class FoldingSet : public FoldingSetImpl {
+private:
+ /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+ /// way to convert nodes into a unique specifier.
+ virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const {
+ T *TN = static_cast<T *>(N);
+ FoldingSetTrait<T>::Profile(*TN, ID);
+ }
+ /// NodeEquals - Instantiations may optionally provide a way to compare a
+ /// node with a specified ID.
+ virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) const {
+ T *TN = static_cast<T *>(N);
+ return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
+ }
+ /// ComputeNodeHash - Instantiations may optionally provide a way to compute a
+ /// hash value directly from a node.
+ virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const {
+ T *TN = static_cast<T *>(N);
+ return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
+ }
+
+public:
+ explicit FoldingSet(unsigned Log2InitSize = 6)
+ : FoldingSetImpl(Log2InitSize)
+ {}
+
+ typedef FoldingSetIterator<T> iterator;
+ iterator begin() { return iterator(Buckets); }
+ iterator end() { return iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetIterator<const T> const_iterator;
+ const_iterator begin() const { return const_iterator(Buckets); }
+ const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetBucketIterator<T> bucket_iterator;
+
+ bucket_iterator bucket_begin(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+ }
+
+ bucket_iterator bucket_end(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+ }
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and
+ /// return it instead.
+ T *GetOrInsertNode(Node *N) {
+ return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+ }
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+ return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// ContextualFoldingSet - This template class is a further refinement
+/// of FoldingSet which provides a context argument when calling
+/// Profile on its nodes. Currently, that argument is fixed at
+/// initialization time.
+///
+/// T must be a subclass of FoldingSetNode and implement a Profile
+/// function with signature
+/// void Profile(llvm::FoldingSetNodeID &, Ctx);
+template <class T, class Ctx>
+class ContextualFoldingSet : public FoldingSetImpl {
+ // Unfortunately, this can't derive from FoldingSet<T> because the
+ // construction vtable for FoldingSet<T> requires
+ // FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
+ // requires a single-argument T::Profile().
+
+private:
+ Ctx Context;
+
+ /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+ /// way to convert nodes into a unique specifier.
+ virtual void GetNodeProfile(FoldingSetImpl::Node *N,
+ FoldingSetNodeID &ID) const {
+ T *TN = static_cast<T *>(N);
+ ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
+ }
+ virtual bool NodeEquals(FoldingSetImpl::Node *N,
+ const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) const {
+ T *TN = static_cast<T *>(N);
+ return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
+ Context);
+ }
+ virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
+ FoldingSetNodeID &TempID) const {
+ T *TN = static_cast<T *>(N);
+ return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
+ }
+
+public:
+ explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
+ : FoldingSetImpl(Log2InitSize), Context(Context)
+ {}
+
+ Ctx getContext() const { return Context; }
+
+
+ typedef FoldingSetIterator<T> iterator;
+ iterator begin() { return iterator(Buckets); }
+ iterator end() { return iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetIterator<const T> const_iterator;
+ const_iterator begin() const { return const_iterator(Buckets); }
+ const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
+
+ typedef FoldingSetBucketIterator<T> bucket_iterator;
+
+ bucket_iterator bucket_begin(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+ }
+
+ bucket_iterator bucket_end(unsigned hash) {
+ return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+ }
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N'
+ /// and return it instead.
+ T *GetOrInsertNode(Node *N) {
+ return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+ }
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it
+ /// exists, return it. If not, return the insertion token that will
+ /// make insertion faster.
+ T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+ return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetIteratorImpl - This is the common iterator support shared by all
+/// folding sets, which knows how to walk the folding set hash table.
+class FoldingSetIteratorImpl {
+protected:
+ FoldingSetNode *NodePtr;
+ FoldingSetIteratorImpl(void **Bucket);
+ void advance();
+
+public:
+ bool operator==(const FoldingSetIteratorImpl &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const FoldingSetIteratorImpl &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+};
+
+
+template<class T>
+class FoldingSetIterator : public FoldingSetIteratorImpl {
+public:
+ explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
+
+ T &operator*() const {
+ return *static_cast<T*>(NodePtr);
+ }
+
+ T *operator->() const {
+ return static_cast<T*>(NodePtr);
+ }
+
+ inline FoldingSetIterator &operator++() { // Preincrement
+ advance();
+ return *this;
+ }
+ FoldingSetIterator operator++(int) { // Postincrement
+ FoldingSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
+/// shared by all folding sets, which knows how to walk a particular bucket
+/// of a folding set hash table.
+
+class FoldingSetBucketIteratorImpl {
+protected:
+ void *Ptr;
+
+ explicit FoldingSetBucketIteratorImpl(void **Bucket);
+
+ FoldingSetBucketIteratorImpl(void **Bucket, bool)
+ : Ptr(Bucket) {}
+
+ void advance() {
+ void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();
+ uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
+ Ptr = reinterpret_cast<void*>(x);
+ }
+
+public:
+ bool operator==(const FoldingSetBucketIteratorImpl &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+};
+
+
+template<class T>
+class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
+public:
+ explicit FoldingSetBucketIterator(void **Bucket) :
+ FoldingSetBucketIteratorImpl(Bucket) {}
+
+ FoldingSetBucketIterator(void **Bucket, bool) :
+ FoldingSetBucketIteratorImpl(Bucket, true) {}
+
+ T &operator*() const { return *static_cast<T*>(Ptr); }
+ T *operator->() const { return static_cast<T*>(Ptr); }
+
+ inline FoldingSetBucketIterator &operator++() { // Preincrement
+ advance();
+ return *this;
+ }
+ FoldingSetBucketIterator operator++(int) { // Postincrement
+ FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
+/// types in an enclosing object so that they can be inserted into FoldingSets.
+template <typename T>
+class FoldingSetNodeWrapper : public FoldingSetNode {
+ T data;
+public:
+ explicit FoldingSetNodeWrapper(const T &x) : data(x) {}
+ virtual ~FoldingSetNodeWrapper() {}
+
+ template<typename A1>
+ explicit FoldingSetNodeWrapper(const A1 &a1)
+ : data(a1) {}
+
+ template <typename A1, typename A2>
+ explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2)
+ : data(a1,a2) {}
+
+ template <typename A1, typename A2, typename A3>
+ explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3)
+ : data(a1,a2,a3) {}
+
+ template <typename A1, typename A2, typename A3, typename A4>
+ explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
+ const A4 &a4)
+ : data(a1,a2,a3,a4) {}
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5>
+ explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
+ const A4 &a4, const A5 &a5)
+ : data(a1,a2,a3,a4,a5) {}
+
+
+ void Profile(FoldingSetNodeID &ID) { FoldingSetTrait<T>::Profile(data, ID); }
+
+ T &getValue() { return data; }
+ const T &getValue() const { return data; }
+
+ operator T&() { return data; }
+ operator const T&() const { return data; }
+};
+
+//===----------------------------------------------------------------------===//
+/// FastFoldingSetNode - This is a subclass of FoldingSetNode which stores
+/// a FoldingSetNodeID value rather than requiring the node to recompute it
+/// each time it is needed. This trades space for speed (which can be
+/// significant if the ID is long), and it also permits nodes to drop
+/// information that would otherwise only be required for recomputing an ID.
+class FastFoldingSetNode : public FoldingSetNode {
+ FoldingSetNodeID FastID;
+protected:
+ explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
+public:
+ void Profile(FoldingSetNodeID &ID) const {
+ ID.AddNodeID(FastID);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Partial specializations of FoldingSetTrait.
+
+template<typename T> struct FoldingSetTrait<T*> {
+ static inline void Profile(T *X, FoldingSetNodeID &ID) {
+ ID.AddPointer(X);
+ }
+};
+} // End of namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/GraphTraits.h b/contrib/llvm/include/llvm/ADT/GraphTraits.h
new file mode 100644
index 000000000000..823caef7647e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/GraphTraits.h
@@ -0,0 +1,106 @@
+//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- 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 little GraphTraits<X> template class that should be
+// specialized by classes that want to be iteratable by generic graph iterators.
+//
+// This file also defines the marker class Inverse that is used to iterate over
+// graphs in a graph defined, inverse ordering...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_GRAPHTRAITS_H
+#define LLVM_ADT_GRAPHTRAITS_H
+
+namespace llvm {
+
+// GraphTraits - This class should be specialized by different graph types...
+// which is why the default version is empty.
+//
+template<class GraphType>
+struct GraphTraits {
+ // Elements to provide:
+
+ // typedef NodeType - Type of Node in the graph
+ // typedef ChildIteratorType - Type used to iterate over children in graph
+
+ // static NodeType *getEntryNode(const GraphType &)
+ // Return the entry node of the graph
+
+ // static ChildIteratorType child_begin(NodeType *)
+ // static ChildIteratorType child_end (NodeType *)
+ // Return iterators that point to the beginning and ending of the child
+ // node list for the specified node.
+ //
+
+
+ // typedef ...iterator nodes_iterator;
+ // static nodes_iterator nodes_begin(GraphType *G)
+ // static nodes_iterator nodes_end (GraphType *G)
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+
+ // static unsigned size (GraphType *G)
+ // Return total number of nodes in the graph
+ //
+
+
+ // If anyone tries to use this class without having an appropriate
+ // specialization, make an error. If you get this error, it's because you
+ // need to include the appropriate specialization of GraphTraits<> for your
+ // graph, or you need to define it for a new graph type. Either that or
+ // your argument to XXX_begin(...) is unknown or needs to have the proper .h
+ // file #include'd.
+ //
+ typedef typename GraphType::UnknownGraphTypeError NodeType;
+};
+
+
+// Inverse - This class is used as a little marker class to tell the graph
+// iterator to iterate over the graph in a graph defined "Inverse" ordering.
+// Not all graphs define an inverse ordering, and if they do, it depends on
+// the graph exactly what that is. Here's an example of usage with the
+// df_iterator:
+//
+// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+// Which is equivalent to:
+// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+template <class GraphType>
+struct Inverse {
+ const GraphType &Graph;
+
+ inline Inverse(const GraphType &G) : Graph(G) {}
+};
+
+// Provide a partial specialization of GraphTraits so that the inverse of an
+// inverse falls back to the original graph.
+template<class T>
+struct GraphTraits<Inverse<Inverse<T> > > {
+ typedef typename GraphTraits<T>::NodeType NodeType;
+ typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
+ return GraphTraits<T>::getEntryNode(G->Graph.Graph);
+ }
+
+ static ChildIteratorType child_begin(NodeType* N) {
+ return GraphTraits<T>::child_begin(N);
+ }
+
+ static ChildIteratorType child_end(NodeType* N) {
+ return GraphTraits<T>::child_end(N);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/Hashing.h b/contrib/llvm/include/llvm/ADT/Hashing.h
new file mode 100644
index 000000000000..53032ee538d2
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/Hashing.h
@@ -0,0 +1,770 @@
+//===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the newly proposed standard C++ interfaces for hashing
+// arbitrary data and building hash functions for user-defined types. This
+// interface was originally proposed in N3333[1] and is currently under review
+// for inclusion in a future TR and/or standard.
+//
+// The primary interfaces provide are comprised of one type and three functions:
+//
+// -- 'hash_code' class is an opaque type representing the hash code for some
+// data. It is the intended product of hashing, and can be used to implement
+// hash tables, checksumming, and other common uses of hashes. It is not an
+// integer type (although it can be converted to one) because it is risky
+// to assume much about the internals of a hash_code. In particular, each
+// execution of the program has a high probability of producing a different
+// hash_code for a given input. Thus their values are not stable to save or
+// persist, and should only be used during the execution for the
+// construction of hashing datastructures.
+//
+// -- 'hash_value' is a function designed to be overloaded for each
+// user-defined type which wishes to be used within a hashing context. It
+// should be overloaded within the user-defined type's namespace and found
+// via ADL. Overloads for primitive types are provided by this library.
+//
+// -- 'hash_combine' and 'hash_combine_range' are functions designed to aid
+// programmers in easily and intuitively combining a set of data into
+// a single hash_code for their object. They should only logically be used
+// within the implementation of a 'hash_value' routine or similar context.
+//
+// Note that 'hash_combine_range' contains very special logic for hashing
+// a contiguous array of integers or pointers. This logic is *extremely* fast,
+// on a modern Intel "Gainestown" Xeon (Nehalem uarch) @2.2 GHz, these were
+// benchmarked at over 6.5 GiB/s for large keys, and <20 cycles/hash for keys
+// under 32-bytes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASHING_H
+#define LLVM_ADT_HASHING_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <iterator>
+#include <utility>
+
+// Allow detecting C++11 feature availability when building with Clang without
+// breaking other compilers.
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+namespace llvm {
+
+/// \brief An opaque object representing a hash code.
+///
+/// This object represents the result of hashing some entity. It is intended to
+/// be used to implement hashtables or other hashing-based data structures.
+/// While it wraps and exposes a numeric value, this value should not be
+/// trusted to be stable or predictable across processes or executions.
+///
+/// In order to obtain the hash_code for an object 'x':
+/// \code
+/// using llvm::hash_value;
+/// llvm::hash_code code = hash_value(x);
+/// \endcode
+///
+/// Also note that there are two numerical values which are reserved, and the
+/// implementation ensures will never be produced for real hash_codes. These
+/// can be used as sentinels within hashing data structures.
+class hash_code {
+ size_t value;
+
+public:
+ /// \brief Default construct a hash_code.
+ /// Note that this leaves the value uninitialized.
+ hash_code() {}
+
+ /// \brief Form a hash code directly from a numerical value.
+ hash_code(size_t value) : value(value) {}
+
+ /// \brief Convert the hash code to its numerical value for use.
+ /*explicit*/ operator size_t() const { return value; }
+
+ friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
+ return lhs.value == rhs.value;
+ }
+ friend bool operator!=(const hash_code &lhs, const hash_code &rhs) {
+ return lhs.value != rhs.value;
+ }
+
+ /// \brief Allow a hash_code to be directly run through hash_value.
+ friend size_t hash_value(const hash_code &code) { return code.value; }
+};
+
+/// \brief Compute a hash_code for any integer value.
+///
+/// Note that this function is intended to compute the same hash_code for
+/// a particular value without regard to the pre-promotion type. This is in
+/// contrast to hash_combine which may produce different hash_codes for
+/// differing argument types even if they would implicit promote to a common
+/// type without changing the value.
+template <typename T>
+typename enable_if<is_integral_or_enum<T>, hash_code>::type hash_value(T value);
+
+/// \brief Compute a hash_code for a pointer's address.
+///
+/// N.B.: This hashes the *address*. Not the value and not the type.
+template <typename T> hash_code hash_value(const T *ptr);
+
+/// \brief Compute a hash_code for a pair of objects.
+template <typename T, typename U>
+hash_code hash_value(const std::pair<T, U> &arg);
+
+/// \brief Compute a hash_code for a standard string.
+template <typename T>
+hash_code hash_value(const std::basic_string<T> &arg);
+
+
+/// \brief Override the execution seed with a fixed value.
+///
+/// This hashing library uses a per-execution seed designed to change on each
+/// run with high probability in order to ensure that the hash codes are not
+/// attackable and to ensure that output which is intended to be stable does
+/// not rely on the particulars of the hash codes produced.
+///
+/// That said, there are use cases where it is important to be able to
+/// reproduce *exactly* a specific behavior. To that end, we provide a function
+/// which will forcibly set the seed to a fixed value. This must be done at the
+/// start of the program, before any hashes are computed. Also, it cannot be
+/// undone. This makes it thread-hostile and very hard to use outside of
+/// immediately on start of a simple program designed for reproducible
+/// behavior.
+void set_fixed_execution_hash_seed(size_t fixed_value);
+
+
+// All of the implementation details of actually computing the various hash
+// code values are held within this namespace. These routines are included in
+// the header file mainly to allow inlining and constant propagation.
+namespace hashing {
+namespace detail {
+
+inline uint64_t fetch64(const char *p) {
+ uint64_t result;
+ memcpy(&result, p, sizeof(result));
+ if (sys::isBigEndianHost())
+ return sys::SwapByteOrder(result);
+ return result;
+}
+
+inline uint32_t fetch32(const char *p) {
+ uint32_t result;
+ memcpy(&result, p, sizeof(result));
+ if (sys::isBigEndianHost())
+ return sys::SwapByteOrder(result);
+ return result;
+}
+
+/// Some primes between 2^63 and 2^64 for various uses.
+static const uint64_t k0 = 0xc3a5c85c97cb3127ULL;
+static const uint64_t k1 = 0xb492b66fbe98f273ULL;
+static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
+static const uint64_t k3 = 0xc949d7c7509e6557ULL;
+
+/// \brief Bitwise right rotate.
+/// Normally this will compile to a single instruction, especially if the
+/// shift is a manifest constant.
+inline uint64_t rotate(uint64_t val, size_t shift) {
+ // Avoid shifting by 64: doing so yields an undefined result.
+ return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
+}
+
+inline uint64_t shift_mix(uint64_t val) {
+ return val ^ (val >> 47);
+}
+
+inline uint64_t hash_16_bytes(uint64_t low, uint64_t high) {
+ // Murmur-inspired hashing.
+ const uint64_t kMul = 0x9ddfea08eb382d69ULL;
+ uint64_t a = (low ^ high) * kMul;
+ a ^= (a >> 47);
+ uint64_t b = (high ^ a) * kMul;
+ b ^= (b >> 47);
+ b *= kMul;
+ return b;
+}
+
+inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) {
+ uint8_t a = s[0];
+ uint8_t b = s[len >> 1];
+ uint8_t c = s[len - 1];
+ uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8);
+ uint32_t z = len + (static_cast<uint32_t>(c) << 2);
+ return shift_mix(y * k2 ^ z * k3 ^ seed) * k2;
+}
+
+inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) {
+ uint64_t a = fetch32(s);
+ return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4));
+}
+
+inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) {
+ uint64_t a = fetch64(s);
+ uint64_t b = fetch64(s + len - 8);
+ return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b;
+}
+
+inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) {
+ uint64_t a = fetch64(s) * k1;
+ uint64_t b = fetch64(s + 8);
+ uint64_t c = fetch64(s + len - 8) * k2;
+ uint64_t d = fetch64(s + len - 16) * k0;
+ return hash_16_bytes(rotate(a - b, 43) + rotate(c ^ seed, 30) + d,
+ a + rotate(b ^ k3, 20) - c + len + seed);
+}
+
+inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) {
+ uint64_t z = fetch64(s + 24);
+ uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0;
+ uint64_t b = rotate(a + z, 52);
+ uint64_t c = rotate(a, 37);
+ a += fetch64(s + 8);
+ c += rotate(a, 7);
+ a += fetch64(s + 16);
+ uint64_t vf = a + z;
+ uint64_t vs = b + rotate(a, 31) + c;
+ a = fetch64(s + 16) + fetch64(s + len - 32);
+ z = fetch64(s + len - 8);
+ b = rotate(a + z, 52);
+ c = rotate(a, 37);
+ a += fetch64(s + len - 24);
+ c += rotate(a, 7);
+ a += fetch64(s + len - 16);
+ uint64_t wf = a + z;
+ uint64_t ws = b + rotate(a, 31) + c;
+ uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0);
+ return shift_mix((seed ^ (r * k0)) + vs) * k2;
+}
+
+inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
+ if (length >= 4 && length <= 8)
+ return hash_4to8_bytes(s, length, seed);
+ if (length > 8 && length <= 16)
+ return hash_9to16_bytes(s, length, seed);
+ if (length > 16 && length <= 32)
+ return hash_17to32_bytes(s, length, seed);
+ if (length > 32)
+ return hash_33to64_bytes(s, length, seed);
+ if (length != 0)
+ return hash_1to3_bytes(s, length, seed);
+
+ return k2 ^ seed;
+}
+
+/// \brief The intermediate state used during hashing.
+/// Currently, the algorithm for computing hash codes is based on CityHash and
+/// keeps 56 bytes of arbitrary state.
+struct hash_state {
+ uint64_t h0, h1, h2, h3, h4, h5, h6;
+ uint64_t seed;
+
+ /// \brief Create a new hash_state structure and initialize it based on the
+ /// seed and the first 64-byte chunk.
+ /// This effectively performs the initial mix.
+ static hash_state create(const char *s, uint64_t seed) {
+ hash_state state = {
+ 0, seed, hash_16_bytes(seed, k1), rotate(seed ^ k1, 49),
+ seed * k1, shift_mix(seed), 0, seed };
+ state.h6 = hash_16_bytes(state.h4, state.h5);
+ state.mix(s);
+ return state;
+ }
+
+ /// \brief Mix 32-bytes from the input sequence into the 16-bytes of 'a'
+ /// and 'b', including whatever is already in 'a' and 'b'.
+ static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
+ a += fetch64(s);
+ uint64_t c = fetch64(s + 24);
+ b = rotate(b + a + c, 21);
+ uint64_t d = a;
+ a += fetch64(s + 8) + fetch64(s + 16);
+ b += rotate(a, 44) + d;
+ a += c;
+ }
+
+ /// \brief Mix in a 64-byte buffer of data.
+ /// We mix all 64 bytes even when the chunk length is smaller, but we
+ /// record the actual length.
+ void mix(const char *s) {
+ h0 = rotate(h0 + h1 + h3 + fetch64(s + 8), 37) * k1;
+ h1 = rotate(h1 + h4 + fetch64(s + 48), 42) * k1;
+ h0 ^= h6;
+ h1 += h3 + fetch64(s + 40);
+ h2 = rotate(h2 + h5, 33) * k1;
+ h3 = h4 * k1;
+ h4 = h0 + h5;
+ mix_32_bytes(s, h3, h4);
+ h5 = h2 + h6;
+ h6 = h1 + fetch64(s + 16);
+ mix_32_bytes(s + 32, h5, h6);
+ std::swap(h2, h0);
+ }
+
+ /// \brief Compute the final 64-bit hash code value based on the current
+ /// state and the length of bytes hashed.
+ uint64_t finalize(size_t length) {
+ return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
+ hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0);
+ }
+};
+
+
+/// \brief A global, fixed seed-override variable.
+///
+/// This variable can be set using the \see llvm::set_fixed_execution_seed
+/// function. See that function for details. Do not, under any circumstances,
+/// set or read this variable.
+extern size_t fixed_seed_override;
+
+inline size_t get_execution_seed() {
+ // FIXME: This needs to be a per-execution seed. This is just a placeholder
+ // implementation. Switching to a per-execution seed is likely to flush out
+ // instability bugs and so will happen as its own commit.
+ //
+ // However, if there is a fixed seed override set the first time this is
+ // called, return that instead of the per-execution seed.
+ const uint64_t seed_prime = 0xff51afd7ed558ccdULL;
+ static size_t seed = fixed_seed_override ? fixed_seed_override
+ : (size_t)seed_prime;
+ return seed;
+}
+
+
+/// \brief Trait to indicate whether a type's bits can be hashed directly.
+///
+/// A type trait which is true if we want to combine values for hashing by
+/// reading the underlying data. It is false if values of this type must
+/// first be passed to hash_value, and the resulting hash_codes combined.
+//
+// FIXME: We want to replace is_integral_or_enum and is_pointer here with
+// a predicate which asserts that comparing the underlying storage of two
+// values of the type for equality is equivalent to comparing the two values
+// for equality. For all the platforms we care about, this holds for integers
+// and pointers, but there are platforms where it doesn't and we would like to
+// support user-defined types which happen to satisfy this property.
+template <typename T> struct is_hashable_data
+ : integral_constant<bool, ((is_integral_or_enum<T>::value ||
+ is_pointer<T>::value) &&
+ 64 % sizeof(T) == 0)> {};
+
+// Special case std::pair to detect when both types are viable and when there
+// is no alignment-derived padding in the pair. This is a bit of a lie because
+// std::pair isn't truly POD, but it's close enough in all reasonable
+// implementations for our use case of hashing the underlying data.
+template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
+ : integral_constant<bool, (is_hashable_data<T>::value &&
+ is_hashable_data<U>::value &&
+ (sizeof(T) + sizeof(U)) ==
+ sizeof(std::pair<T, U>))> {};
+
+/// \brief Helper to get the hashable data representation for a type.
+/// This variant is enabled when the type itself can be used.
+template <typename T>
+typename enable_if<is_hashable_data<T>, T>::type
+get_hashable_data(const T &value) {
+ return value;
+}
+/// \brief Helper to get the hashable data representation for a type.
+/// This variant is enabled when we must first call hash_value and use the
+/// result as our data.
+template <typename T>
+typename enable_if_c<!is_hashable_data<T>::value, size_t>::type
+get_hashable_data(const T &value) {
+ using ::llvm::hash_value;
+ return hash_value(value);
+}
+
+/// \brief Helper to store data from a value into a buffer and advance the
+/// pointer into that buffer.
+///
+/// This routine first checks whether there is enough space in the provided
+/// buffer, and if not immediately returns false. If there is space, it
+/// copies the underlying bytes of value into the buffer, advances the
+/// buffer_ptr past the copied bytes, and returns true.
+template <typename T>
+bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
+ size_t offset = 0) {
+ size_t store_size = sizeof(value) - offset;
+ if (buffer_ptr + store_size > buffer_end)
+ return false;
+ const char *value_data = reinterpret_cast<const char *>(&value);
+ memcpy(buffer_ptr, value_data + offset, store_size);
+ buffer_ptr += store_size;
+ return true;
+}
+
+/// \brief Implement the combining of integral values into a hash_code.
+///
+/// This overload is selected when the value type of the iterator is
+/// integral. Rather than computing a hash_code for each object and then
+/// combining them, this (as an optimization) directly combines the integers.
+template <typename InputIteratorT>
+hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
+ typedef typename std::iterator_traits<InputIteratorT>::value_type ValueT;
+ const size_t seed = get_execution_seed();
+ char buffer[64], *buffer_ptr = buffer;
+ char *const buffer_end = buffer_ptr + array_lengthof(buffer);
+ while (first != last && store_and_advance(buffer_ptr, buffer_end,
+ get_hashable_data(*first)))
+ ++first;
+ if (first == last)
+ return hash_short(buffer, buffer_ptr - buffer, seed);
+ assert(buffer_ptr == buffer_end);
+
+ hash_state state = state.create(buffer, seed);
+ size_t length = 64;
+ while (first != last) {
+ // Fill up the buffer. We don't clear it, which re-mixes the last round
+ // when only a partial 64-byte chunk is left.
+ buffer_ptr = buffer;
+ while (first != last && store_and_advance(buffer_ptr, buffer_end,
+ get_hashable_data(*first)))
+ ++first;
+
+ // Rotate the buffer if we did a partial fill in order to simulate doing
+ // a mix of the last 64-bytes. That is how the algorithm works when we
+ // have a contiguous byte sequence, and we want to emulate that here.
+ std::rotate(buffer, buffer_ptr, buffer_end);
+
+ // Mix this chunk into the current state.
+ state.mix(buffer);
+ length += buffer_ptr - buffer;
+ };
+
+ return state.finalize(length);
+}
+
+/// \brief Implement the combining of integral values into a hash_code.
+///
+/// This overload is selected when the value type of the iterator is integral
+/// and when the input iterator is actually a pointer. Rather than computing
+/// a hash_code for each object and then combining them, this (as an
+/// optimization) directly combines the integers. Also, because the integers
+/// are stored in contiguous memory, this routine avoids copying each value
+/// and directly reads from the underlying memory.
+template <typename ValueT>
+typename enable_if<is_hashable_data<ValueT>, hash_code>::type
+hash_combine_range_impl(ValueT *first, ValueT *last) {
+ const size_t seed = get_execution_seed();
+ const char *s_begin = reinterpret_cast<const char *>(first);
+ const char *s_end = reinterpret_cast<const char *>(last);
+ const size_t length = std::distance(s_begin, s_end);
+ if (length <= 64)
+ return hash_short(s_begin, length, seed);
+
+ const char *s_aligned_end = s_begin + (length & ~63);
+ hash_state state = state.create(s_begin, seed);
+ s_begin += 64;
+ while (s_begin != s_aligned_end) {
+ state.mix(s_begin);
+ s_begin += 64;
+ }
+ if (length & 63)
+ state.mix(s_end - 64);
+
+ return state.finalize(length);
+}
+
+} // namespace detail
+} // namespace hashing
+
+
+/// \brief Compute a hash_code for a sequence of values.
+///
+/// This hashes a sequence of values. It produces the same hash_code as
+/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
+/// and is significantly faster given pointers and types which can be hashed as
+/// a sequence of bytes.
+template <typename InputIteratorT>
+hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
+ return ::llvm::hashing::detail::hash_combine_range_impl(first, last);
+}
+
+
+// Implementation details for hash_combine.
+namespace hashing {
+namespace detail {
+
+/// \brief Helper class to manage the recursive combining of hash_combine
+/// arguments.
+///
+/// This class exists to manage the state and various calls involved in the
+/// recursive combining of arguments used in hash_combine. It is particularly
+/// useful at minimizing the code in the recursive calls to ease the pain
+/// caused by a lack of variadic functions.
+struct hash_combine_recursive_helper {
+ char buffer[64];
+ hash_state state;
+ const size_t seed;
+
+public:
+ /// \brief Construct a recursive hash combining helper.
+ ///
+ /// This sets up the state for a recursive hash combine, including getting
+ /// the seed and buffer setup.
+ hash_combine_recursive_helper()
+ : seed(get_execution_seed()) {}
+
+ /// \brief Combine one chunk of data into the current in-flight hash.
+ ///
+ /// This merges one chunk of data into the hash. First it tries to buffer
+ /// the data. If the buffer is full, it hashes the buffer into its
+ /// hash_state, empties it, and then merges the new chunk in. This also
+ /// handles cases where the data straddles the end of the buffer.
+ template <typename T>
+ char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) {
+ if (!store_and_advance(buffer_ptr, buffer_end, data)) {
+ // Check for skew which prevents the buffer from being packed, and do
+ // a partial store into the buffer to fill it. This is only a concern
+ // with the variadic combine because that formation can have varying
+ // argument types.
+ size_t partial_store_size = buffer_end - buffer_ptr;
+ memcpy(buffer_ptr, &data, partial_store_size);
+
+ // If the store fails, our buffer is full and ready to hash. We have to
+ // either initialize the hash state (on the first full buffer) or mix
+ // this buffer into the existing hash state. Length tracks the *hashed*
+ // length, not the buffered length.
+ if (length == 0) {
+ state = state.create(buffer, seed);
+ length = 64;
+ } else {
+ // Mix this chunk into the current state and bump length up by 64.
+ state.mix(buffer);
+ length += 64;
+ }
+ // Reset the buffer_ptr to the head of the buffer for the next chunk of
+ // data.
+ buffer_ptr = buffer;
+
+ // Try again to store into the buffer -- this cannot fail as we only
+ // store types smaller than the buffer.
+ if (!store_and_advance(buffer_ptr, buffer_end, data,
+ partial_store_size))
+ abort();
+ }
+ return buffer_ptr;
+ }
+
+#if defined(__has_feature) && __has_feature(__cxx_variadic_templates__)
+
+ /// \brief Recursive, variadic combining method.
+ ///
+ /// This function recurses through each argument, combining that argument
+ /// into a single hash.
+ template <typename T, typename ...Ts>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T &arg, const Ts &...args) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg));
+
+ // Recurse to the next argument.
+ return combine(length, buffer_ptr, buffer_end, args...);
+ }
+
+#else
+ // Manually expanded recursive combining methods. See variadic above for
+ // documentation.
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T1 &arg1, const T2 &arg2, const T3 &arg3,
+ const T4 &arg4, const T5 &arg5, const T6 &arg6) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+ return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5, arg6);
+ }
+ template <typename T1, typename T2, typename T3, typename T4, typename T5>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T1 &arg1, const T2 &arg2, const T3 &arg3,
+ const T4 &arg4, const T5 &arg5) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+ return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4, arg5);
+ }
+ template <typename T1, typename T2, typename T3, typename T4>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T1 &arg1, const T2 &arg2, const T3 &arg3,
+ const T4 &arg4) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+ return combine(length, buffer_ptr, buffer_end, arg2, arg3, arg4);
+ }
+ template <typename T1, typename T2, typename T3>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T1 &arg1, const T2 &arg2, const T3 &arg3) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+ return combine(length, buffer_ptr, buffer_end, arg2, arg3);
+ }
+ template <typename T1, typename T2>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T1 &arg1, const T2 &arg2) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+ return combine(length, buffer_ptr, buffer_end, arg2);
+ }
+ template <typename T1>
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end,
+ const T1 &arg1) {
+ buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg1));
+ return combine(length, buffer_ptr, buffer_end);
+ }
+
+#endif
+
+ /// \brief Base case for recursive, variadic combining.
+ ///
+ /// The base case when combining arguments recursively is reached when all
+ /// arguments have been handled. It flushes the remaining buffer and
+ /// constructs a hash_code.
+ hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) {
+ // Check whether the entire set of values fit in the buffer. If so, we'll
+ // use the optimized short hashing routine and skip state entirely.
+ if (length == 0)
+ return hash_short(buffer, buffer_ptr - buffer, seed);
+
+ // Mix the final buffer, rotating it if we did a partial fill in order to
+ // simulate doing a mix of the last 64-bytes. That is how the algorithm
+ // works when we have a contiguous byte sequence, and we want to emulate
+ // that here.
+ std::rotate(buffer, buffer_ptr, buffer_end);
+
+ // Mix this chunk into the current state.
+ state.mix(buffer);
+ length += buffer_ptr - buffer;
+
+ return state.finalize(length);
+ }
+};
+
+} // namespace detail
+} // namespace hashing
+
+
+#if __has_feature(__cxx_variadic_templates__)
+
+/// \brief Combine values into a single hash_code.
+///
+/// This routine accepts a varying number of arguments of any type. It will
+/// attempt to combine them into a single hash_code. For user-defined types it
+/// attempts to call a \see hash_value overload (via ADL) for the type. For
+/// integer and pointer types it directly combines their data into the
+/// resulting hash_code.
+///
+/// The result is suitable for returning from a user's hash_value
+/// *implementation* for their user-defined type. Consumers of a type should
+/// *not* call this routine, they should instead call 'hash_value'.
+template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
+ // Recursively hash each argument using a helper class.
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64, args...);
+}
+
+#else
+
+// What follows are manually exploded overloads for each argument width. See
+// the above variadic definition for documentation and specification.
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
+ const T4 &arg4, const T5 &arg5, const T6 &arg6) {
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64,
+ arg1, arg2, arg3, arg4, arg5, arg6);
+}
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
+ const T4 &arg4, const T5 &arg5) {
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64,
+ arg1, arg2, arg3, arg4, arg5);
+}
+template <typename T1, typename T2, typename T3, typename T4>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3,
+ const T4 &arg4) {
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64,
+ arg1, arg2, arg3, arg4);
+}
+template <typename T1, typename T2, typename T3>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3) {
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2, arg3);
+}
+template <typename T1, typename T2>
+hash_code hash_combine(const T1 &arg1, const T2 &arg2) {
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64, arg1, arg2);
+}
+template <typename T1>
+hash_code hash_combine(const T1 &arg1) {
+ ::llvm::hashing::detail::hash_combine_recursive_helper helper;
+ return helper.combine(0, helper.buffer, helper.buffer + 64, arg1);
+}
+
+#endif
+
+
+// Implementation details for implementatinos of hash_value overloads provided
+// here.
+namespace hashing {
+namespace detail {
+
+/// \brief Helper to hash the value of a single integer.
+///
+/// Overloads for smaller integer types are not provided to ensure consistent
+/// behavior in the presence of integral promotions. Essentially,
+/// "hash_value('4')" and "hash_value('0' + 4)" should be the same.
+inline hash_code hash_integer_value(uint64_t value) {
+ // Similar to hash_4to8_bytes but using a seed instead of length.
+ const uint64_t seed = get_execution_seed();
+ const char *s = reinterpret_cast<const char *>(&value);
+ const uint64_t a = fetch32(s);
+ return hash_16_bytes(seed + (a << 3), fetch32(s + 4));
+}
+
+} // namespace detail
+} // namespace hashing
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T>
+typename enable_if<is_integral_or_enum<T>, hash_code>::type
+hash_value(T value) {
+ return ::llvm::hashing::detail::hash_integer_value(value);
+}
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T> hash_code hash_value(const T *ptr) {
+ return ::llvm::hashing::detail::hash_integer_value(
+ reinterpret_cast<uintptr_t>(ptr));
+}
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T, typename U>
+hash_code hash_value(const std::pair<T, U> &arg) {
+ return hash_combine(arg.first, arg.second);
+}
+
+// Declared and documented above, but defined here so that any of the hashing
+// infrastructure is available.
+template <typename T>
+hash_code hash_value(const std::basic_string<T> &arg) {
+ return hash_combine_range(arg.begin(), arg.end());
+}
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h b/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h
new file mode 100644
index 000000000000..fa7ccb975e52
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ImmutableIntervalMap.h
@@ -0,0 +1,248 @@
+//===--- ImmutableIntervalMap.h - Immutable (functional) 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 defines the ImmutableIntervalMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
+#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
+
+#include "llvm/ADT/ImmutableMap.h"
+
+namespace llvm {
+
+class Interval {
+private:
+ int64_t Start;
+ int64_t End;
+
+public:
+ Interval(int64_t S, int64_t E) : Start(S), End(E) {}
+
+ int64_t getStart() const { return Start; }
+ int64_t getEnd() const { return End; }
+};
+
+template <typename T>
+struct ImutIntervalInfo {
+ typedef const std::pair<Interval, T> value_type;
+ typedef const value_type &value_type_ref;
+ typedef const Interval key_type;
+ typedef const Interval &key_type_ref;
+ typedef const T data_type;
+ typedef const T &data_type_ref;
+
+ static key_type_ref KeyOfValue(value_type_ref V) {
+ return V.first;
+ }
+
+ static data_type_ref DataOfValue(value_type_ref V) {
+ return V.second;
+ }
+
+ static bool isEqual(key_type_ref L, key_type_ref R) {
+ return L.getStart() == R.getStart() && L.getEnd() == R.getEnd();
+ }
+
+ static bool isDataEqual(data_type_ref L, data_type_ref R) {
+ return ImutContainerInfo<T>::isEqual(L,R);
+ }
+
+ static bool isLess(key_type_ref L, key_type_ref R) {
+ // Assume L and R does not overlap.
+ if (L.getStart() < R.getStart()) {
+ assert(L.getEnd() < R.getStart());
+ return true;
+ } else if (L.getStart() == R.getStart()) {
+ assert(L.getEnd() == R.getEnd());
+ return false;
+ } else {
+ assert(L.getStart() > R.getEnd());
+ return false;
+ }
+ }
+
+ static bool isContainedIn(key_type_ref K, key_type_ref L) {
+ if (K.getStart() >= L.getStart() && K.getEnd() <= L.getEnd())
+ return true;
+ else
+ return false;
+ }
+
+ static void Profile(FoldingSetNodeID &ID, value_type_ref V) {
+ ID.AddInteger(V.first.getStart());
+ ID.AddInteger(V.first.getEnd());
+ ImutProfileInfo<T>::Profile(ID, V.second);
+ }
+};
+
+template <typename ImutInfo>
+class ImutIntervalAVLFactory : public ImutAVLFactory<ImutInfo> {
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef typename ImutInfo::value_type value_type;
+ typedef typename ImutInfo::value_type_ref value_type_ref;
+ typedef typename ImutInfo::key_type key_type;
+ typedef typename ImutInfo::key_type_ref key_type_ref;
+ typedef typename ImutInfo::data_type data_type;
+ typedef typename ImutInfo::data_type_ref data_type_ref;
+
+public:
+ ImutIntervalAVLFactory(BumpPtrAllocator &Alloc)
+ : ImutAVLFactory<ImutInfo>(Alloc) {}
+
+ TreeTy *Add(TreeTy *T, value_type_ref V) {
+ T = add_internal(V,T);
+ this->MarkImmutable(T);
+ return T;
+ }
+
+ TreeTy *Find(TreeTy *T, key_type_ref K) {
+ if (!T)
+ return NULL;
+
+ key_type_ref CurrentKey = ImutInfo::KeyOfValue(this->getValue(T));
+
+ if (ImutInfo::isContainedIn(K, CurrentKey))
+ return T;
+ else if (ImutInfo::isLess(K, CurrentKey))
+ return Find(this->getLeft(T), K);
+ else
+ return Find(this->getRight(T), K);
+ }
+
+private:
+ TreeTy *add_internal(value_type_ref V, TreeTy *T) {
+ key_type_ref K = ImutInfo::KeyOfValue(V);
+ T = removeAllOverlaps(T, K);
+ if (this->isEmpty(T))
+ return this->CreateNode(NULL, V, NULL);
+
+ assert(!T->isMutable());
+
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(this->Value(T));
+
+ if (ImutInfo::isLess(K, KCurrent))
+ return this->Balance(add_internal(V, this->Left(T)), this->Value(T),
+ this->Right(T));
+ else
+ return this->Balance(this->Left(T), this->Value(T),
+ add_internal(V, this->Right(T)));
+ }
+
+ // Remove all overlaps from T.
+ TreeTy *removeAllOverlaps(TreeTy *T, key_type_ref K) {
+ bool Changed;
+ do {
+ Changed = false;
+ T = removeOverlap(T, K, Changed);
+ this->markImmutable(T);
+ } while (Changed);
+
+ return T;
+ }
+
+ // Remove one overlap from T.
+ TreeTy *removeOverlap(TreeTy *T, key_type_ref K, bool &Changed) {
+ if (!T)
+ return NULL;
+ Interval CurrentK = ImutInfo::KeyOfValue(this->Value(T));
+
+ // If current key does not overlap the inserted key.
+ if (CurrentK.getStart() > K.getEnd())
+ return this->Balance(removeOverlap(this->Left(T), K, Changed),
+ this->Value(T), this->Right(T));
+ else if (CurrentK.getEnd() < K.getStart())
+ return this->Balance(this->Left(T), this->Value(T),
+ removeOverlap(this->Right(T), K, Changed));
+
+ // Current key overlaps with the inserted key.
+ // Remove the current key.
+ Changed = true;
+ data_type_ref OldData = ImutInfo::DataOfValue(this->Value(T));
+ T = this->Remove_internal(CurrentK, T);
+ // Add back the unoverlapped part of the current key.
+ if (CurrentK.getStart() < K.getStart()) {
+ if (CurrentK.getEnd() <= K.getEnd()) {
+ Interval NewK(CurrentK.getStart(), K.getStart()-1);
+ return add_internal(std::make_pair(NewK, OldData), T);
+ } else {
+ Interval NewK1(CurrentK.getStart(), K.getStart()-1);
+ T = add_internal(std::make_pair(NewK1, OldData), T);
+
+ Interval NewK2(K.getEnd()+1, CurrentK.getEnd());
+ return add_internal(std::make_pair(NewK2, OldData), T);
+ }
+ } else {
+ if (CurrentK.getEnd() > K.getEnd()) {
+ Interval NewK(K.getEnd()+1, CurrentK.getEnd());
+ return add_internal(std::make_pair(NewK, OldData), T);
+ } else
+ return T;
+ }
+ }
+};
+
+/// ImmutableIntervalMap maps an interval [start, end] to a value. The intervals
+/// in the map are guaranteed to be disjoint.
+template <typename ValT>
+class ImmutableIntervalMap
+ : public ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> > {
+
+ typedef typename ImutIntervalInfo<ValT>::value_type value_type;
+ typedef typename ImutIntervalInfo<ValT>::value_type_ref value_type_ref;
+ typedef typename ImutIntervalInfo<ValT>::key_type key_type;
+ typedef typename ImutIntervalInfo<ValT>::key_type_ref key_type_ref;
+ typedef typename ImutIntervalInfo<ValT>::data_type data_type;
+ typedef typename ImutIntervalInfo<ValT>::data_type_ref data_type_ref;
+ typedef ImutAVLTree<ImutIntervalInfo<ValT> > TreeTy;
+
+public:
+ explicit ImmutableIntervalMap(TreeTy *R)
+ : ImmutableMap<Interval, ValT, ImutIntervalInfo<ValT> >(R) {}
+
+ class Factory {
+ ImutIntervalAVLFactory<ImutIntervalInfo<ValT> > F;
+
+ public:
+ Factory(BumpPtrAllocator& Alloc) : F(Alloc) {}
+
+ ImmutableIntervalMap getEmptyMap() {
+ return ImmutableIntervalMap(F.getEmptyTree());
+ }
+
+ ImmutableIntervalMap add(ImmutableIntervalMap Old,
+ key_type_ref K, data_type_ref D) {
+ TreeTy *T = F.add(Old.Root, std::pair<key_type, data_type>(K, D));
+ return ImmutableIntervalMap(F.getCanonicalTree(T));
+ }
+
+ ImmutableIntervalMap remove(ImmutableIntervalMap Old, key_type_ref K) {
+ TreeTy *T = F.remove(Old.Root, K);
+ return ImmutableIntervalMap(F.getCanonicalTree(T));
+ }
+
+ data_type *lookup(ImmutableIntervalMap M, key_type_ref K) {
+ TreeTy *T = F.Find(M.getRoot(), K);
+ if (T)
+ return &T->getValue().second;
+ else
+ return 0;
+ }
+ };
+
+private:
+ // For ImmutableIntervalMap, the lookup operation has to be done by the
+ // factory.
+ data_type* lookup(key_type_ref K) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableList.h b/contrib/llvm/include/llvm/ADT/ImmutableList.h
new file mode 100644
index 000000000000..d7c0074a9f08
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ImmutableList.h
@@ -0,0 +1,230 @@
+//==--- ImmutableList.h - Immutable (functional) list interface --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImmutableList class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMLIST_H
+#define LLVM_ADT_IMLIST_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+template <typename T> class ImmutableListFactory;
+
+template <typename T>
+class ImmutableListImpl : public FoldingSetNode {
+ T Head;
+ const ImmutableListImpl* Tail;
+
+ ImmutableListImpl(const T& head, const ImmutableListImpl* tail = 0)
+ : Head(head), Tail(tail) {}
+
+ friend class ImmutableListFactory<T>;
+
+ // Do not implement.
+ void operator=(const ImmutableListImpl&);
+ ImmutableListImpl(const ImmutableListImpl&);
+
+public:
+ const T& getHead() const { return Head; }
+ const ImmutableListImpl* getTail() const { return Tail; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const T& H,
+ const ImmutableListImpl* L){
+ ID.AddPointer(L);
+ ID.Add(H);
+ }
+
+ void Profile(FoldingSetNodeID& ID) {
+ Profile(ID, Head, Tail);
+ }
+};
+
+/// ImmutableList - This class represents an immutable (functional) list.
+/// It is implemented as a smart pointer (wraps ImmutableListImpl), so it
+/// it is intended to always be copied by value as if it were a pointer.
+/// This interface matches ImmutableSet and ImmutableMap. ImmutableList
+/// objects should almost never be created directly, and instead should
+/// be created by ImmutableListFactory objects that manage the lifetime
+/// of a group of lists. When the factory object is reclaimed, all lists
+/// created by that factory are released as well.
+template <typename T>
+class ImmutableList {
+public:
+ typedef T value_type;
+ typedef ImmutableListFactory<T> Factory;
+
+private:
+ const ImmutableListImpl<T>* X;
+
+public:
+ // This constructor should normally only be called by ImmutableListFactory<T>.
+ // There may be cases, however, when one needs to extract the internal pointer
+ // and reconstruct a list object from that pointer.
+ ImmutableList(const ImmutableListImpl<T>* x = 0) : X(x) {}
+
+ const ImmutableListImpl<T>* getInternalPointer() const {
+ return X;
+ }
+
+ class iterator {
+ const ImmutableListImpl<T>* L;
+ public:
+ iterator() : L(0) {}
+ iterator(ImmutableList l) : L(l.getInternalPointer()) {}
+
+ iterator& operator++() { L = L->getTail(); return *this; }
+ bool operator==(const iterator& I) const { return L == I.L; }
+ bool operator!=(const iterator& I) const { return L != I.L; }
+ const value_type& operator*() const { return L->getHead(); }
+ ImmutableList getList() const { return L; }
+ };
+
+ /// begin - Returns an iterator referring to the head of the list, or
+ /// an iterator denoting the end of the list if the list is empty.
+ iterator begin() const { return iterator(X); }
+
+ /// end - Returns an iterator denoting the end of the list. This iterator
+ /// does not refer to a valid list element.
+ iterator end() const { return iterator(); }
+
+ /// isEmpty - Returns true if the list is empty.
+ bool isEmpty() const { return !X; }
+
+ bool contains(const T& V) const {
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ if (*I == V)
+ return true;
+ }
+ return false;
+ }
+
+ /// isEqual - Returns true if two lists are equal. Because all lists created
+ /// from the same ImmutableListFactory are uniqued, this has O(1) complexity
+ /// because it the contents of the list do not need to be compared. Note
+ /// that you should only compare two lists created from the same
+ /// ImmutableListFactory.
+ bool isEqual(const ImmutableList& L) const { return X == L.X; }
+
+ bool operator==(const ImmutableList& L) const { return isEqual(L); }
+
+ /// getHead - Returns the head of the list.
+ const T& getHead() {
+ assert (!isEmpty() && "Cannot get the head of an empty list.");
+ return X->getHead();
+ }
+
+ /// getTail - Returns the tail of the list, which is another (possibly empty)
+ /// ImmutableList.
+ ImmutableList getTail() {
+ return X ? X->getTail() : 0;
+ }
+
+ void Profile(FoldingSetNodeID& ID) const {
+ ID.AddPointer(X);
+ }
+};
+
+template <typename T>
+class ImmutableListFactory {
+ typedef ImmutableListImpl<T> ListTy;
+ typedef FoldingSet<ListTy> CacheTy;
+
+ CacheTy Cache;
+ uintptr_t Allocator;
+
+ bool ownsAllocator() const {
+ return Allocator & 0x1 ? false : true;
+ }
+
+ BumpPtrAllocator& getAllocator() const {
+ return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+ }
+
+public:
+ ImmutableListFactory()
+ : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+
+ ImmutableListFactory(BumpPtrAllocator& Alloc)
+ : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+
+ ~ImmutableListFactory() {
+ if (ownsAllocator()) delete &getAllocator();
+ }
+
+ ImmutableList<T> concat(const T& Head, ImmutableList<T> Tail) {
+ // Profile the new list to see if it already exists in our cache.
+ FoldingSetNodeID ID;
+ void* InsertPos;
+
+ const ListTy* TailImpl = Tail.getInternalPointer();
+ ListTy::Profile(ID, Head, TailImpl);
+ ListTy* L = Cache.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!L) {
+ // The list does not exist in our cache. Create it.
+ BumpPtrAllocator& A = getAllocator();
+ L = (ListTy*) A.Allocate<ListTy>();
+ new (L) ListTy(Head, TailImpl);
+
+ // Insert the new list into the cache.
+ Cache.InsertNode(L, InsertPos);
+ }
+
+ return L;
+ }
+
+ ImmutableList<T> add(const T& D, ImmutableList<T> L) {
+ return concat(D, L);
+ }
+
+ ImmutableList<T> getEmptyList() const {
+ return ImmutableList<T>(0);
+ }
+
+ ImmutableList<T> create(const T& X) {
+ return Concat(X, getEmptyList());
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Partially-specialized Traits.
+//===----------------------------------------------------------------------===//
+
+template<typename T> struct DenseMapInfo;
+template<typename T> struct DenseMapInfo<ImmutableList<T> > {
+ static inline ImmutableList<T> getEmptyKey() {
+ return reinterpret_cast<ImmutableListImpl<T>*>(-1);
+ }
+ static inline ImmutableList<T> getTombstoneKey() {
+ return reinterpret_cast<ImmutableListImpl<T>*>(-2);
+ }
+ static unsigned getHashValue(ImmutableList<T> X) {
+ uintptr_t PtrVal = reinterpret_cast<uintptr_t>(X.getInternalPointer());
+ return (unsigned((uintptr_t)PtrVal) >> 4) ^
+ (unsigned((uintptr_t)PtrVal) >> 9);
+ }
+ static bool isEqual(ImmutableList<T> X1, ImmutableList<T> X2) {
+ return X1 == X2;
+ }
+};
+
+template <typename T> struct isPodLike;
+template <typename T>
+struct isPodLike<ImmutableList<T> > { static const bool value = true; };
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableMap.h b/contrib/llvm/include/llvm/ADT/ImmutableMap.h
new file mode 100644
index 000000000000..8346ffabff76
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ImmutableMap.h
@@ -0,0 +1,418 @@
+//===--- ImmutableMap.h - Immutable (functional) map interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImmutableMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_IMMAP_H
+#define LLVM_ADT_IMMAP_H
+
+#include "llvm/ADT/ImmutableSet.h"
+
+namespace llvm {
+
+/// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the first
+/// and second elements in a pair are used to generate profile information,
+/// only the first element (the key) is used by isEqual and isLess.
+template <typename T, typename S>
+struct ImutKeyValueInfo {
+ typedef const std::pair<T,S> value_type;
+ typedef const value_type& value_type_ref;
+ typedef const T key_type;
+ typedef const T& key_type_ref;
+ typedef const S data_type;
+ typedef const S& data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref V) {
+ return V.first;
+ }
+
+ static inline data_type_ref DataOfValue(value_type_ref V) {
+ return V.second;
+ }
+
+ static inline bool isEqual(key_type_ref L, key_type_ref R) {
+ return ImutContainerInfo<T>::isEqual(L,R);
+ }
+ static inline bool isLess(key_type_ref L, key_type_ref R) {
+ return ImutContainerInfo<T>::isLess(L,R);
+ }
+
+ static inline bool isDataEqual(data_type_ref L, data_type_ref R) {
+ return ImutContainerInfo<S>::isEqual(L,R);
+ }
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) {
+ ImutContainerInfo<T>::Profile(ID, V.first);
+ ImutContainerInfo<S>::Profile(ID, V.second);
+ }
+};
+
+
+template <typename KeyT, typename ValT,
+ typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMap {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef typename ValInfo::key_type key_type;
+ typedef typename ValInfo::key_type_ref key_type_ref;
+ typedef typename ValInfo::data_type data_type;
+ typedef typename ValInfo::data_type_ref data_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+
+protected:
+ TreeTy* Root;
+
+public:
+ /// Constructs a map from a pointer to a tree root. In general one
+ /// should use a Factory object to create maps instead of directly
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableMap(const ImmutableMap &X) : Root(X.Root) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableMap &operator=(const ImmutableMap &X) {
+ if (Root != X.Root) {
+ if (X.Root) { X.Root->retain(); }
+ if (Root) { Root->release(); }
+ Root = X.Root;
+ }
+ return *this;
+ }
+ ~ImmutableMap() {
+ if (Root) { Root->release(); }
+ }
+
+ class Factory {
+ typename TreeTy::Factory F;
+ const bool Canonicalize;
+
+ public:
+ Factory(bool canonicalize = true)
+ : Canonicalize(canonicalize) {}
+
+ Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
+ : F(Alloc), Canonicalize(canonicalize) {}
+
+ ImmutableMap getEmptyMap() { return ImmutableMap(F.getEmptyTree()); }
+
+ ImmutableMap add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
+ TreeTy *T = F.add(Old.Root, std::pair<key_type,data_type>(K,D));
+ return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
+ }
+
+ ImmutableMap remove(ImmutableMap Old, key_type_ref K) {
+ TreeTy *T = F.remove(Old.Root,K);
+ return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
+ }
+
+ 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
+ };
+
+ bool contains(key_type_ref K) const {
+ return Root ? Root->contains(K) : false;
+ }
+
+ bool operator==(const ImmutableMap &RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(const ImmutableMap &RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ TreeTy *getRoot() const {
+ if (Root) { Root->retain(); }
+ return Root;
+ }
+
+ TreeTy *getRootWithoutRetain() const {
+ return Root;
+ }
+
+ void manualRetain() {
+ if (Root) Root->retain();
+ }
+
+ void manualRelease() {
+ if (Root) Root->release();
+ }
+
+ bool isEmpty() const { return !Root; }
+
+ //===--------------------------------------------------===//
+ // Foreach - A limited form of map iteration.
+ //===--------------------------------------------------===//
+
+private:
+ template <typename Callback>
+ struct CBWrapper {
+ Callback C;
+ void operator()(value_type_ref V) { C(V.first,V.second); }
+ };
+
+ template <typename Callback>
+ struct CBWrapperRef {
+ Callback &C;
+ CBWrapperRef(Callback& c) : C(c) {}
+
+ void operator()(value_type_ref V) { C(V.first,V.second); }
+ };
+
+public:
+ template <typename Callback>
+ void foreach(Callback& C) {
+ if (Root) {
+ CBWrapperRef<Callback> CB(C);
+ Root->foreach(CB);
+ }
+ }
+
+ template <typename Callback>
+ void foreach() {
+ if (Root) {
+ CBWrapper<Callback> CB;
+ Root->foreach(CB);
+ }
+ }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+
+ iterator() {}
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableMap;
+
+ public:
+ value_type_ref operator*() const { return itr->getValue(); }
+ value_type* operator->() const { return &itr->getValue(); }
+
+ key_type_ref getKey() const { return itr->getValue().first; }
+ data_type_ref getData() const { return itr->getValue().second; }
+
+
+ iterator& operator++() { ++itr; return *this; }
+ iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ iterator& operator--() { --itr; return *this; }
+ iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ data_type* lookup(key_type_ref K) const {
+ if (Root) {
+ TreeTy* T = Root->find(K);
+ if (T) return &T->getValue().second;
+ }
+
+ return 0;
+ }
+
+ /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
+ /// which key is the highest in the ordering of keys in the map. This
+ /// method returns NULL if the map is empty.
+ value_type* getMaxElement() const {
+ return Root ? &(Root->getMaxElement()->getValue()) : 0;
+ }
+
+ //===--------------------------------------------------===//
+ // Utility methods.
+ //===--------------------------------------------------===//
+
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
+ ID.AddPointer(M.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID,*this);
+ }
+};
+
+// NOTE: This will possibly become the new implementation of ImmutableMap some day.
+template <typename KeyT, typename ValT,
+typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
+class ImmutableMapRef {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef typename ValInfo::key_type key_type;
+ typedef typename ValInfo::key_type_ref key_type_ref;
+ typedef typename ValInfo::data_type data_type;
+ typedef typename ValInfo::data_type_ref data_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+ typedef typename TreeTy::Factory FactoryTy;
+
+protected:
+ TreeTy *Root;
+ FactoryTy *Factory;
+
+public:
+ /// Constructs a map from a pointer to a tree root. In general one
+ /// should use a Factory object to create maps instead of directly
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F)
+ : Root(const_cast<TreeTy*>(R)),
+ Factory(F) {
+ if (Root) { Root->retain(); }
+ }
+
+ ImmutableMapRef(const ImmutableMapRef &X)
+ : Root(X.Root),
+ Factory(X.Factory) {
+ if (Root) { Root->retain(); }
+ }
+
+ ImmutableMapRef &operator=(const ImmutableMapRef &X) {
+ if (Root != X.Root) {
+ if (X.Root)
+ X.Root->retain();
+
+ if (Root)
+ Root->release();
+
+ Root = X.Root;
+ Factory = X.Factory;
+ }
+ return *this;
+ }
+
+ ~ImmutableMapRef() {
+ if (Root)
+ Root->release();
+ }
+
+ static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
+ return ImmutableMapRef(0, F);
+ }
+
+ ImmutableMapRef add(key_type_ref K, data_type_ref D) {
+ TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
+ return ImmutableMapRef(NewT, Factory);
+ }
+
+ ImmutableMapRef remove(key_type_ref K) {
+ TreeTy *NewT = Factory->remove(Root, K);
+ return ImmutableMapRef(NewT, Factory);
+ }
+
+ bool contains(key_type_ref K) const {
+ return Root ? Root->contains(K) : false;
+ }
+
+ ImmutableMap<KeyT, ValT> asImmutableMap() const {
+ return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root));
+ }
+
+ bool operator==(const ImmutableMapRef &RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(const ImmutableMapRef &RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ bool isEmpty() const { return !Root; }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ void verify() const { if (Root) Root->verify(); }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+
+ iterator() {}
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableMapRef;
+
+ public:
+ value_type_ref operator*() const { return itr->getValue(); }
+ value_type* operator->() const { return &itr->getValue(); }
+
+ key_type_ref getKey() const { return itr->getValue().first; }
+ data_type_ref getData() const { return itr->getValue().second; }
+
+
+ iterator& operator++() { ++itr; return *this; }
+ iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ iterator& operator--() { --itr; return *this; }
+ iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
+ };
+
+ iterator begin() const { return iterator(Root); }
+ iterator end() const { return iterator(); }
+
+ data_type* lookup(key_type_ref K) const {
+ if (Root) {
+ TreeTy* T = Root->find(K);
+ if (T) return &T->getValue().second;
+ }
+
+ return 0;
+ }
+
+ /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
+ /// which key is the highest in the ordering of keys in the map. This
+ /// method returns NULL if the map is empty.
+ value_type* getMaxElement() const {
+ return Root ? &(Root->getMaxElement()->getValue()) : 0;
+ }
+
+ //===--------------------------------------------------===//
+ // Utility methods.
+ //===--------------------------------------------------===//
+
+ unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+
+ static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) {
+ ID.AddPointer(M.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID, *this);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ImmutableSet.h b/contrib/llvm/include/llvm/ADT/ImmutableSet.h
new file mode 100644
index 000000000000..89b164819d37
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ImmutableSet.h
@@ -0,0 +1,1224 @@
+//===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ImutAVLTree and ImmutableSet classes.
+//
+//===----------------------------------------------------------------------===//
+
+#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/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <functional>
+#include <vector>
+#include <stdio.h>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Definition.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo> class ImutAVLFactory;
+template <typename ImutInfo> class ImutIntervalAVLFactory;
+template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
+template <typename ImutInfo> class ImutAVLTreeGenericIterator;
+
+template <typename ImutInfo >
+class ImutAVLTree {
+public:
+ typedef typename ImutInfo::key_type_ref key_type_ref;
+ typedef typename ImutInfo::value_type value_type;
+ typedef typename ImutInfo::value_type_ref value_type_ref;
+
+ typedef ImutAVLFactory<ImutInfo> Factory;
+ friend class ImutAVLFactory<ImutInfo>;
+ friend class ImutIntervalAVLFactory<ImutInfo>;
+
+ friend class ImutAVLTreeGenericIterator<ImutInfo>;
+
+ typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator;
+
+ //===----------------------------------------------------===//
+ // Public Interface.
+ //===----------------------------------------------------===//
+
+ /// Return a pointer to the left subtree. This value
+ /// is NULL if there is no left subtree.
+ ImutAVLTree *getLeft() const { return left; }
+
+ /// Return a pointer to the right subtree. This value is
+ /// NULL if there is no right subtree.
+ ImutAVLTree *getRight() const { return right; }
+
+ /// getHeight - Returns the height of the tree. A tree with no subtrees
+ /// has a height of 1.
+ unsigned getHeight() const { return height; }
+
+ /// getValue - Returns the data value associated with the tree node.
+ const value_type& getValue() const { return value; }
+
+ /// find - Finds the subtree associated with the specified key value.
+ /// This method returns NULL if no matching subtree is found.
+ ImutAVLTree* find(key_type_ref K) {
+ ImutAVLTree *T = this;
+ while (T) {
+ key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
+ if (ImutInfo::isEqual(K,CurrentKey))
+ return T;
+ else if (ImutInfo::isLess(K,CurrentKey))
+ T = T->getLeft();
+ else
+ T = T->getRight();
+ }
+ 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(); }
+ return T;
+ }
+
+ /// size - Returns the number of nodes in the tree, which includes
+ /// both leaves and non-leaf nodes.
+ unsigned size() const {
+ unsigned n = 1;
+ if (const ImutAVLTree* L = getLeft())
+ n += L->size();
+ if (const ImutAVLTree* R = getRight())
+ n += R->size();
+ return n;
+ }
+
+ /// begin - Returns an iterator that iterates over the nodes of the tree
+ /// in an inorder traversal. The returned iterator thus refers to the
+ /// the tree node with the minimum data element.
+ iterator begin() const { return iterator(this); }
+
+ /// end - Returns an iterator for the tree that denotes the end of an
+ /// inorder traversal.
+ iterator end() const { return iterator(); }
+
+ bool isElementEqual(value_type_ref V) const {
+ // Compare the keys.
+ if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(V)))
+ return false;
+
+ // Also compare the data values.
+ if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()),
+ ImutInfo::DataOfValue(V)))
+ return false;
+
+ return true;
+ }
+
+ bool isElementEqual(const ImutAVLTree* RHS) const {
+ return isElementEqual(RHS->getValue());
+ }
+
+ /// isEqual - Compares two trees for structural equality and returns true
+ /// if they are equal. This worst case performance of this operation is
+ // linear in the sizes of the trees.
+ bool isEqual(const ImutAVLTree& RHS) const {
+ if (&RHS == this)
+ return true;
+
+ iterator LItr = begin(), LEnd = end();
+ iterator RItr = RHS.begin(), REnd = RHS.end();
+
+ while (LItr != LEnd && RItr != REnd) {
+ if (*LItr == *RItr) {
+ LItr.skipSubTree();
+ RItr.skipSubTree();
+ continue;
+ }
+
+ if (!LItr->isElementEqual(*RItr))
+ return false;
+
+ ++LItr;
+ ++RItr;
+ }
+
+ return LItr == LEnd && RItr == REnd;
+ }
+
+ /// isNotEqual - Compares two trees for structural inequality. Performance
+ /// is the same is isEqual.
+ bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
+
+ /// contains - Returns true if this tree contains a subtree (node) that
+ /// has an data element that matches the specified key. Complexity
+ /// is logarithmic in the size of the tree.
+ bool contains(key_type_ref K) { return (bool) find(K); }
+
+ /// foreach - A member template the accepts invokes operator() on a functor
+ /// object (specifed by Callback) for every node/subtree in the tree.
+ /// Nodes are visited using an inorder traversal.
+ template <typename Callback>
+ void foreach(Callback& C) {
+ if (ImutAVLTree* L = getLeft())
+ L->foreach(C);
+
+ C(value);
+
+ if (ImutAVLTree* R = getRight())
+ R->foreach(C);
+ }
+
+ /// validateTree - A utility method that checks that the balancing and
+ /// ordering invariants of the tree are satisifed. It is a recursive
+ /// method that returns the height of the tree, which is then consumed
+ /// by the enclosing validateTree call. External callers should ignore the
+ /// return value. An invalid tree will cause an assertion to fire in
+ /// a debug build.
+ unsigned validateTree() const {
+ unsigned HL = getLeft() ? getLeft()->validateTree() : 0;
+ unsigned HR = getRight() ? getRight()->validateTree() : 0;
+ (void) HL;
+ (void) HR;
+
+ assert(getHeight() == ( HL > HR ? HL : HR ) + 1
+ && "Height calculation wrong");
+
+ assert((HL > HR ? HL-HR : HR-HL) <= 2
+ && "Balancing invariant violated");
+
+ assert((!getLeft() ||
+ ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
+ ImutInfo::KeyOfValue(getValue()))) &&
+ "Value in left child is not less that current value");
+
+
+ assert(!(getRight() ||
+ ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
+ ImutInfo::KeyOfValue(getRight()->getValue()))) &&
+ "Current value is not less that value of right child");
+
+ return getHeight();
+ }
+
+ //===----------------------------------------------------===//
+ // Internal values.
+ //===----------------------------------------------------===//
+
+private:
+ Factory *factory;
+ ImutAVLTree *left;
+ ImutAVLTree *right;
+ ImutAVLTree *prev;
+ ImutAVLTree *next;
+
+ unsigned height : 28;
+ unsigned IsMutable : 1;
+ unsigned IsDigestCached : 1;
+ unsigned IsCanonicalized : 1;
+
+ value_type value;
+ uint32_t digest;
+ uint32_t refCount;
+
+ //===----------------------------------------------------===//
+ // Internal methods (node manipulation; used by Factory).
+ //===----------------------------------------------------===//
+
+private:
+ /// ImutAVLTree - Internal constructor that is only called by
+ /// ImutAVLFactory.
+ ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
+ unsigned height)
+ : factory(f), left(l), right(r), prev(0), next(0), height(height),
+ IsMutable(true), IsDigestCached(false), IsCanonicalized(0),
+ value(v), digest(0), refCount(0)
+ {
+ if (left) left->retain();
+ if (right) right->retain();
+ }
+
+ /// isMutable - Returns true if the left and right subtree references
+ /// (as well as height) can be changed. If this method returns false,
+ /// the tree is truly immutable. Trees returned from an ImutAVLFactory
+ /// object should always have this method return true. Further, if this
+ /// method returns false for an instance of ImutAVLTree, all subtrees
+ /// will also have this method return false. The converse is not true.
+ bool isMutable() const { return 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; }
+
+ //===----------------------------------------------------===//
+ // Mutating operations. A tree root can be manipulated as
+ // long as its reference has not "escaped" from internal
+ // methods of a factory object (see below). When a tree
+ // pointer is externally viewable by client code, the
+ // internal "mutable bit" is cleared to mark the tree
+ // immutable. Note that a tree that still has its mutable
+ // bit set may have children (subtrees) that are themselves
+ // immutable.
+ //===----------------------------------------------------===//
+
+ /// markImmutable - Clears the mutable flag for a tree. After this happens,
+ /// it is an error to call setLeft(), setRight(), and setHeight().
+ void markImmutable() {
+ assert(isMutable() && "Mutable flag already removed.");
+ IsMutable = false;
+ }
+
+ /// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
+ void markedCachedDigest() {
+ assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
+ IsDigestCached = true;
+ }
+
+ /// setHeight - Changes the height of the tree. Used internally by
+ /// ImutAVLFactory.
+ void setHeight(unsigned h) {
+ assert(isMutable() && "Only a mutable tree can have its height changed.");
+ height = h;
+ }
+
+ static inline
+ uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+ uint32_t digest = 0;
+
+ if (L)
+ digest += L->computeDigest();
+
+ // Compute digest of stored data.
+ FoldingSetNodeID ID;
+ ImutInfo::Profile(ID,V);
+ digest += ID.ComputeHash();
+
+ if (R)
+ digest += R->computeDigest();
+
+ return digest;
+ }
+
+ inline uint32_t computeDigest() {
+ // Check the lowest bit to determine if digest has actually been
+ // pre-computed.
+ if (hasCachedDigest())
+ return digest;
+
+ uint32_t X = computeDigest(getLeft(), getRight(), getValue());
+ digest = X;
+ markedCachedDigest();
+ return X;
+ }
+
+ //===----------------------------------------------------===//
+ // Reference count operations.
+ //===----------------------------------------------------===//
+
+public:
+ void retain() { ++refCount; }
+ void release() {
+ assert(refCount > 0);
+ if (--refCount == 0)
+ destroy();
+ }
+ void destroy() {
+ if (left)
+ left->release();
+ if (right)
+ right->release();
+ if (IsCanonicalized) {
+ if (next)
+ next->prev = prev;
+
+ if (prev)
+ prev->next = next;
+ 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;
+ factory->freeNodes.push_back(this);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Factory class.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo >
+class ImutAVLFactory {
+ friend class ImutAVLTree<ImutInfo>;
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef typename TreeTy::value_type_ref value_type_ref;
+ typedef typename TreeTy::key_type_ref key_type_ref;
+
+ typedef DenseMap<unsigned, TreeTy*> CacheTy;
+
+ CacheTy Cache;
+ uintptr_t Allocator;
+ std::vector<TreeTy*> createdNodes;
+ std::vector<TreeTy*> freeNodes;
+
+ bool ownsAllocator() const {
+ return Allocator & 0x1 ? false : true;
+ }
+
+ BumpPtrAllocator& getAllocator() const {
+ return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+ }
+
+ //===--------------------------------------------------===//
+ // Public interface.
+ //===--------------------------------------------------===//
+
+public:
+ ImutAVLFactory()
+ : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+
+ ImutAVLFactory(BumpPtrAllocator& Alloc)
+ : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+
+ ~ImutAVLFactory() {
+ if (ownsAllocator()) delete &getAllocator();
+ }
+
+ TreeTy* add(TreeTy* T, value_type_ref V) {
+ T = add_internal(V,T);
+ markImmutable(T);
+ recoverNodes();
+ return T;
+ }
+
+ TreeTy* remove(TreeTy* T, key_type_ref V) {
+ T = remove_internal(V,T);
+ markImmutable(T);
+ recoverNodes();
+ return T;
+ }
+
+ TreeTy* getEmptyTree() const { return NULL; }
+
+protected:
+
+ //===--------------------------------------------------===//
+ // A bunch of quick helper functions used for reasoning
+ // about the properties of trees and their children.
+ // These have succinct names so that the balancing code
+ // is as terse (and readable) as possible.
+ //===--------------------------------------------------===//
+
+ bool isEmpty(TreeTy* T) const { return !T; }
+ unsigned getHeight(TreeTy* T) const { return T ? T->getHeight() : 0; }
+ TreeTy* getLeft(TreeTy* T) const { return T->getLeft(); }
+ TreeTy* getRight(TreeTy* T) const { return T->getRight(); }
+ value_type_ref getValue(TreeTy* T) const { return T->value; }
+
+ // Make sure the index is not the Tombstone or Entry key of the DenseMap.
+ static inline unsigned maskCacheIndex(unsigned I) {
+ return (I & ~0x02);
+ }
+
+ unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
+ unsigned hl = getHeight(L);
+ unsigned hr = getHeight(R);
+ return (hl > hr ? hl : hr) + 1;
+ }
+
+ static bool compareTreeWithSection(TreeTy* T,
+ typename TreeTy::iterator& TI,
+ typename TreeTy::iterator& TE) {
+ typename TreeTy::iterator I = T->begin(), E = T->end();
+ for ( ; I!=E ; ++I, ++TI) {
+ if (TI == TE || !I->isElementEqual(*TI))
+ return false;
+ }
+ return true;
+ }
+
+ //===--------------------------------------------------===//
+ // "createNode" is used to generate new tree roots that link
+ // to other trees. The functon may also simply move links
+ // in an existing root if that root is still marked mutable.
+ // This is necessary because otherwise our balancing code
+ // would leak memory as it would create nodes that are
+ // then discarded later before the finished tree is
+ // returned to the caller.
+ //===--------------------------------------------------===//
+
+ TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
+ BumpPtrAllocator& A = getAllocator();
+ TreeTy* T;
+ if (!freeNodes.empty()) {
+ T = freeNodes.back();
+ freeNodes.pop_back();
+ assert(T != L);
+ assert(T != R);
+ }
+ else {
+ T = (TreeTy*) A.Allocate<TreeTy>();
+ }
+ new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
+ createdNodes.push_back(T);
+ return T;
+ }
+
+ TreeTy* createNode(TreeTy* newLeft, TreeTy* oldTree, TreeTy* newRight) {
+ return createNode(newLeft, getValue(oldTree), newRight);
+ }
+
+ void recoverNodes() {
+ for (unsigned i = 0, n = createdNodes.size(); i < n; ++i) {
+ TreeTy *N = createdNodes[i];
+ if (N->isMutable() && N->refCount == 0)
+ N->destroy();
+ }
+ createdNodes.clear();
+ }
+
+ /// balanceTree - Used by add_internal and remove_internal to
+ /// balance a newly created tree.
+ TreeTy* balanceTree(TreeTy* L, value_type_ref V, TreeTy* R) {
+ unsigned hl = getHeight(L);
+ unsigned hr = getHeight(R);
+
+ if (hl > hr + 2) {
+ assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2");
+
+ TreeTy *LL = getLeft(L);
+ TreeTy *LR = getRight(L);
+
+ if (getHeight(LL) >= getHeight(LR))
+ return createNode(LL, L, createNode(LR,V,R));
+
+ assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1");
+
+ TreeTy *LRL = getLeft(LR);
+ TreeTy *LRR = getRight(LR);
+
+ return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
+ }
+ else if (hr > hl + 2) {
+ assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
+
+ TreeTy *RL = getLeft(R);
+ TreeTy *RR = getRight(R);
+
+ if (getHeight(RR) >= getHeight(RL))
+ return createNode(createNode(L,V,RL), R, RR);
+
+ assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1");
+
+ TreeTy *RLL = getLeft(RL);
+ TreeTy *RLR = getRight(RL);
+
+ return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
+ }
+ else
+ return createNode(L,V,R);
+ }
+
+ /// add_internal - Creates a new tree that includes the specified
+ /// data and the data from the original tree. If the original tree
+ /// already contained the data item, the original tree is returned.
+ TreeTy* add_internal(value_type_ref V, TreeTy* T) {
+ if (isEmpty(T))
+ return createNode(T, V, T);
+ assert(!T->isMutable());
+
+ key_type_ref K = ImutInfo::KeyOfValue(V);
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
+
+ if (ImutInfo::isEqual(K,KCurrent))
+ return createNode(getLeft(T), V, getRight(T));
+ else if (ImutInfo::isLess(K,KCurrent))
+ return balanceTree(add_internal(V, getLeft(T)), getValue(T), getRight(T));
+ else
+ return balanceTree(getLeft(T), getValue(T), add_internal(V, getRight(T)));
+ }
+
+ /// remove_internal - Creates a new tree that includes all the data
+ /// from the original tree except the specified data. If the
+ /// specified data did not exist in the original tree, the original
+ /// tree is returned.
+ TreeTy* remove_internal(key_type_ref K, TreeTy* T) {
+ if (isEmpty(T))
+ return T;
+
+ assert(!T->isMutable());
+
+ key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
+
+ if (ImutInfo::isEqual(K,KCurrent)) {
+ return combineTrees(getLeft(T), getRight(T));
+ } else if (ImutInfo::isLess(K,KCurrent)) {
+ return balanceTree(remove_internal(K, getLeft(T)),
+ getValue(T), getRight(T));
+ } else {
+ return balanceTree(getLeft(T), getValue(T),
+ remove_internal(K, getRight(T)));
+ }
+ }
+
+ TreeTy* combineTrees(TreeTy* L, TreeTy* R) {
+ if (isEmpty(L))
+ return R;
+ if (isEmpty(R))
+ return L;
+ TreeTy* OldNode;
+ TreeTy* newRight = removeMinBinding(R,OldNode);
+ return balanceTree(L, getValue(OldNode), newRight);
+ }
+
+ TreeTy* removeMinBinding(TreeTy* T, TreeTy*& Noderemoved) {
+ assert(!isEmpty(T));
+ if (isEmpty(getLeft(T))) {
+ Noderemoved = T;
+ return getRight(T);
+ }
+ return balanceTree(removeMinBinding(getLeft(T), Noderemoved),
+ getValue(T), getRight(T));
+ }
+
+ /// markImmutable - Clears the mutable bits of a root and all of its
+ /// descendants.
+ void markImmutable(TreeTy* T) {
+ if (!T || !T->isMutable())
+ return;
+ T->markImmutable();
+ markImmutable(getLeft(T));
+ markImmutable(getRight(T));
+ }
+
+public:
+ TreeTy *getCanonicalTree(TreeTy *TNew) {
+ if (!TNew)
+ return 0;
+
+ if (TNew->IsCanonicalized)
+ return TNew;
+
+ // Search the hashtable for another tree with the same digest, and
+ // if find a collision compare those trees by their contents.
+ unsigned digest = TNew->computeDigest();
+ TreeTy *&entry = Cache[maskCacheIndex(digest)];
+ do {
+ if (!entry)
+ break;
+ for (TreeTy *T = entry ; T != 0; T = T->next) {
+ // Compare the Contents('T') with Contents('TNew')
+ typename TreeTy::iterator TI = T->begin(), TE = T->end();
+ if (!compareTreeWithSection(TNew, TI, TE))
+ continue;
+ if (TI != TE)
+ continue; // T has more contents than TNew.
+ // Trees did match! Return 'T'.
+ if (TNew->refCount == 0)
+ TNew->destroy();
+ return T;
+ }
+ entry->prev = TNew;
+ TNew->next = entry;
+ }
+ while (false);
+
+ entry = TNew;
+ TNew->IsCanonicalized = true;
+ return TNew;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable AVL-Tree Iterators.
+//===----------------------------------------------------------------------===//
+
+template <typename ImutInfo>
+class ImutAVLTreeGenericIterator {
+ SmallVector<uintptr_t,20> stack;
+public:
+ enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
+ Flags=0x3 };
+
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
+
+ inline ImutAVLTreeGenericIterator() {}
+ inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
+ if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
+ }
+
+ TreeTy* operator*() const {
+ assert(!stack.empty());
+ return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ }
+
+ uintptr_t getVisitState() {
+ assert(!stack.empty());
+ return stack.back() & Flags;
+ }
+
+
+ bool atEnd() const { return stack.empty(); }
+
+ bool atBeginning() const {
+ return stack.size() == 1 && getVisitState() == VisitedNone;
+ }
+
+ void skipToParent() {
+ assert(!stack.empty());
+ stack.pop_back();
+ if (stack.empty())
+ return;
+ switch (getVisitState()) {
+ case VisitedNone:
+ stack.back() |= VisitedLeft;
+ break;
+ case VisitedLeft:
+ stack.back() |= VisitedRight;
+ break;
+ default:
+ llvm_unreachable("Unreachable.");
+ }
+ }
+
+ inline bool operator==(const _Self& x) const {
+ if (stack.size() != x.stack.size())
+ return false;
+ for (unsigned i = 0 ; i < stack.size(); i++)
+ if (stack[i] != x.stack[i])
+ return false;
+ return true;
+ }
+
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ _Self& operator++() {
+ assert(!stack.empty());
+ TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ assert(Current);
+ switch (getVisitState()) {
+ case VisitedNone:
+ if (TreeTy* L = Current->getLeft())
+ stack.push_back(reinterpret_cast<uintptr_t>(L));
+ else
+ stack.back() |= VisitedLeft;
+ break;
+ case VisitedLeft:
+ if (TreeTy* R = Current->getRight())
+ stack.push_back(reinterpret_cast<uintptr_t>(R));
+ else
+ stack.back() |= VisitedRight;
+ break;
+ case VisitedRight:
+ skipToParent();
+ break;
+ default:
+ llvm_unreachable("Unreachable.");
+ }
+ return *this;
+ }
+
+ _Self& operator--() {
+ assert(!stack.empty());
+ TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ assert(Current);
+ switch (getVisitState()) {
+ case VisitedNone:
+ stack.pop_back();
+ break;
+ case VisitedLeft:
+ stack.back() &= ~Flags; // Set state to "VisitedNone."
+ if (TreeTy* L = Current->getLeft())
+ stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
+ break;
+ case VisitedRight:
+ stack.back() &= ~Flags;
+ stack.back() |= VisitedLeft;
+ if (TreeTy* R = Current->getRight())
+ stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
+ break;
+ default:
+ llvm_unreachable("Unreachable.");
+ }
+ return *this;
+ }
+};
+
+template <typename ImutInfo>
+class ImutAVLTreeInOrderIterator {
+ typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
+ InternalIteratorTy InternalItr;
+
+public:
+ typedef ImutAVLTree<ImutInfo> TreeTy;
+ typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
+
+ ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
+ if (Root) operator++(); // Advance to first element.
+ }
+
+ ImutAVLTreeInOrderIterator() : InternalItr() {}
+
+ inline bool operator==(const _Self& x) const {
+ return InternalItr == x.InternalItr;
+ }
+
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline TreeTy* operator*() const { return *InternalItr; }
+ inline TreeTy* operator->() const { return *InternalItr; }
+
+ inline _Self& operator++() {
+ do ++InternalItr;
+ while (!InternalItr.atEnd() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+ return *this;
+ }
+
+ inline _Self& operator--() {
+ do --InternalItr;
+ while (!InternalItr.atBeginning() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+ return *this;
+ }
+
+ inline void skipSubTree() {
+ InternalItr.skipToParent();
+
+ while (!InternalItr.atEnd() &&
+ InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
+ ++InternalItr;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes for Profile information.
+//===----------------------------------------------------------------------===//
+
+/// Generic profile template. The default behavior is to invoke the
+/// profile method of an object. Specializations for primitive integers
+/// and generic handling of pointers is done below.
+template <typename T>
+struct ImutProfileInfo {
+ typedef const T value_type;
+ typedef const T& value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ FoldingSetTrait<T>::Profile(X,ID);
+ }
+};
+
+/// Profile traits for integers.
+template <typename T>
+struct ImutProfileInteger {
+ typedef const T value_type;
+ typedef const T& value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ ID.AddInteger(X);
+ }
+};
+
+#define PROFILE_INTEGER_INFO(X)\
+template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
+
+PROFILE_INTEGER_INFO(char)
+PROFILE_INTEGER_INFO(unsigned char)
+PROFILE_INTEGER_INFO(short)
+PROFILE_INTEGER_INFO(unsigned short)
+PROFILE_INTEGER_INFO(unsigned)
+PROFILE_INTEGER_INFO(signed)
+PROFILE_INTEGER_INFO(long)
+PROFILE_INTEGER_INFO(unsigned long)
+PROFILE_INTEGER_INFO(long long)
+PROFILE_INTEGER_INFO(unsigned long long)
+
+#undef PROFILE_INTEGER_INFO
+
+/// Generic profile trait for pointer types. We treat pointers as
+/// references to unique objects.
+template <typename T>
+struct ImutProfileInfo<T*> {
+ typedef const T* value_type;
+ typedef value_type value_type_ref;
+
+ static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
+ ID.AddPointer(X);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Trait classes that contain element comparison operators and type
+// definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap. These
+// inherit from the profile traits (ImutProfileInfo) to include operations
+// for element profiling.
+//===----------------------------------------------------------------------===//
+
+
+/// ImutContainerInfo - Generic definition of comparison operations for
+/// elements of immutable containers that defaults to using
+/// std::equal_to<> and std::less<> to perform comparison of elements.
+template <typename T>
+struct ImutContainerInfo : public ImutProfileInfo<T> {
+ typedef typename ImutProfileInfo<T>::value_type value_type;
+ typedef typename ImutProfileInfo<T>::value_type_ref value_type_ref;
+ typedef value_type key_type;
+ typedef value_type_ref key_type_ref;
+ typedef bool data_type;
+ typedef bool data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+ static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+
+ static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ return std::equal_to<key_type>()(LHS,RHS);
+ }
+
+ static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ return std::less<key_type>()(LHS,RHS);
+ }
+
+ static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+};
+
+/// ImutContainerInfo - Specialization for pointer values to treat pointers
+/// as references to unique objects. Pointers are thus compared by
+/// their addresses.
+template <typename T>
+struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
+ typedef typename ImutProfileInfo<T*>::value_type value_type;
+ typedef typename ImutProfileInfo<T*>::value_type_ref value_type_ref;
+ typedef value_type key_type;
+ typedef value_type_ref key_type_ref;
+ typedef bool data_type;
+ typedef bool data_type_ref;
+
+ static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
+ static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+
+ static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ return LHS == RHS;
+ }
+
+ static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ return LHS < RHS;
+ }
+
+ static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Immutable Set
+//===----------------------------------------------------------------------===//
+
+template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
+class ImmutableSet {
+public:
+ typedef typename ValInfo::value_type value_type;
+ typedef typename ValInfo::value_type_ref value_type_ref;
+ typedef ImutAVLTree<ValInfo> TreeTy;
+
+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
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableSet(TreeTy* R) : Root(R) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSet(const ImmutableSet &X) : Root(X.Root) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSet &operator=(const ImmutableSet &X) {
+ if (Root != X.Root) {
+ if (X.Root) { X.Root->retain(); }
+ if (Root) { Root->release(); }
+ Root = X.Root;
+ }
+ return *this;
+ }
+ ~ImmutableSet() {
+ if (Root) { Root->release(); }
+ }
+
+ class Factory {
+ typename TreeTy::Factory F;
+ const bool Canonicalize;
+
+ public:
+ Factory(bool canonicalize = true)
+ : Canonicalize(canonicalize) {}
+
+ Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
+ : F(Alloc), Canonicalize(canonicalize) {}
+
+ /// getEmptySet - Returns an immutable set that contains no elements.
+ ImmutableSet getEmptySet() {
+ return ImmutableSet(F.getEmptyTree());
+ }
+
+ /// add - Creates a new immutable set that contains all of the values
+ /// of the original set with the addition of the specified value. If
+ /// the original set already included the value, then the original set is
+ /// returned and no memory is allocated. The time and space complexity
+ /// of this operation is logarithmic in the size of the original set.
+ /// The memory allocated to represent the set is released when the
+ /// factory object that created the set is destroyed.
+ ImmutableSet add(ImmutableSet Old, value_type_ref V) {
+ TreeTy *NewT = F.add(Old.Root, V);
+ return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
+ }
+
+ /// remove - Creates a new immutable set that contains all of the values
+ /// of the original set with the exception of the specified value. If
+ /// the original set did not contain the value, the original set is
+ /// returned and no memory is allocated. The time and space complexity
+ /// of this operation is logarithmic in the size of the original set.
+ /// The memory allocated to represent the set is released when the
+ /// factory object that created the set is destroyed.
+ ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
+ TreeTy *NewT = F.remove(Old.Root, V);
+ return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
+ }
+
+ BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
+
+ 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
+ };
+
+ friend class Factory;
+
+ /// Returns true if the set contains the specified value.
+ bool contains(value_type_ref V) const {
+ return Root ? Root->contains(V) : false;
+ }
+
+ bool operator==(const ImmutableSet &RHS) const {
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ }
+
+ bool operator!=(const ImmutableSet &RHS) const {
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ }
+
+ TreeTy *getRoot() {
+ if (Root) { Root->retain(); }
+ return Root;
+ }
+
+ TreeTy *getRootWithoutRetain() const {
+ return 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; }
+
+ template <typename Callback>
+ void foreach(Callback& C) { if (Root) Root->foreach(C); }
+
+ template <typename Callback>
+ void foreach() { if (Root) { Callback C; Root->foreach(C); } }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableSet<ValT,ValInfo>;
+ public:
+ iterator() {}
+ inline value_type_ref operator*() const { return itr->getValue(); }
+ inline iterator& operator++() { ++itr; return *this; }
+ inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ inline iterator& operator--() { --itr; return *this; }
+ inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ 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 ImmutableSet& S) {
+ ID.AddPointer(S.Root);
+ }
+
+ inline void Profile(FoldingSetNodeID& ID) const {
+ return Profile(ID,*this);
+ }
+
+ //===--------------------------------------------------===//
+ // For testing.
+ //===--------------------------------------------------===//
+
+ 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 {
+public:
+ typedef typename ValInfo::value_type value_type;
+ 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
+ /// invoking the constructor, but there are cases where make this
+ /// constructor public is useful.
+ explicit ImmutableSetRef(TreeTy* R, FactoryTy *F)
+ : Root(R),
+ Factory(F) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSetRef(const ImmutableSetRef &X)
+ : Root(X.Root),
+ Factory(X.Factory) {
+ if (Root) { Root->retain(); }
+ }
+ ImmutableSetRef &operator=(const ImmutableSetRef &X) {
+ if (Root != X.Root) {
+ if (X.Root) { X.Root->retain(); }
+ if (Root) { Root->release(); }
+ Root = X.Root;
+ Factory = X.Factory;
+ }
+ return *this;
+ }
+ ~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; }
+
+ //===--------------------------------------------------===//
+ // Iterators.
+ //===--------------------------------------------------===//
+
+ class iterator {
+ typename TreeTy::iterator itr;
+ iterator(TreeTy* t) : itr(t) {}
+ friend class ImmutableSetRef<ValT,ValInfo>;
+ public:
+ iterator() {}
+ inline value_type_ref operator*() const { return itr->getValue(); }
+ inline iterator& operator++() { ++itr; return *this; }
+ inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ inline iterator& operator--() { --itr; return *this; }
+ inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+ inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ 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(); }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/InMemoryStruct.h b/contrib/llvm/include/llvm/ADT/InMemoryStruct.h
new file mode 100644
index 000000000000..a56084501a62
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/InMemoryStruct.h
@@ -0,0 +1,77 @@
+//===- InMemoryStruct.h - Indirect Struct Access Smart Pointer --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INMEMORYSTRUCT_H
+#define LLVM_ADT_INMEMORYSTRUCT_H
+
+#include <cassert>
+
+namespace llvm {
+
+/// \brief Helper object for abstracting access to an in-memory structure which
+/// may require some kind of temporary storage.
+///
+/// This class is designed to be used for accessing file data structures which
+/// in the common case can be accessed from a direct pointer to a memory mapped
+/// object, but which in some cases may require indirect access to a temporary
+/// structure (which, for example, may have undergone endianness translation).
+template<typename T>
+class InMemoryStruct {
+ typedef T value_type;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+ typedef const value_type &const_reference;
+ typedef const value_type *const_pointer;
+
+ /// \brief The smart pointer target.
+ value_type *Target;
+
+ /// \brief A temporary object which can be used as a target of the smart
+ /// pointer.
+ value_type Contents;
+
+private:
+
+public:
+ InMemoryStruct() : Target(0) {}
+ InMemoryStruct(reference Value) : Target(&Contents), Contents(Value) {}
+ InMemoryStruct(pointer Value) : Target(Value) {}
+ InMemoryStruct(const InMemoryStruct<T> &Value) { *this = Value; }
+
+ void operator=(const InMemoryStruct<T> &Value) {
+ if (Value.Target != &Value.Contents) {
+ Target = Value.Target;
+ } else {
+ Target = &Contents;
+ Contents = Value.Contents;
+ }
+ }
+
+ const_reference operator*() const {
+ assert(Target && "Cannot dereference null pointer");
+ return *Target;
+ }
+ reference operator*() {
+ assert(Target && "Cannot dereference null pointer");
+ return *Target;
+ }
+
+ const_pointer operator->() const {
+ return Target;
+ }
+ pointer operator->() {
+ return Target;
+ }
+
+ operator bool() const { return Target != 0; }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/IndexedMap.h b/contrib/llvm/include/llvm/ADT/IndexedMap.h
new file mode 100644
index 000000000000..87126ea49187
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/IndexedMap.h
@@ -0,0 +1,87 @@
+//===- llvm/ADT/IndexedMap.h - An index map implementation ------*- 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 an indexed map. The index map template takes two
+// types. The first is the mapped type and the second is a functor
+// that maps its argument to a size_t. On instantiation a "null" value
+// can be provided to be used as a "does not exist" indicator in the
+// map. A member function grow() is provided that given the value of
+// the maximally indexed key (the argument of the functor) makes sure
+// the map has enough space for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INDEXEDMAP_H
+#define LLVM_ADT_INDEXEDMAP_H
+
+#include <cassert>
+#include <functional>
+#include <vector>
+
+namespace llvm {
+
+ struct IdentityFunctor : public std::unary_function<unsigned, unsigned> {
+ unsigned operator()(unsigned Index) const {
+ return Index;
+ }
+ };
+
+ template <typename T, typename ToIndexT = IdentityFunctor>
+ class IndexedMap {
+ typedef typename ToIndexT::argument_type IndexT;
+ typedef std::vector<T> StorageT;
+ StorageT storage_;
+ T nullVal_;
+ ToIndexT toIndex_;
+
+ public:
+ IndexedMap() : nullVal_(T()) { }
+
+ explicit IndexedMap(const T& val) : nullVal_(val) { }
+
+ typename StorageT::reference operator[](IndexT n) {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ typename StorageT::const_reference operator[](IndexT n) const {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ void reserve(typename StorageT::size_type s) {
+ storage_.reserve(s);
+ }
+
+ void resize(typename StorageT::size_type s) {
+ storage_.resize(s, nullVal_);
+ }
+
+ void clear() {
+ storage_.clear();
+ }
+
+ void grow(IndexT n) {
+ unsigned NewSize = toIndex_(n) + 1;
+ if (NewSize > storage_.size())
+ resize(NewSize);
+ }
+
+ bool inBounds(IndexT n) const {
+ return toIndex_(n) < storage_.size();
+ }
+
+ typename StorageT::size_type size() const {
+ return storage_.size();
+ }
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/IntEqClasses.h b/contrib/llvm/include/llvm/ADT/IntEqClasses.h
new file mode 100644
index 000000000000..8e75c48e3764
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/IntEqClasses.h
@@ -0,0 +1,88 @@
+//===-- llvm/ADT/IntEqClasses.h - Equiv. Classes of Integers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Equivalence classes for small integers. This is a mapping of the integers
+// 0 .. N-1 into M equivalence classes numbered 0 .. M-1.
+//
+// Initially each integer has its own equivalence class. Classes are joined by
+// passing a representative member of each class to join().
+//
+// Once the classes are built, compress() will number them 0 .. M-1 and prevent
+// further changes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTEQCLASSES_H
+#define LLVM_ADT_INTEQCLASSES_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class IntEqClasses {
+ /// EC - When uncompressed, map each integer to a smaller member of its
+ /// equivalence class. The class leader is the smallest member and maps to
+ /// itself.
+ ///
+ /// When compressed, EC[i] is the equivalence class of i.
+ SmallVector<unsigned, 8> EC;
+
+ /// NumClasses - The number of equivalence classes when compressed, or 0 when
+ /// uncompressed.
+ unsigned NumClasses;
+
+public:
+ /// IntEqClasses - Create an equivalence class mapping for 0 .. N-1.
+ IntEqClasses(unsigned N = 0) : NumClasses(0) { grow(N); }
+
+ /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
+ /// equivalence classes.
+ /// This requires an uncompressed map.
+ void grow(unsigned N);
+
+ /// clear - Clear all classes so that grow() will assign a unique class to
+ /// every integer.
+ void clear() {
+ EC.clear();
+ NumClasses = 0;
+ }
+
+ /// join - Join the equivalence classes of a and b. After joining classes,
+ /// findLeader(a) == findLeader(b).
+ /// This requires an uncompressed map.
+ void join(unsigned a, unsigned b);
+
+ /// findLeader - Compute the leader of a's equivalence class. This is the
+ /// smallest member of the class.
+ /// This requires an uncompressed map.
+ unsigned findLeader(unsigned a) const;
+
+ /// compress - Compress equivalence classes by numbering them 0 .. M.
+ /// This makes the equivalence class map immutable.
+ void compress();
+
+ /// getNumClasses - Return the number of equivalence classes after compress()
+ /// was called.
+ unsigned getNumClasses() const { return NumClasses; }
+
+ /// operator[] - Return a's equivalence class number, 0 .. getNumClasses()-1.
+ /// This requires a compressed map.
+ unsigned operator[](unsigned a) const {
+ assert(NumClasses && "operator[] called before compress()");
+ return EC[a];
+ }
+
+ /// uncompress - Change back to the uncompressed representation that allows
+ /// editing.
+ void uncompress();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/IntervalMap.h b/contrib/llvm/include/llvm/ADT/IntervalMap.h
new file mode 100644
index 000000000000..931b67e40911
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/IntervalMap.h
@@ -0,0 +1,2146 @@
+//===- llvm/ADT/IntervalMap.h - A sorted interval 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 coalescing interval map for small objects.
+//
+// KeyT objects are mapped to ValT objects. Intervals of keys that map to the
+// same value are represented in a compressed form.
+//
+// Iterators provide ordered access to the compressed intervals rather than the
+// individual keys, and insert and erase operations use key intervals as well.
+//
+// Like SmallVector, IntervalMap will store the first N intervals in the map
+// object itself without any allocations. When space is exhausted it switches to
+// a B+-tree representation with very small overhead for small key and value
+// objects.
+//
+// A Traits class specifies how keys are compared. It also allows IntervalMap to
+// work with both closed and half-open intervals.
+//
+// Keys and values are not stored next to each other in a std::pair, so we don't
+// provide such a value_type. Dereferencing iterators only returns the mapped
+// value. The interval bounds are accessible through the start() and stop()
+// iterator methods.
+//
+// IntervalMap is optimized for small key and value objects, 4 or 8 bytes each
+// is the optimal size. For large objects use std::map instead.
+//
+//===----------------------------------------------------------------------===//
+//
+// Synopsis:
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap {
+// public:
+// typedef KeyT key_type;
+// typedef ValT mapped_type;
+// typedef RecyclingAllocator<...> Allocator;
+// class iterator;
+// class const_iterator;
+//
+// explicit IntervalMap(Allocator&);
+// ~IntervalMap():
+//
+// bool empty() const;
+// KeyT start() const;
+// KeyT stop() const;
+// ValT lookup(KeyT x, Value NotFound = Value()) const;
+//
+// const_iterator begin() const;
+// const_iterator end() const;
+// iterator begin();
+// iterator end();
+// const_iterator find(KeyT x) const;
+// iterator find(KeyT x);
+//
+// void insert(KeyT a, KeyT b, ValT y);
+// void clear();
+// };
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap::const_iterator :
+// public std::iterator<std::bidirectional_iterator_tag, ValT> {
+// public:
+// bool operator==(const const_iterator &) const;
+// bool operator!=(const const_iterator &) const;
+// bool valid() const;
+//
+// const KeyT &start() const;
+// const KeyT &stop() const;
+// const ValT &value() const;
+// const ValT &operator*() const;
+// const ValT *operator->() const;
+//
+// const_iterator &operator++();
+// const_iterator &operator++(int);
+// const_iterator &operator--();
+// const_iterator &operator--(int);
+// void goToBegin();
+// void goToEnd();
+// void find(KeyT x);
+// void advanceTo(KeyT x);
+// };
+//
+// template <typename KeyT, typename ValT, unsigned N, typename Traits>
+// class IntervalMap::iterator : public const_iterator {
+// public:
+// void insert(KeyT a, KeyT b, Value y);
+// void erase();
+// };
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTERVALMAP_H
+#define LLVM_ADT_INTERVALMAP_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include <iterator>
+
+namespace llvm {
+
+
+//===----------------------------------------------------------------------===//
+//--- Key traits ---//
+//===----------------------------------------------------------------------===//
+//
+// The IntervalMap works with closed or half-open intervals.
+// Adjacent intervals that map to the same value are coalesced.
+//
+// The IntervalMapInfo traits class is used to determine if a key is contained
+// in an interval, and if two intervals are adjacent so they can be coalesced.
+// The provided implementation works for closed integer intervals, other keys
+// probably need a specialized version.
+//
+// The point x is contained in [a;b] when !startLess(x, a) && !stopLess(b, x).
+//
+// It is assumed that (a;b] half-open intervals are not used, only [a;b) is
+// allowed. This is so that stopLess(a, b) can be used to determine if two
+// intervals overlap.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+struct IntervalMapInfo {
+
+ /// startLess - Return true if x is not in [a;b].
+ /// This is x < a both for closed intervals and for [a;b) half-open intervals.
+ static inline bool startLess(const T &x, const T &a) {
+ return x < a;
+ }
+
+ /// stopLess - Return true if x is not in [a;b].
+ /// This is b < x for a closed interval, b <= x for [a;b) half-open intervals.
+ 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.
+ /// This is a+1 == b for closed intervals, a == b for half-open intervals.
+ static inline bool adjacent(const T &a, const T &b) {
+ return a+1 == b;
+ }
+
+};
+
+/// IntervalMapImpl - Namespace used for IntervalMap implementation details.
+/// It should be considered private to the implementation.
+namespace IntervalMapImpl {
+
+// Forward declarations.
+template <typename, typename, unsigned, typename> class LeafNode;
+template <typename, typename, unsigned, typename> class BranchNode;
+
+typedef std::pair<unsigned,unsigned> IdxPair;
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::NodeBase ---//
+//===----------------------------------------------------------------------===//
+//
+// Both leaf and branch nodes store vectors of pairs.
+// Leaves store ((KeyT, KeyT), ValT) pairs, branches use (NodeRef, KeyT).
+//
+// Keys and values are stored in separate arrays to avoid padding caused by
+// different object alignments. This also helps improve locality of reference
+// when searching the keys.
+//
+// The nodes don't know how many elements they contain - that information is
+// stored elsewhere. Omitting the size field prevents padding and allows a node
+// to fill the allocated cache lines completely.
+//
+// These are typical key and value sizes, the node branching factor (N), and
+// wasted space when nodes are sized to fit in three cache lines (192 bytes):
+//
+// T1 T2 N Waste Used by
+// 4 4 24 0 Branch<4> (32-bit pointers)
+// 8 4 16 0 Leaf<4,4>, Branch<4>
+// 8 8 12 0 Leaf<4,8>, Branch<8>
+// 16 4 9 12 Leaf<8,4>
+// 16 8 8 0 Leaf<8,8>
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T1, typename T2, unsigned N>
+class NodeBase {
+public:
+ enum { Capacity = N };
+
+ T1 first[N];
+ T2 second[N];
+
+ /// copy - Copy elements from another node.
+ /// @param Other Node elements are copied from.
+ /// @param i Beginning of the source range in other.
+ /// @param j Beginning of the destination range in this.
+ /// @param Count Number of elements to copy.
+ template <unsigned M>
+ void copy(const NodeBase<T1, T2, M> &Other, unsigned i,
+ unsigned j, unsigned Count) {
+ assert(i + Count <= M && "Invalid source range");
+ assert(j + Count <= N && "Invalid dest range");
+ for (unsigned e = i + Count; i != e; ++i, ++j) {
+ first[j] = Other.first[i];
+ second[j] = Other.second[i];
+ }
+ }
+
+ /// moveLeft - Move elements to the left.
+ /// @param i Beginning of the source range.
+ /// @param j Beginning of the destination range.
+ /// @param Count Number of elements to copy.
+ void moveLeft(unsigned i, unsigned j, unsigned Count) {
+ assert(j <= i && "Use moveRight shift elements right");
+ copy(*this, i, j, Count);
+ }
+
+ /// moveRight - Move elements to the right.
+ /// @param i Beginning of the source range.
+ /// @param j Beginning of the destination range.
+ /// @param Count Number of elements to copy.
+ void moveRight(unsigned i, unsigned j, unsigned Count) {
+ assert(i <= j && "Use moveLeft shift elements left");
+ assert(j + Count <= N && "Invalid range");
+ while (Count--) {
+ first[j + Count] = first[i + Count];
+ second[j + Count] = second[i + Count];
+ }
+ }
+
+ /// erase - Erase elements [i;j).
+ /// @param i Beginning of the range to erase.
+ /// @param j End of the range. (Exclusive).
+ /// @param Size Number of elements in node.
+ void erase(unsigned i, unsigned j, unsigned Size) {
+ moveLeft(j, i, Size - j);
+ }
+
+ /// erase - Erase element at i.
+ /// @param i Index of element to erase.
+ /// @param Size Number of elements in node.
+ void erase(unsigned i, unsigned Size) {
+ erase(i, i+1, Size);
+ }
+
+ /// shift - Shift elements [i;size) 1 position to the right.
+ /// @param i Beginning of the range to move.
+ /// @param Size Number of elements in node.
+ void shift(unsigned i, unsigned Size) {
+ moveRight(i, i + 1, Size - i);
+ }
+
+ /// transferToLeftSib - Transfer elements to a left sibling node.
+ /// @param Size Number of elements in this.
+ /// @param Sib Left sibling node.
+ /// @param SSize Number of elements in sib.
+ /// @param Count Number of elements to transfer.
+ void transferToLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize,
+ unsigned Count) {
+ Sib.copy(*this, 0, SSize, Count);
+ erase(0, Count, Size);
+ }
+
+ /// transferToRightSib - Transfer elements to a right sibling node.
+ /// @param Size Number of elements in this.
+ /// @param Sib Right sibling node.
+ /// @param SSize Number of elements in sib.
+ /// @param Count Number of elements to transfer.
+ void transferToRightSib(unsigned Size, NodeBase &Sib, unsigned SSize,
+ unsigned Count) {
+ Sib.moveRight(0, Count, SSize);
+ Sib.copy(*this, Size-Count, 0, Count);
+ }
+
+ /// adjustFromLeftSib - Adjust the number if elements in this node by moving
+ /// elements to or from a left sibling node.
+ /// @param Size Number of elements in this.
+ /// @param Sib Right sibling node.
+ /// @param SSize Number of elements in sib.
+ /// @param Add The number of elements to add to this node, possibly < 0.
+ /// @return Number of elements added to this node, possibly negative.
+ int adjustFromLeftSib(unsigned Size, NodeBase &Sib, unsigned SSize, int Add) {
+ if (Add > 0) {
+ // We want to grow, copy from sib.
+ unsigned Count = std::min(std::min(unsigned(Add), SSize), N - Size);
+ Sib.transferToRightSib(SSize, *this, Size, Count);
+ return Count;
+ } else {
+ // We want to shrink, copy to sib.
+ unsigned Count = std::min(std::min(unsigned(-Add), Size), N - SSize);
+ transferToLeftSib(Size, Sib, SSize, Count);
+ return -Count;
+ }
+ }
+};
+
+/// IntervalMapImpl::adjustSiblingSizes - Move elements between sibling nodes.
+/// @param Node Array of pointers to sibling nodes.
+/// @param Nodes Number of nodes.
+/// @param CurSize Array of current node sizes, will be overwritten.
+/// @param NewSize Array of desired node sizes.
+template <typename NodeT>
+void adjustSiblingSizes(NodeT *Node[], unsigned Nodes,
+ unsigned CurSize[], const unsigned NewSize[]) {
+ // Move elements right.
+ for (int n = Nodes - 1; n; --n) {
+ if (CurSize[n] == NewSize[n])
+ continue;
+ for (int m = n - 1; m != -1; --m) {
+ int d = Node[n]->adjustFromLeftSib(CurSize[n], *Node[m], CurSize[m],
+ NewSize[n] - CurSize[n]);
+ CurSize[m] -= d;
+ CurSize[n] += d;
+ // Keep going if the current node was exhausted.
+ if (CurSize[n] >= NewSize[n])
+ break;
+ }
+ }
+
+ if (Nodes == 0)
+ return;
+
+ // Move elements left.
+ for (unsigned n = 0; n != Nodes - 1; ++n) {
+ if (CurSize[n] == NewSize[n])
+ continue;
+ for (unsigned m = n + 1; m != Nodes; ++m) {
+ int d = Node[m]->adjustFromLeftSib(CurSize[m], *Node[n], CurSize[n],
+ CurSize[n] - NewSize[n]);
+ CurSize[m] += d;
+ CurSize[n] -= d;
+ // Keep going if the current node was exhausted.
+ if (CurSize[n] >= NewSize[n])
+ break;
+ }
+ }
+
+#ifndef NDEBUG
+ for (unsigned n = 0; n != Nodes; n++)
+ assert(CurSize[n] == NewSize[n] && "Insufficient element shuffle");
+#endif
+}
+
+/// IntervalMapImpl::distribute - Compute a new distribution of node elements
+/// after an overflow or underflow. Reserve space for a new element at Position,
+/// and compute the node that will hold Position after redistributing node
+/// elements.
+///
+/// It is required that
+///
+/// Elements == sum(CurSize), and
+/// Elements + Grow <= Nodes * Capacity.
+///
+/// NewSize[] will be filled in such that:
+///
+/// sum(NewSize) == Elements, and
+/// NewSize[i] <= Capacity.
+///
+/// The returned index is the node where Position will go, so:
+///
+/// sum(NewSize[0..idx-1]) <= Position
+/// sum(NewSize[0..idx]) >= Position
+///
+/// The last equality, sum(NewSize[0..idx]) == Position, can only happen when
+/// Grow is set and NewSize[idx] == Capacity-1. The index points to the node
+/// before the one holding the Position'th element where there is room for an
+/// insertion.
+///
+/// @param Nodes The number of nodes.
+/// @param Elements Total elements in all nodes.
+/// @param Capacity The capacity of each node.
+/// @param CurSize Array[Nodes] of current node sizes, or NULL.
+/// @param NewSize Array[Nodes] to receive the new node sizes.
+/// @param Position Insert position.
+/// @param Grow Reserve space for a new element at Position.
+/// @return (node, offset) for Position.
+IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
+ const unsigned *CurSize, unsigned NewSize[],
+ unsigned Position, bool Grow);
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::NodeSizer ---//
+//===----------------------------------------------------------------------===//
+//
+// Compute node sizes from key and value types.
+//
+// The branching factors are chosen to make nodes fit in three cache lines.
+// This may not be possible if keys or values are very large. Such large objects
+// are handled correctly, but a std::map would probably give better performance.
+//
+//===----------------------------------------------------------------------===//
+
+enum {
+ // Cache line size. Most architectures have 32 or 64 byte cache lines.
+ // We use 64 bytes here because it provides good branching factors.
+ Log2CacheLine = 6,
+ CacheLineBytes = 1 << Log2CacheLine,
+ DesiredNodeBytes = 3 * CacheLineBytes
+};
+
+template <typename KeyT, typename ValT>
+struct NodeSizer {
+ enum {
+ // Compute the leaf node branching factor that makes a node fit in three
+ // cache lines. The branching factor must be at least 3, or some B+-tree
+ // balancing algorithms won't work.
+ // LeafSize can't be larger than CacheLineBytes. This is required by the
+ // PointerIntPair used by NodeRef.
+ DesiredLeafSize = DesiredNodeBytes /
+ static_cast<unsigned>(2*sizeof(KeyT)+sizeof(ValT)),
+ MinLeafSize = 3,
+ LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize
+ };
+
+ typedef NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize> LeafBase;
+
+ enum {
+ // Now that we have the leaf branching factor, compute the actual allocation
+ // unit size by rounding up to a whole number of cache lines.
+ AllocBytes = (sizeof(LeafBase) + CacheLineBytes-1) & ~(CacheLineBytes-1),
+
+ // Determine the branching factor for branch nodes.
+ BranchSize = AllocBytes /
+ static_cast<unsigned>(sizeof(KeyT) + sizeof(void*))
+ };
+
+ /// Allocator - The recycling allocator used for both branch and leaf nodes.
+ /// This typedef is very likely to be identical for all IntervalMaps with
+ /// reasonably sized entries, so the same allocator can be shared among
+ /// different kinds of maps.
+ typedef RecyclingAllocator<BumpPtrAllocator, char,
+ AllocBytes, CacheLineBytes> Allocator;
+
+};
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::NodeRef ---//
+//===----------------------------------------------------------------------===//
+//
+// B+-tree nodes can be leaves or branches, so we need a polymorphic node
+// pointer that can point to both kinds.
+//
+// All nodes are cache line aligned and the low 6 bits of a node pointer are
+// always 0. These bits are used to store the number of elements in the
+// referenced node. Besides saving space, placing node sizes in the parents
+// allow tree balancing algorithms to run without faulting cache lines for nodes
+// that may not need to be modified.
+//
+// A NodeRef doesn't know whether it references a leaf node or a branch node.
+// It is the responsibility of the caller to use the correct types.
+//
+// Nodes are never supposed to be empty, and it is invalid to store a node size
+// of 0 in a NodeRef. The valid range of sizes is 1-64.
+//
+//===----------------------------------------------------------------------===//
+
+class NodeRef {
+ struct CacheAlignedPointerTraits {
+ static inline void *getAsVoidPointer(void *P) { return P; }
+ static inline void *getFromVoidPointer(void *P) { return P; }
+ enum { NumLowBitsAvailable = Log2CacheLine };
+ };
+ PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip;
+
+public:
+ /// NodeRef - Create a null ref.
+ NodeRef() {}
+
+ /// operator bool - Detect a null ref.
+ operator bool() const { return pip.getOpaqueValue(); }
+
+ /// NodeRef - Create a reference to the node p with n elements.
+ template <typename NodeT>
+ NodeRef(NodeT *p, unsigned n) : pip(p, n - 1) {
+ assert(n <= NodeT::Capacity && "Size too big for node");
+ }
+
+ /// size - Return the number of elements in the referenced node.
+ unsigned size() const { return pip.getInt() + 1; }
+
+ /// setSize - Update the node size.
+ void setSize(unsigned n) { pip.setInt(n - 1); }
+
+ /// subtree - Access the i'th subtree reference in a branch node.
+ /// This depends on branch nodes storing the NodeRef array as their first
+ /// member.
+ NodeRef &subtree(unsigned i) const {
+ return reinterpret_cast<NodeRef*>(pip.getPointer())[i];
+ }
+
+ /// get - Dereference as a NodeT reference.
+ template <typename NodeT>
+ NodeT &get() const {
+ return *reinterpret_cast<NodeT*>(pip.getPointer());
+ }
+
+ bool operator==(const NodeRef &RHS) const {
+ if (pip == RHS.pip)
+ return true;
+ assert(pip.getPointer() != RHS.pip.getPointer() && "Inconsistent NodeRefs");
+ return false;
+ }
+
+ bool operator!=(const NodeRef &RHS) const {
+ return !operator==(RHS);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::LeafNode ---//
+//===----------------------------------------------------------------------===//
+//
+// Leaf nodes store up to N disjoint intervals with corresponding values.
+//
+// The intervals are kept sorted and fully coalesced so there are no adjacent
+// intervals mapping to the same value.
+//
+// These constraints are always satisfied:
+//
+// - Traits::stopLess(start(i), stop(i)) - Non-empty, sane intervals.
+//
+// - Traits::stopLess(stop(i), start(i + 1) - Sorted.
+//
+// - value(i) != value(i + 1) || !Traits::adjacent(stop(i), start(i + 1))
+// - Fully coalesced.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class LeafNode : public NodeBase<std::pair<KeyT, KeyT>, ValT, N> {
+public:
+ const KeyT &start(unsigned i) const { return this->first[i].first; }
+ const KeyT &stop(unsigned i) const { return this->first[i].second; }
+ const ValT &value(unsigned i) const { return this->second[i]; }
+
+ KeyT &start(unsigned i) { return this->first[i].first; }
+ KeyT &stop(unsigned i) { return this->first[i].second; }
+ ValT &value(unsigned i) { return this->second[i]; }
+
+ /// findFrom - Find the first interval after i that may contain x.
+ /// @param i Starting index for the search.
+ /// @param Size Number of elements in node.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i].stop, x), or size.
+ /// This is the first interval that can possibly contain x.
+ unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
+ assert(i <= Size && Size <= N && "Bad indices");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index is past the needed point");
+ while (i != Size && Traits::stopLess(stop(i), x)) ++i;
+ return i;
+ }
+
+ /// safeFind - Find an interval that is known to exist. This is the same as
+ /// findFrom except is it assumed that x is at least within range of the last
+ /// interval.
+ /// @param i Starting index for the search.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i].stop, x), never size.
+ /// This is the first interval that can possibly contain x.
+ unsigned safeFind(unsigned i, KeyT x) const {
+ assert(i < N && "Bad index");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index is past the needed point");
+ while (Traits::stopLess(stop(i), x)) ++i;
+ assert(i < N && "Unsafe intervals");
+ return i;
+ }
+
+ /// safeLookup - Lookup mapped value for a safe key.
+ /// It is assumed that x is within range of the last entry.
+ /// @param x Key to search for.
+ /// @param NotFound Value to return if x is not in any interval.
+ /// @return The mapped value at x or NotFound.
+ ValT safeLookup(KeyT x, ValT NotFound) const {
+ unsigned i = safeFind(0, x);
+ return Traits::startLess(x, start(i)) ? NotFound : value(i);
+ }
+
+ unsigned insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y);
+};
+
+/// insertFrom - Add mapping of [a;b] to y if possible, coalescing as much as
+/// possible. This may cause the node to grow by 1, or it may cause the node
+/// to shrink because of coalescing.
+/// @param i Starting index = insertFrom(0, size, a)
+/// @param Size Number of elements in node.
+/// @param a Interval start.
+/// @param b Interval stop.
+/// @param y Value be mapped.
+/// @return (insert position, new size), or (i, Capacity+1) on overflow.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+unsigned LeafNode<KeyT, ValT, N, Traits>::
+insertFrom(unsigned &Pos, unsigned Size, KeyT a, KeyT b, ValT y) {
+ unsigned i = Pos;
+ assert(i <= Size && Size <= N && "Invalid index");
+ assert(!Traits::stopLess(b, a) && "Invalid interval");
+
+ // Verify the findFrom invariant.
+ assert((i == 0 || Traits::stopLess(stop(i - 1), a)));
+ assert((i == Size || !Traits::stopLess(stop(i), a)));
+ assert((i == Size || Traits::stopLess(b, start(i))) && "Overlapping insert");
+
+ // Coalesce with previous interval.
+ if (i && value(i - 1) == y && Traits::adjacent(stop(i - 1), a)) {
+ Pos = i - 1;
+ // Also coalesce with next interval?
+ if (i != Size && value(i) == y && Traits::adjacent(b, start(i))) {
+ stop(i - 1) = stop(i);
+ this->erase(i, Size);
+ return Size - 1;
+ }
+ stop(i - 1) = b;
+ return Size;
+ }
+
+ // Detect overflow.
+ if (i == N)
+ return N + 1;
+
+ // Add new interval at end.
+ if (i == Size) {
+ start(i) = a;
+ stop(i) = b;
+ value(i) = y;
+ return Size + 1;
+ }
+
+ // Try to coalesce with following interval.
+ if (value(i) == y && Traits::adjacent(b, start(i))) {
+ start(i) = a;
+ return Size;
+ }
+
+ // We must insert before i. Detect overflow.
+ if (Size == N)
+ return N + 1;
+
+ // Insert before i.
+ this->shift(i, Size);
+ start(i) = a;
+ stop(i) = b;
+ value(i) = y;
+ return Size + 1;
+}
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::BranchNode ---//
+//===----------------------------------------------------------------------===//
+//
+// A branch node stores references to 1--N subtrees all of the same height.
+//
+// The key array in a branch node holds the rightmost stop key of each subtree.
+// It is redundant to store the last stop key since it can be found in the
+// parent node, but doing so makes tree balancing a lot simpler.
+//
+// It is unusual for a branch node to only have one subtree, but it can happen
+// in the root node if it is smaller than the normal nodes.
+//
+// When all of the leaf nodes from all the subtrees are concatenated, they must
+// satisfy the same constraints as a single leaf node. They must be sorted,
+// sane, and fully coalesced.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class BranchNode : public NodeBase<NodeRef, KeyT, N> {
+public:
+ const KeyT &stop(unsigned i) const { return this->second[i]; }
+ const NodeRef &subtree(unsigned i) const { return this->first[i]; }
+
+ KeyT &stop(unsigned i) { return this->second[i]; }
+ NodeRef &subtree(unsigned i) { return this->first[i]; }
+
+ /// findFrom - Find the first subtree after i that may contain x.
+ /// @param i Starting index for the search.
+ /// @param Size Number of elements in node.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i], x), or size.
+ /// This is the first subtree that can possibly contain x.
+ unsigned findFrom(unsigned i, unsigned Size, KeyT x) const {
+ assert(i <= Size && Size <= N && "Bad indices");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index to findFrom is past the needed point");
+ while (i != Size && Traits::stopLess(stop(i), x)) ++i;
+ return i;
+ }
+
+ /// safeFind - Find a subtree that is known to exist. This is the same as
+ /// findFrom except is it assumed that x is in range.
+ /// @param i Starting index for the search.
+ /// @param x Key to search for.
+ /// @return First index with !stopLess(key[i], x), never size.
+ /// This is the first subtree that can possibly contain x.
+ unsigned safeFind(unsigned i, KeyT x) const {
+ assert(i < N && "Bad index");
+ assert((i == 0 || Traits::stopLess(stop(i - 1), x)) &&
+ "Index is past the needed point");
+ while (Traits::stopLess(stop(i), x)) ++i;
+ assert(i < N && "Unsafe intervals");
+ return i;
+ }
+
+ /// safeLookup - Get the subtree containing x, Assuming that x is in range.
+ /// @param x Key to search for.
+ /// @return Subtree containing x
+ NodeRef safeLookup(KeyT x) const {
+ return subtree(safeFind(0, x));
+ }
+
+ /// insert - Insert a new (subtree, stop) pair.
+ /// @param i Insert position, following entries will be shifted.
+ /// @param Size Number of elements in node.
+ /// @param Node Subtree to insert.
+ /// @param Stop Last key in subtree.
+ void insert(unsigned i, unsigned Size, NodeRef Node, KeyT Stop) {
+ assert(Size < N && "branch node overflow");
+ assert(i <= Size && "Bad insert position");
+ this->shift(i, Size);
+ subtree(i) = Node;
+ stop(i) = Stop;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapImpl::Path ---//
+//===----------------------------------------------------------------------===//
+//
+// A Path is used by iterators to represent a position in a B+-tree, and the
+// path to get there from the root.
+//
+// The Path class also contains the tree navigation code that doesn't have to
+// be templatized.
+//
+//===----------------------------------------------------------------------===//
+
+class Path {
+ /// Entry - Each step in the path is a node pointer and an offset into that
+ /// node.
+ struct Entry {
+ void *node;
+ unsigned size;
+ unsigned offset;
+
+ Entry(void *Node, unsigned Size, unsigned Offset)
+ : node(Node), size(Size), offset(Offset) {}
+
+ Entry(NodeRef Node, unsigned Offset)
+ : node(&Node.subtree(0)), size(Node.size()), offset(Offset) {}
+
+ NodeRef &subtree(unsigned i) const {
+ return reinterpret_cast<NodeRef*>(node)[i];
+ }
+ };
+
+ /// path - The path entries, path[0] is the root node, path.back() is a leaf.
+ SmallVector<Entry, 4> path;
+
+public:
+ // Node accessors.
+ template <typename NodeT> NodeT &node(unsigned Level) const {
+ return *reinterpret_cast<NodeT*>(path[Level].node);
+ }
+ unsigned size(unsigned Level) const { return path[Level].size; }
+ unsigned offset(unsigned Level) const { return path[Level].offset; }
+ unsigned &offset(unsigned Level) { return path[Level].offset; }
+
+ // Leaf accessors.
+ template <typename NodeT> NodeT &leaf() const {
+ return *reinterpret_cast<NodeT*>(path.back().node);
+ }
+ unsigned leafSize() const { return path.back().size; }
+ unsigned leafOffset() const { return path.back().offset; }
+ unsigned &leafOffset() { return path.back().offset; }
+
+ /// valid - Return true if path is at a valid node, not at end().
+ bool valid() const {
+ return !path.empty() && path.front().offset < path.front().size;
+ }
+
+ /// height - Return the height of the tree corresponding to this path.
+ /// This matches map->height in a full path.
+ unsigned height() const { return path.size() - 1; }
+
+ /// subtree - Get the subtree referenced from Level. When the path is
+ /// consistent, node(Level + 1) == subtree(Level).
+ /// @param Level 0..height-1. The leaves have no subtrees.
+ NodeRef &subtree(unsigned Level) const {
+ return path[Level].subtree(path[Level].offset);
+ }
+
+ /// reset - Reset cached information about node(Level) from subtree(Level -1).
+ /// @param Level 1..height. THe node to update after parent node changed.
+ void reset(unsigned Level) {
+ path[Level] = Entry(subtree(Level - 1), offset(Level));
+ }
+
+ /// push - Add entry to path.
+ /// @param Node Node to add, should be subtree(path.size()-1).
+ /// @param Offset Offset into Node.
+ void push(NodeRef Node, unsigned Offset) {
+ path.push_back(Entry(Node, Offset));
+ }
+
+ /// pop - Remove the last path entry.
+ void pop() {
+ path.pop_back();
+ }
+
+ /// setSize - Set the size of a node both in the path and in the tree.
+ /// @param Level 0..height. Note that setting the root size won't change
+ /// map->rootSize.
+ /// @param Size New node size.
+ void setSize(unsigned Level, unsigned Size) {
+ path[Level].size = Size;
+ if (Level)
+ subtree(Level - 1).setSize(Size);
+ }
+
+ /// setRoot - Clear the path and set a new root node.
+ /// @param Node New root node.
+ /// @param Size New root size.
+ /// @param Offset Offset into root node.
+ void setRoot(void *Node, unsigned Size, unsigned Offset) {
+ path.clear();
+ path.push_back(Entry(Node, Size, Offset));
+ }
+
+ /// replaceRoot - Replace the current root node with two new entries after the
+ /// tree height has increased.
+ /// @param Root The new root node.
+ /// @param Size Number of entries in the new root.
+ /// @param Offsets Offsets into the root and first branch nodes.
+ void replaceRoot(void *Root, unsigned Size, IdxPair Offsets);
+
+ /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
+ /// @param Level Get the sibling to node(Level).
+ /// @return Left sibling, or NodeRef().
+ NodeRef getLeftSibling(unsigned Level) const;
+
+ /// moveLeft - Move path to the left sibling at Level. Leave nodes below Level
+ /// unaltered.
+ /// @param Level Move node(Level).
+ void moveLeft(unsigned Level);
+
+ /// fillLeft - Grow path to Height by taking leftmost branches.
+ /// @param Height The target height.
+ void fillLeft(unsigned Height) {
+ while (height() < Height)
+ push(subtree(height()), 0);
+ }
+
+ /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
+ /// @param Level Get the sinbling to node(Level).
+ /// @return Left sibling, or NodeRef().
+ NodeRef getRightSibling(unsigned Level) const;
+
+ /// moveRight - Move path to the left sibling at Level. Leave nodes below
+ /// Level unaltered.
+ /// @param Level Move node(Level).
+ void moveRight(unsigned Level);
+
+ /// atBegin - Return true if path is at begin().
+ bool atBegin() const {
+ for (unsigned i = 0, e = path.size(); i != e; ++i)
+ if (path[i].offset != 0)
+ return false;
+ return true;
+ }
+
+ /// atLastEntry - Return true if the path is at the last entry of the node at
+ /// Level.
+ /// @param Level Node to examine.
+ bool atLastEntry(unsigned Level) const {
+ return path[Level].offset == path[Level].size - 1;
+ }
+
+ /// legalizeForInsert - Prepare the path for an insertion at Level. When the
+ /// path is at end(), node(Level) may not be a legal node. legalizeForInsert
+ /// ensures that node(Level) is real by moving back to the last node at Level,
+ /// and setting offset(Level) to size(Level) if required.
+ /// @param Level The level where an insertion is about to take place.
+ void legalizeForInsert(unsigned Level) {
+ if (valid())
+ return;
+ moveLeft(Level);
+ ++path[Level].offset;
+ }
+};
+
+} // namespace IntervalMapImpl
+
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMap ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT,
+ unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
+ typename Traits = IntervalMapInfo<KeyT> >
+class IntervalMap {
+ typedef IntervalMapImpl::NodeSizer<KeyT, ValT> Sizer;
+ typedef IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits> Leaf;
+ typedef IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>
+ Branch;
+ typedef IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits> RootLeaf;
+ typedef IntervalMapImpl::IdxPair IdxPair;
+
+ // The RootLeaf capacity is given as a template parameter. We must compute the
+ // corresponding RootBranch capacity.
+ enum {
+ DesiredRootBranchCap = (sizeof(RootLeaf) - sizeof(KeyT)) /
+ (sizeof(KeyT) + sizeof(IntervalMapImpl::NodeRef)),
+ RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
+ };
+
+ typedef IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>
+ RootBranch;
+
+ // When branched, we store a global start key as well as the branch node.
+ struct RootBranchData {
+ KeyT start;
+ RootBranch node;
+ };
+
+ enum {
+ RootDataSize = sizeof(RootBranchData) > sizeof(RootLeaf) ?
+ sizeof(RootBranchData) : sizeof(RootLeaf)
+ };
+
+public:
+ typedef typename Sizer::Allocator Allocator;
+ typedef KeyT KeyType;
+ typedef ValT ValueType;
+ typedef Traits KeyTraits;
+
+private:
+ // The root data is either a RootLeaf or a RootBranchData instance.
+ // We can't put them in a union since C++03 doesn't allow non-trivial
+ // constructors in unions.
+ // Instead, we use a char array with pointer alignment. The alignment is
+ // ensured by the allocator member in the class, but still verified in the
+ // constructor. We don't support keys or values that are more aligned than a
+ // pointer.
+ char data[RootDataSize];
+
+ // Tree height.
+ // 0: Leaves in root.
+ // 1: Root points to leaf.
+ // 2: root->branch->leaf ...
+ unsigned height;
+
+ // Number of entries in the root node.
+ unsigned rootSize;
+
+ // Allocator used for creating external nodes.
+ Allocator &allocator;
+
+ /// dataAs - Represent data as a node type without breaking aliasing rules.
+ template <typename T>
+ T &dataAs() const {
+ union {
+ const char *d;
+ T *t;
+ } u;
+ u.d = data;
+ return *u.t;
+ }
+
+ const RootLeaf &rootLeaf() const {
+ assert(!branched() && "Cannot acces leaf data in branched root");
+ return dataAs<RootLeaf>();
+ }
+ RootLeaf &rootLeaf() {
+ assert(!branched() && "Cannot acces leaf data in branched root");
+ return dataAs<RootLeaf>();
+ }
+ RootBranchData &rootBranchData() const {
+ assert(branched() && "Cannot access branch data in non-branched root");
+ return dataAs<RootBranchData>();
+ }
+ RootBranchData &rootBranchData() {
+ assert(branched() && "Cannot access branch data in non-branched root");
+ return dataAs<RootBranchData>();
+ }
+ const RootBranch &rootBranch() const { return rootBranchData().node; }
+ RootBranch &rootBranch() { return rootBranchData().node; }
+ KeyT rootBranchStart() const { return rootBranchData().start; }
+ KeyT &rootBranchStart() { return rootBranchData().start; }
+
+ template <typename NodeT> NodeT *newNode() {
+ return new(allocator.template Allocate<NodeT>()) NodeT();
+ }
+
+ template <typename NodeT> void deleteNode(NodeT *P) {
+ P->~NodeT();
+ allocator.Deallocate(P);
+ }
+
+ IdxPair branchRoot(unsigned Position);
+ IdxPair splitRoot(unsigned Position);
+
+ void switchRootToBranch() {
+ rootLeaf().~RootLeaf();
+ height = 1;
+ new (&rootBranchData()) RootBranchData();
+ }
+
+ void switchRootToLeaf() {
+ rootBranchData().~RootBranchData();
+ height = 0;
+ new(&rootLeaf()) RootLeaf();
+ }
+
+ bool branched() const { return height > 0; }
+
+ ValT treeSafeLookup(KeyT x, ValT NotFound) const;
+ void visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef,
+ unsigned Level));
+ void deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level);
+
+public:
+ explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) {
+ assert((uintptr_t(data) & (alignOf<RootLeaf>() - 1)) == 0 &&
+ "Insufficient alignment");
+ new(&rootLeaf()) RootLeaf();
+ }
+
+ ~IntervalMap() {
+ clear();
+ rootLeaf().~RootLeaf();
+ }
+
+ /// empty - Return true when no intervals are mapped.
+ bool empty() const {
+ return rootSize == 0;
+ }
+
+ /// start - Return the smallest mapped key in a non-empty map.
+ KeyT start() const {
+ assert(!empty() && "Empty IntervalMap has no start");
+ return !branched() ? rootLeaf().start(0) : rootBranchStart();
+ }
+
+ /// stop - Return the largest mapped key in a non-empty map.
+ KeyT stop() const {
+ assert(!empty() && "Empty IntervalMap has no stop");
+ return !branched() ? rootLeaf().stop(rootSize - 1) :
+ rootBranch().stop(rootSize - 1);
+ }
+
+ /// lookup - Return the mapped value at x or NotFound.
+ ValT lookup(KeyT x, ValT NotFound = ValT()) const {
+ if (empty() || Traits::startLess(x, start()) || Traits::stopLess(stop(), x))
+ return NotFound;
+ return branched() ? treeSafeLookup(x, NotFound) :
+ rootLeaf().safeLookup(x, NotFound);
+ }
+
+ /// insert - Add a mapping of [a;b] to y, coalesce with adjacent intervals.
+ /// It is assumed that no key in the interval is mapped to another value, but
+ /// overlapping intervals already mapped to y will be coalesced.
+ void insert(KeyT a, KeyT b, ValT y) {
+ if (branched() || rootSize == RootLeaf::Capacity)
+ return find(a).insert(a, b, y);
+
+ // Easy insert into root leaf.
+ unsigned p = rootLeaf().findFrom(0, rootSize, a);
+ rootSize = rootLeaf().insertFrom(p, rootSize, a, b, y);
+ }
+
+ /// clear - Remove all entries.
+ void clear();
+
+ class const_iterator;
+ class iterator;
+ friend class const_iterator;
+ friend class iterator;
+
+ const_iterator begin() const {
+ const_iterator I(*this);
+ I.goToBegin();
+ return I;
+ }
+
+ iterator begin() {
+ iterator I(*this);
+ I.goToBegin();
+ return I;
+ }
+
+ const_iterator end() const {
+ const_iterator I(*this);
+ I.goToEnd();
+ return I;
+ }
+
+ iterator end() {
+ iterator I(*this);
+ I.goToEnd();
+ return I;
+ }
+
+ /// find - Return an iterator pointing to the first interval ending at or
+ /// after x, or end().
+ const_iterator find(KeyT x) const {
+ const_iterator I(*this);
+ I.find(x);
+ return I;
+ }
+
+ iterator find(KeyT x) {
+ iterator I(*this);
+ I.find(x);
+ return I;
+ }
+};
+
+/// treeSafeLookup - Return the mapped value at x or NotFound, assuming a
+/// branched root.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+ValT IntervalMap<KeyT, ValT, N, Traits>::
+treeSafeLookup(KeyT x, ValT NotFound) const {
+ assert(branched() && "treeLookup assumes a branched root");
+
+ IntervalMapImpl::NodeRef NR = rootBranch().safeLookup(x);
+ for (unsigned h = height-1; h; --h)
+ NR = NR.get<Branch>().safeLookup(x);
+ return NR.get<Leaf>().safeLookup(x, NotFound);
+}
+
+
+// branchRoot - Switch from a leaf root to a branched root.
+// Return the new (root offset, node offset) corresponding to Position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
+branchRoot(unsigned Position) {
+ using namespace IntervalMapImpl;
+ // How many external leaf nodes to hold RootLeaf+1?
+ const unsigned Nodes = RootLeaf::Capacity / Leaf::Capacity + 1;
+
+ // Compute element distribution among new nodes.
+ unsigned size[Nodes];
+ IdxPair NewOffset(0, Position);
+
+ // Is is very common for the root node to be smaller than external nodes.
+ if (Nodes == 1)
+ size[0] = rootSize;
+ else
+ NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, NULL, size,
+ Position, true);
+
+ // Allocate new nodes.
+ unsigned pos = 0;
+ NodeRef node[Nodes];
+ for (unsigned n = 0; n != Nodes; ++n) {
+ Leaf *L = newNode<Leaf>();
+ L->copy(rootLeaf(), pos, 0, size[n]);
+ node[n] = NodeRef(L, size[n]);
+ pos += size[n];
+ }
+
+ // Destroy the old leaf node, construct branch node instead.
+ switchRootToBranch();
+ for (unsigned n = 0; n != Nodes; ++n) {
+ rootBranch().stop(n) = node[n].template get<Leaf>().stop(size[n]-1);
+ rootBranch().subtree(n) = node[n];
+ }
+ rootBranchStart() = node[0].template get<Leaf>().start(0);
+ rootSize = Nodes;
+ return NewOffset;
+}
+
+// splitRoot - Split the current BranchRoot into multiple Branch nodes.
+// Return the new (root offset, node offset) corresponding to Position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+IntervalMapImpl::IdxPair IntervalMap<KeyT, ValT, N, Traits>::
+splitRoot(unsigned Position) {
+ using namespace IntervalMapImpl;
+ // How many external leaf nodes to hold RootBranch+1?
+ const unsigned Nodes = RootBranch::Capacity / Branch::Capacity + 1;
+
+ // Compute element distribution among new nodes.
+ unsigned Size[Nodes];
+ IdxPair NewOffset(0, Position);
+
+ // Is is very common for the root node to be smaller than external nodes.
+ if (Nodes == 1)
+ Size[0] = rootSize;
+ else
+ NewOffset = distribute(Nodes, rootSize, Leaf::Capacity, NULL, Size,
+ Position, true);
+
+ // Allocate new nodes.
+ unsigned Pos = 0;
+ NodeRef Node[Nodes];
+ for (unsigned n = 0; n != Nodes; ++n) {
+ Branch *B = newNode<Branch>();
+ B->copy(rootBranch(), Pos, 0, Size[n]);
+ Node[n] = NodeRef(B, Size[n]);
+ Pos += Size[n];
+ }
+
+ for (unsigned n = 0; n != Nodes; ++n) {
+ rootBranch().stop(n) = Node[n].template get<Branch>().stop(Size[n]-1);
+ rootBranch().subtree(n) = Node[n];
+ }
+ rootSize = Nodes;
+ ++height;
+ return NewOffset;
+}
+
+/// visitNodes - Visit each external node.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+visitNodes(void (IntervalMap::*f)(IntervalMapImpl::NodeRef, unsigned Height)) {
+ if (!branched())
+ return;
+ SmallVector<IntervalMapImpl::NodeRef, 4> Refs, NextRefs;
+
+ // Collect level 0 nodes from the root.
+ for (unsigned i = 0; i != rootSize; ++i)
+ Refs.push_back(rootBranch().subtree(i));
+
+ // Visit all branch nodes.
+ for (unsigned h = height - 1; h; --h) {
+ for (unsigned i = 0, e = Refs.size(); i != e; ++i) {
+ for (unsigned j = 0, s = Refs[i].size(); j != s; ++j)
+ NextRefs.push_back(Refs[i].subtree(j));
+ (this->*f)(Refs[i], h);
+ }
+ Refs.clear();
+ Refs.swap(NextRefs);
+ }
+
+ // Visit all leaf nodes.
+ for (unsigned i = 0, e = Refs.size(); i != e; ++i)
+ (this->*f)(Refs[i], 0);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+deleteNode(IntervalMapImpl::NodeRef Node, unsigned Level) {
+ if (Level)
+ deleteNode(&Node.get<Branch>());
+ else
+ deleteNode(&Node.get<Leaf>());
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+clear() {
+ if (branched()) {
+ visitNodes(&IntervalMap::deleteNode);
+ switchRootToLeaf();
+ }
+ rootSize = 0;
+}
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMap::const_iterator ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
+ public std::iterator<std::bidirectional_iterator_tag, ValT> {
+protected:
+ friend class IntervalMap;
+
+ // The map referred to.
+ IntervalMap *map;
+
+ // We store a full path from the root to the current position.
+ // The path may be partially filled, but never between iterator calls.
+ IntervalMapImpl::Path path;
+
+ explicit const_iterator(const IntervalMap &map) :
+ map(const_cast<IntervalMap*>(&map)) {}
+
+ bool branched() const {
+ assert(map && "Invalid iterator");
+ return map->branched();
+ }
+
+ void setRoot(unsigned Offset) {
+ if (branched())
+ path.setRoot(&map->rootBranch(), map->rootSize, Offset);
+ else
+ path.setRoot(&map->rootLeaf(), map->rootSize, Offset);
+ }
+
+ void pathFillFind(KeyT x);
+ void treeFind(KeyT x);
+ void treeAdvanceTo(KeyT x);
+
+ /// unsafeStart - Writable access to start() for iterator.
+ KeyT &unsafeStart() const {
+ assert(valid() && "Cannot access invalid iterator");
+ return branched() ? path.leaf<Leaf>().start(path.leafOffset()) :
+ path.leaf<RootLeaf>().start(path.leafOffset());
+ }
+
+ /// unsafeStop - Writable access to stop() for iterator.
+ KeyT &unsafeStop() const {
+ assert(valid() && "Cannot access invalid iterator");
+ return branched() ? path.leaf<Leaf>().stop(path.leafOffset()) :
+ path.leaf<RootLeaf>().stop(path.leafOffset());
+ }
+
+ /// unsafeValue - Writable access to value() for iterator.
+ ValT &unsafeValue() const {
+ assert(valid() && "Cannot access invalid iterator");
+ return branched() ? path.leaf<Leaf>().value(path.leafOffset()) :
+ path.leaf<RootLeaf>().value(path.leafOffset());
+ }
+
+public:
+ /// const_iterator - Create an iterator that isn't pointing anywhere.
+ const_iterator() : map(0) {}
+
+ /// setMap - Change the map iterated over. This call must be followed by a
+ /// call to goToBegin(), goToEnd(), or find()
+ void setMap(const IntervalMap &m) { map = const_cast<IntervalMap*>(&m); }
+
+ /// valid - Return true if the current position is valid, false for end().
+ bool valid() const { return path.valid(); }
+
+ /// atBegin - Return true if the current position is the first map entry.
+ bool atBegin() const { return path.atBegin(); }
+
+ /// start - Return the beginning of the current interval.
+ const KeyT &start() const { return unsafeStart(); }
+
+ /// stop - Return the end of the current interval.
+ const KeyT &stop() const { return unsafeStop(); }
+
+ /// value - Return the mapped value at the current interval.
+ const ValT &value() const { return unsafeValue(); }
+
+ const ValT &operator*() const { return value(); }
+
+ bool operator==(const const_iterator &RHS) const {
+ assert(map == RHS.map && "Cannot compare iterators from different maps");
+ if (!valid())
+ return !RHS.valid();
+ if (path.leafOffset() != RHS.path.leafOffset())
+ return false;
+ return &path.template leaf<Leaf>() == &RHS.path.template leaf<Leaf>();
+ }
+
+ bool operator!=(const const_iterator &RHS) const {
+ return !operator==(RHS);
+ }
+
+ /// goToBegin - Move to the first interval in map.
+ void goToBegin() {
+ setRoot(0);
+ if (branched())
+ path.fillLeft(map->height);
+ }
+
+ /// goToEnd - Move beyond the last interval in map.
+ void goToEnd() {
+ setRoot(map->rootSize);
+ }
+
+ /// preincrement - move to the next interval.
+ const_iterator &operator++() {
+ assert(valid() && "Cannot increment end()");
+ if (++path.leafOffset() == path.leafSize() && branched())
+ path.moveRight(map->height);
+ return *this;
+ }
+
+ /// postincrement - Dont do that!
+ const_iterator operator++(int) {
+ const_iterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+
+ /// predecrement - move to the previous interval.
+ const_iterator &operator--() {
+ if (path.leafOffset() && (valid() || !branched()))
+ --path.leafOffset();
+ else
+ path.moveLeft(map->height);
+ return *this;
+ }
+
+ /// postdecrement - Dont do that!
+ const_iterator operator--(int) {
+ const_iterator tmp = *this;
+ operator--();
+ return tmp;
+ }
+
+ /// find - Move to the first interval with stop >= x, or end().
+ /// This is a full search from the root, the current position is ignored.
+ void find(KeyT x) {
+ if (branched())
+ treeFind(x);
+ else
+ setRoot(map->rootLeaf().findFrom(0, map->rootSize, x));
+ }
+
+ /// advanceTo - Move to the first interval with stop >= x, or end().
+ /// The search is started from the current position, and no earlier positions
+ /// can be found. This is much faster than find() for small moves.
+ void advanceTo(KeyT x) {
+ if (!valid())
+ return;
+ if (branched())
+ treeAdvanceTo(x);
+ else
+ path.leafOffset() =
+ map->rootLeaf().findFrom(path.leafOffset(), map->rootSize, x);
+ }
+
+};
+
+/// pathFillFind - Complete path by searching for x.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::pathFillFind(KeyT x) {
+ IntervalMapImpl::NodeRef NR = path.subtree(path.height());
+ for (unsigned i = map->height - path.height() - 1; i; --i) {
+ unsigned p = NR.get<Branch>().safeFind(0, x);
+ path.push(NR, p);
+ NR = NR.subtree(p);
+ }
+ path.push(NR, NR.get<Leaf>().safeFind(0, x));
+}
+
+/// treeFind - Find in a branched tree.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::treeFind(KeyT x) {
+ setRoot(map->rootBranch().findFrom(0, map->rootSize, x));
+ if (valid())
+ pathFillFind(x);
+}
+
+/// treeAdvanceTo - Find position after the current one.
+/// @param x Key to search for.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+const_iterator::treeAdvanceTo(KeyT x) {
+ // Can we stay on the same leaf node?
+ if (!Traits::stopLess(path.leaf<Leaf>().stop(path.leafSize() - 1), x)) {
+ path.leafOffset() = path.leaf<Leaf>().safeFind(path.leafOffset(), x);
+ return;
+ }
+
+ // Drop the current leaf.
+ path.pop();
+
+ // Search towards the root for a usable subtree.
+ if (path.height()) {
+ for (unsigned l = path.height() - 1; l; --l) {
+ if (!Traits::stopLess(path.node<Branch>(l).stop(path.offset(l)), x)) {
+ // The branch node at l+1 is usable
+ path.offset(l + 1) =
+ path.node<Branch>(l + 1).safeFind(path.offset(l + 1), x);
+ return pathFillFind(x);
+ }
+ path.pop();
+ }
+ // Is the level-1 Branch usable?
+ if (!Traits::stopLess(map->rootBranch().stop(path.offset(0)), x)) {
+ path.offset(1) = path.node<Branch>(1).safeFind(path.offset(1), x);
+ return pathFillFind(x);
+ }
+ }
+
+ // We reached the root.
+ setRoot(map->rootBranch().findFrom(path.offset(0), map->rootSize, x));
+ if (valid())
+ pathFillFind(x);
+}
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMap::iterator ----//
+//===----------------------------------------------------------------------===//
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator {
+ friend class IntervalMap;
+ typedef IntervalMapImpl::IdxPair IdxPair;
+
+ explicit iterator(IntervalMap &map) : const_iterator(map) {}
+
+ void setNodeStop(unsigned Level, KeyT Stop);
+ bool insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop);
+ template <typename NodeT> bool overflow(unsigned Level);
+ void treeInsert(KeyT a, KeyT b, ValT y);
+ void eraseNode(unsigned Level);
+ void treeErase(bool UpdateRoot = true);
+ bool canCoalesceLeft(KeyT Start, ValT x);
+ bool canCoalesceRight(KeyT Stop, ValT x);
+
+public:
+ /// iterator - Create null iterator.
+ iterator() {}
+
+ /// setStart - Move the start of the current interval.
+ /// This may cause coalescing with the previous interval.
+ /// @param a New start key, must not overlap the previous interval.
+ void setStart(KeyT a);
+
+ /// setStop - Move the end of the current interval.
+ /// This may cause coalescing with the following interval.
+ /// @param b New stop key, must not overlap the following interval.
+ void setStop(KeyT b);
+
+ /// setValue - Change the mapped value of the current interval.
+ /// This may cause coalescing with the previous and following intervals.
+ /// @param x New value.
+ void setValue(ValT x);
+
+ /// setStartUnchecked - Move the start of the current interval without
+ /// checking for coalescing or overlaps.
+ /// This should only be used when it is known that coalescing is not required.
+ /// @param a New start key.
+ void setStartUnchecked(KeyT a) { this->unsafeStart() = a; }
+
+ /// setStopUnchecked - Move the end of the current interval without checking
+ /// for coalescing or overlaps.
+ /// This should only be used when it is known that coalescing is not required.
+ /// @param b New stop key.
+ void setStopUnchecked(KeyT b) {
+ this->unsafeStop() = b;
+ // Update keys in branch nodes as well.
+ if (this->path.atLastEntry(this->path.height()))
+ setNodeStop(this->path.height(), b);
+ }
+
+ /// setValueUnchecked - Change the mapped value of the current interval
+ /// without checking for coalescing.
+ /// @param x New value.
+ void setValueUnchecked(ValT x) { this->unsafeValue() = x; }
+
+ /// insert - Insert mapping [a;b] -> y before the current position.
+ void insert(KeyT a, KeyT b, ValT y);
+
+ /// erase - Erase the current interval.
+ void erase();
+
+ iterator &operator++() {
+ const_iterator::operator++();
+ return *this;
+ }
+
+ iterator operator++(int) {
+ iterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+
+ iterator &operator--() {
+ const_iterator::operator--();
+ return *this;
+ }
+
+ iterator operator--(int) {
+ iterator tmp = *this;
+ operator--();
+ return tmp;
+ }
+
+};
+
+/// canCoalesceLeft - Can the current interval coalesce to the left after
+/// changing start or value?
+/// @param Start New start of current interval.
+/// @param Value New value for current interval.
+/// @return True when updating the current interval would enable coalescing.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::canCoalesceLeft(KeyT Start, ValT Value) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+ if (!this->branched()) {
+ unsigned i = P.leafOffset();
+ RootLeaf &Node = P.leaf<RootLeaf>();
+ return i && Node.value(i-1) == Value &&
+ Traits::adjacent(Node.stop(i-1), Start);
+ }
+ // Branched.
+ if (unsigned i = P.leafOffset()) {
+ Leaf &Node = P.leaf<Leaf>();
+ return Node.value(i-1) == Value && Traits::adjacent(Node.stop(i-1), Start);
+ } else if (NodeRef NR = P.getLeftSibling(P.height())) {
+ unsigned i = NR.size() - 1;
+ Leaf &Node = NR.get<Leaf>();
+ return Node.value(i) == Value && Traits::adjacent(Node.stop(i), Start);
+ }
+ return false;
+}
+
+/// canCoalesceRight - Can the current interval coalesce to the right after
+/// changing stop or value?
+/// @param Stop New stop of current interval.
+/// @param Value New value for current interval.
+/// @return True when updating the current interval would enable coalescing.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::canCoalesceRight(KeyT Stop, ValT Value) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+ unsigned i = P.leafOffset() + 1;
+ if (!this->branched()) {
+ if (i >= P.leafSize())
+ return false;
+ RootLeaf &Node = P.leaf<RootLeaf>();
+ return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
+ }
+ // Branched.
+ if (i < P.leafSize()) {
+ Leaf &Node = P.leaf<Leaf>();
+ return Node.value(i) == Value && Traits::adjacent(Stop, Node.start(i));
+ } else if (NodeRef NR = P.getRightSibling(P.height())) {
+ Leaf &Node = NR.get<Leaf>();
+ return Node.value(0) == Value && Traits::adjacent(Stop, Node.start(0));
+ }
+ return false;
+}
+
+/// setNodeStop - Update the stop key of the current node at level and above.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setNodeStop(unsigned Level, KeyT Stop) {
+ // There are no references to the root node, so nothing to update.
+ if (!Level)
+ return;
+ IntervalMapImpl::Path &P = this->path;
+ // Update nodes pointing to the current node.
+ while (--Level) {
+ P.node<Branch>(Level).stop(P.offset(Level)) = Stop;
+ if (!P.atLastEntry(Level))
+ return;
+ }
+ // Update root separately since it has a different layout.
+ P.node<RootBranch>(Level).stop(P.offset(Level)) = Stop;
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setStart(KeyT a) {
+ assert(Traits::stopLess(a, this->stop()) && "Cannot move start beyond stop");
+ KeyT &CurStart = this->unsafeStart();
+ if (!Traits::startLess(a, CurStart) || !canCoalesceLeft(a, this->value())) {
+ CurStart = a;
+ return;
+ }
+ // Coalesce with the interval to the left.
+ --*this;
+ a = this->start();
+ erase();
+ setStartUnchecked(a);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setStop(KeyT b) {
+ assert(Traits::stopLess(this->start(), b) && "Cannot move stop beyond start");
+ if (Traits::startLess(b, this->stop()) ||
+ !canCoalesceRight(b, this->value())) {
+ setStopUnchecked(b);
+ return;
+ }
+ // Coalesce with interval to the right.
+ KeyT a = this->start();
+ erase();
+ setStartUnchecked(a);
+}
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::setValue(ValT x) {
+ setValueUnchecked(x);
+ if (canCoalesceRight(this->stop(), x)) {
+ KeyT a = this->start();
+ erase();
+ setStartUnchecked(a);
+ }
+ if (canCoalesceLeft(this->start(), x)) {
+ --*this;
+ KeyT a = this->start();
+ erase();
+ setStartUnchecked(a);
+ }
+}
+
+/// insertNode - insert a node before the current path at level.
+/// Leave the current path pointing at the new node.
+/// @param Level path index of the node to be inserted.
+/// @param Node The node to be inserted.
+/// @param Stop The last index in the new node.
+/// @return True if the tree height was increased.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::insertNode(unsigned Level, IntervalMapImpl::NodeRef Node, KeyT Stop) {
+ assert(Level && "Cannot insert next to the root");
+ bool SplitRoot = false;
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+
+ if (Level == 1) {
+ // Insert into the root branch node.
+ if (IM.rootSize < RootBranch::Capacity) {
+ IM.rootBranch().insert(P.offset(0), IM.rootSize, Node, Stop);
+ P.setSize(0, ++IM.rootSize);
+ P.reset(Level);
+ return SplitRoot;
+ }
+
+ // We need to split the root while keeping our position.
+ SplitRoot = true;
+ IdxPair Offset = IM.splitRoot(P.offset(0));
+ P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
+
+ // Fall through to insert at the new higher level.
+ ++Level;
+ }
+
+ // When inserting before end(), make sure we have a valid path.
+ P.legalizeForInsert(--Level);
+
+ // Insert into the branch node at Level-1.
+ if (P.size(Level) == Branch::Capacity) {
+ // Branch node is full, handle handle the overflow.
+ assert(!SplitRoot && "Cannot overflow after splitting the root");
+ SplitRoot = overflow<Branch>(Level);
+ Level += SplitRoot;
+ }
+ P.node<Branch>(Level).insert(P.offset(Level), P.size(Level), Node, Stop);
+ P.setSize(Level, P.size(Level) + 1);
+ if (P.atLastEntry(Level))
+ setNodeStop(Level, Stop);
+ P.reset(Level + 1);
+ return SplitRoot;
+}
+
+// insert
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::insert(KeyT a, KeyT b, ValT y) {
+ if (this->branched())
+ return treeInsert(a, b, y);
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+
+ // Try simple root leaf insert.
+ unsigned Size = IM.rootLeaf().insertFrom(P.leafOffset(), IM.rootSize, a, b, y);
+
+ // Was the root node insert successful?
+ if (Size <= RootLeaf::Capacity) {
+ P.setSize(0, IM.rootSize = Size);
+ return;
+ }
+
+ // Root leaf node is full, we must branch.
+ IdxPair Offset = IM.branchRoot(P.leafOffset());
+ P.replaceRoot(&IM.rootBranch(), IM.rootSize, Offset);
+
+ // Now it fits in the new leaf.
+ treeInsert(a, b, y);
+}
+
+
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::treeInsert(KeyT a, KeyT b, ValT y) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+
+ if (!P.valid())
+ P.legalizeForInsert(this->map->height);
+
+ // Check if this insertion will extend the node to the left.
+ if (P.leafOffset() == 0 && Traits::startLess(a, P.leaf<Leaf>().start(0))) {
+ // Node is growing to the left, will it affect a left sibling node?
+ if (NodeRef Sib = P.getLeftSibling(P.height())) {
+ Leaf &SibLeaf = Sib.get<Leaf>();
+ unsigned SibOfs = Sib.size() - 1;
+ if (SibLeaf.value(SibOfs) == y &&
+ Traits::adjacent(SibLeaf.stop(SibOfs), a)) {
+ // This insertion will coalesce with the last entry in SibLeaf. We can
+ // handle it in two ways:
+ // 1. Extend SibLeaf.stop to b and be done, or
+ // 2. Extend a to SibLeaf, erase the SibLeaf entry and continue.
+ // We prefer 1., but need 2 when coalescing to the right as well.
+ Leaf &CurLeaf = P.leaf<Leaf>();
+ P.moveLeft(P.height());
+ if (Traits::stopLess(b, CurLeaf.start(0)) &&
+ (y != CurLeaf.value(0) || !Traits::adjacent(b, CurLeaf.start(0)))) {
+ // Easy, just extend SibLeaf and we're done.
+ setNodeStop(P.height(), SibLeaf.stop(SibOfs) = b);
+ return;
+ } else {
+ // We have both left and right coalescing. Erase the old SibLeaf entry
+ // and continue inserting the larger interval.
+ a = SibLeaf.start(SibOfs);
+ treeErase(/* UpdateRoot= */false);
+ }
+ }
+ } else {
+ // No left sibling means we are at begin(). Update cached bound.
+ this->map->rootBranchStart() = a;
+ }
+ }
+
+ // When we are inserting at the end of a leaf node, we must update stops.
+ unsigned Size = P.leafSize();
+ bool Grow = P.leafOffset() == Size;
+ Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), Size, a, b, y);
+
+ // Leaf insertion unsuccessful? Overflow and try again.
+ if (Size > Leaf::Capacity) {
+ overflow<Leaf>(P.height());
+ Grow = P.leafOffset() == P.leafSize();
+ Size = P.leaf<Leaf>().insertFrom(P.leafOffset(), P.leafSize(), a, b, y);
+ assert(Size <= Leaf::Capacity && "overflow() didn't make room");
+ }
+
+ // Inserted, update offset and leaf size.
+ P.setSize(P.height(), Size);
+
+ // Insert was the last node entry, update stops.
+ if (Grow)
+ setNodeStop(P.height(), b);
+}
+
+/// erase - erase the current interval and move to the next position.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::erase() {
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+ assert(P.valid() && "Cannot erase end()");
+ if (this->branched())
+ return treeErase();
+ IM.rootLeaf().erase(P.leafOffset(), IM.rootSize);
+ P.setSize(0, --IM.rootSize);
+}
+
+/// treeErase - erase() for a branched tree.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::treeErase(bool UpdateRoot) {
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+ Leaf &Node = P.leaf<Leaf>();
+
+ // Nodes are not allowed to become empty.
+ if (P.leafSize() == 1) {
+ IM.deleteNode(&Node);
+ eraseNode(IM.height);
+ // Update rootBranchStart if we erased begin().
+ if (UpdateRoot && IM.branched() && P.valid() && P.atBegin())
+ IM.rootBranchStart() = P.leaf<Leaf>().start(0);
+ return;
+ }
+
+ // Erase current entry.
+ Node.erase(P.leafOffset(), P.leafSize());
+ unsigned NewSize = P.leafSize() - 1;
+ P.setSize(IM.height, NewSize);
+ // When we erase the last entry, update stop and move to a legal position.
+ if (P.leafOffset() == NewSize) {
+ setNodeStop(IM.height, Node.stop(NewSize - 1));
+ P.moveRight(IM.height);
+ } else if (UpdateRoot && P.atBegin())
+ IM.rootBranchStart() = P.leaf<Leaf>().start(0);
+}
+
+/// eraseNode - Erase the current node at Level from its parent and move path to
+/// the first entry of the next sibling node.
+/// The node must be deallocated by the caller.
+/// @param Level 1..height, the root node cannot be erased.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+void IntervalMap<KeyT, ValT, N, Traits>::
+iterator::eraseNode(unsigned Level) {
+ assert(Level && "Cannot erase root node");
+ IntervalMap &IM = *this->map;
+ IntervalMapImpl::Path &P = this->path;
+
+ if (--Level == 0) {
+ IM.rootBranch().erase(P.offset(0), IM.rootSize);
+ P.setSize(0, --IM.rootSize);
+ // If this cleared the root, switch to height=0.
+ if (IM.empty()) {
+ IM.switchRootToLeaf();
+ this->setRoot(0);
+ return;
+ }
+ } else {
+ // Remove node ref from branch node at Level.
+ Branch &Parent = P.node<Branch>(Level);
+ if (P.size(Level) == 1) {
+ // Branch node became empty, remove it recursively.
+ IM.deleteNode(&Parent);
+ eraseNode(Level);
+ } else {
+ // Branch node won't become empty.
+ Parent.erase(P.offset(Level), P.size(Level));
+ unsigned NewSize = P.size(Level) - 1;
+ P.setSize(Level, NewSize);
+ // If we removed the last branch, update stop and move to a legal pos.
+ if (P.offset(Level) == NewSize) {
+ setNodeStop(Level, Parent.stop(NewSize - 1));
+ P.moveRight(Level);
+ }
+ }
+ }
+ // Update path cache for the new right sibling position.
+ if (P.valid()) {
+ P.reset(Level + 1);
+ P.offset(Level + 1) = 0;
+ }
+}
+
+/// overflow - Distribute entries of the current node evenly among
+/// its siblings and ensure that the current node is not full.
+/// This may require allocating a new node.
+/// @param NodeT The type of node at Level (Leaf or Branch).
+/// @param Level path index of the overflowing node.
+/// @return True when the tree height was changed.
+template <typename KeyT, typename ValT, unsigned N, typename Traits>
+template <typename NodeT>
+bool IntervalMap<KeyT, ValT, N, Traits>::
+iterator::overflow(unsigned Level) {
+ using namespace IntervalMapImpl;
+ Path &P = this->path;
+ unsigned CurSize[4];
+ NodeT *Node[4];
+ unsigned Nodes = 0;
+ unsigned Elements = 0;
+ unsigned Offset = P.offset(Level);
+
+ // Do we have a left sibling?
+ NodeRef LeftSib = P.getLeftSibling(Level);
+ if (LeftSib) {
+ Offset += Elements = CurSize[Nodes] = LeftSib.size();
+ Node[Nodes++] = &LeftSib.get<NodeT>();
+ }
+
+ // Current node.
+ Elements += CurSize[Nodes] = P.size(Level);
+ Node[Nodes++] = &P.node<NodeT>(Level);
+
+ // Do we have a right sibling?
+ NodeRef RightSib = P.getRightSibling(Level);
+ if (RightSib) {
+ Elements += CurSize[Nodes] = RightSib.size();
+ Node[Nodes++] = &RightSib.get<NodeT>();
+ }
+
+ // Do we need to allocate a new node?
+ unsigned NewNode = 0;
+ if (Elements + 1 > Nodes * NodeT::Capacity) {
+ // Insert NewNode at the penultimate position, or after a single node.
+ NewNode = Nodes == 1 ? 1 : Nodes - 1;
+ CurSize[Nodes] = CurSize[NewNode];
+ Node[Nodes] = Node[NewNode];
+ CurSize[NewNode] = 0;
+ Node[NewNode] = this->map->template newNode<NodeT>();
+ ++Nodes;
+ }
+
+ // Compute the new element distribution.
+ unsigned NewSize[4];
+ IdxPair NewOffset = distribute(Nodes, Elements, NodeT::Capacity,
+ CurSize, NewSize, Offset, true);
+ adjustSiblingSizes(Node, Nodes, CurSize, NewSize);
+
+ // Move current location to the leftmost node.
+ if (LeftSib)
+ P.moveLeft(Level);
+
+ // Elements have been rearranged, now update node sizes and stops.
+ bool SplitRoot = false;
+ unsigned Pos = 0;
+ for (;;) {
+ KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1);
+ if (NewNode && Pos == NewNode) {
+ SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
+ Level += SplitRoot;
+ } else {
+ P.setSize(Level, NewSize[Pos]);
+ setNodeStop(Level, Stop);
+ }
+ if (Pos + 1 == Nodes)
+ break;
+ P.moveRight(Level);
+ ++Pos;
+ }
+
+ // Where was I? Find NewOffset.
+ while(Pos != NewOffset.first) {
+ P.moveLeft(Level);
+ --Pos;
+ }
+ P.offset(Level) = NewOffset.second;
+ return SplitRoot;
+}
+
+//===----------------------------------------------------------------------===//
+//--- IntervalMapOverlaps ----//
+//===----------------------------------------------------------------------===//
+
+/// IntervalMapOverlaps - Iterate over the overlaps of mapped intervals in two
+/// IntervalMaps. The maps may be different, but the KeyT and Traits types
+/// should be the same.
+///
+/// Typical uses:
+///
+/// 1. Test for overlap:
+/// bool overlap = IntervalMapOverlaps(a, b).valid();
+///
+/// 2. Enumerate overlaps:
+/// for (IntervalMapOverlaps I(a, b); I.valid() ; ++I) { ... }
+///
+template <typename MapA, typename MapB>
+class IntervalMapOverlaps {
+ typedef typename MapA::KeyType KeyType;
+ typedef typename MapA::KeyTraits Traits;
+ typename MapA::const_iterator posA;
+ typename MapB::const_iterator posB;
+
+ /// advance - Move posA and posB forward until reaching an overlap, or until
+ /// either meets end.
+ /// Don't move the iterators if they are already overlapping.
+ void advance() {
+ if (!valid())
+ return;
+
+ if (Traits::stopLess(posA.stop(), posB.start())) {
+ // A ends before B begins. Catch up.
+ posA.advanceTo(posB.start());
+ if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
+ return;
+ } else if (Traits::stopLess(posB.stop(), posA.start())) {
+ // B ends before A begins. Catch up.
+ posB.advanceTo(posA.start());
+ if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
+ return;
+ } else
+ // Already overlapping.
+ return;
+
+ for (;;) {
+ // Make a.end > b.start.
+ posA.advanceTo(posB.start());
+ if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))
+ return;
+ // Make b.end > a.start.
+ posB.advanceTo(posA.start());
+ if (!posB.valid() || !Traits::stopLess(posA.stop(), posB.start()))
+ return;
+ }
+ }
+
+public:
+ /// IntervalMapOverlaps - Create an iterator for the overlaps of a and b.
+ IntervalMapOverlaps(const MapA &a, const MapB &b)
+ : posA(b.empty() ? a.end() : a.find(b.start())),
+ posB(posA.valid() ? b.find(posA.start()) : b.end()) { advance(); }
+
+ /// valid - Return true if iterator is at an overlap.
+ bool valid() const {
+ return posA.valid() && posB.valid();
+ }
+
+ /// a - access the left hand side in the overlap.
+ const typename MapA::const_iterator &a() const { return posA; }
+
+ /// b - access the right hand side in the overlap.
+ const typename MapB::const_iterator &b() const { return posB; }
+
+ /// start - Beginning of the overlapping interval.
+ KeyType start() const {
+ KeyType ak = a().start();
+ KeyType bk = b().start();
+ return Traits::startLess(ak, bk) ? bk : ak;
+ }
+
+ /// stop - End of the overlapping interval.
+ KeyType stop() const {
+ KeyType ak = a().stop();
+ KeyType bk = b().stop();
+ return Traits::startLess(ak, bk) ? ak : bk;
+ }
+
+ /// skipA - Move to the next overlap that doesn't involve a().
+ void skipA() {
+ ++posA;
+ advance();
+ }
+
+ /// skipB - Move to the next overlap that doesn't involve b().
+ void skipB() {
+ ++posB;
+ advance();
+ }
+
+ /// Preincrement - Move to the next overlap.
+ IntervalMapOverlaps &operator++() {
+ // Bump the iterator that ends first. The other one may have more overlaps.
+ if (Traits::startLess(posB.stop(), posA.stop()))
+ skipB();
+ else
+ skipA();
+ return *this;
+ }
+
+ /// advanceTo - Move to the first overlapping interval with
+ /// stopLess(x, stop()).
+ void advanceTo(KeyType x) {
+ if (!valid())
+ return;
+ // Make sure advanceTo sees monotonic keys.
+ if (Traits::stopLess(posA.stop(), x))
+ posA.advanceTo(x);
+ if (Traits::stopLess(posB.stop(), x))
+ posB.advanceTo(x);
+ advance();
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h b/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
new file mode 100644
index 000000000000..3a1a3f4634cf
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -0,0 +1,247 @@
+//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- 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 IntrusiveRefCntPtr, a template class that
+// implements a "smart" pointer for objects that maintain their own
+// internal reference count, and RefCountedBase/RefCountedBaseVPTR, two
+// generic base classes for objects that wish to have their lifetimes
+// managed using reference counting.
+//
+// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added
+// LLVM-style casting.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+
+#include <cassert>
+
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+
+ template <class T>
+ class IntrusiveRefCntPtr;
+
+//===----------------------------------------------------------------------===//
+/// RefCountedBase - A generic base class for objects that wish to
+/// have their lifetimes managed using reference counts. Classes
+/// subclass RefCountedBase to obtain such functionality, and are
+/// typically handled with IntrusivePtr "smart pointers" (see below)
+/// which automatically handle the management of reference counts.
+/// Objects that subclass RefCountedBase should not be allocated on
+/// the stack, as invoking "delete" (which is called when the
+/// reference count hits 0) on such objects is an error.
+//===----------------------------------------------------------------------===//
+ template <class Derived>
+ class RefCountedBase {
+ mutable unsigned ref_cnt;
+
+ public:
+ RefCountedBase() : ref_cnt(0) {}
+ RefCountedBase(const RefCountedBase &) : ref_cnt(0) {}
+
+ void Retain() const { ++ref_cnt; }
+ void Release() const {
+ assert (ref_cnt > 0 && "Reference count is already zero.");
+ if (--ref_cnt == 0) delete static_cast<const Derived*>(this);
+ }
+ };
+
+//===----------------------------------------------------------------------===//
+/// RefCountedBaseVPTR - A class that has the same function as
+/// RefCountedBase, but with a virtual destructor. Should be used
+/// instead of RefCountedBase for classes that already have virtual
+/// methods to enforce dynamic allocation via 'new'. Classes that
+/// inherit from RefCountedBaseVPTR can't be allocated on stack -
+/// attempting to do this will produce a compile error.
+//===----------------------------------------------------------------------===//
+ class RefCountedBaseVPTR {
+ mutable unsigned ref_cnt;
+ virtual void anchor();
+
+ protected:
+ RefCountedBaseVPTR() : ref_cnt(0) {}
+ RefCountedBaseVPTR(const RefCountedBaseVPTR &) : ref_cnt(0) {}
+
+ virtual ~RefCountedBaseVPTR() {}
+
+ void Retain() const { ++ref_cnt; }
+ void Release() const {
+ assert (ref_cnt > 0 && "Reference count is already zero.");
+ if (--ref_cnt == 0) delete this;
+ }
+
+ template <typename T>
+ friend struct IntrusiveRefCntPtrInfo;
+ };
+
+
+ template <typename T> struct IntrusiveRefCntPtrInfo {
+ static void retain(T *obj) { obj->Retain(); }
+ static void release(T *obj) { obj->Release(); }
+ };
+
+//===----------------------------------------------------------------------===//
+/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
+/// that assumes the wrapped object has a reference count associated
+/// with it that can be managed via calls to
+/// IntrusivePtrAddRef/IntrusivePtrRelease. The smart pointers
+/// manage reference counts via the RAII idiom: upon creation of
+/// smart pointer the reference count of the wrapped object is
+/// incremented and upon destruction of the smart pointer the
+/// reference count is decremented. This class also safely handles
+/// wrapping NULL pointers.
+///
+/// Reference counting is implemented via calls to
+/// Obj->Retain()/Obj->Release(). Release() is required to destroy
+/// the object when the reference count reaches zero. Inheriting from
+/// RefCountedBase/RefCountedBaseVPTR takes care of this
+/// automatically.
+//===----------------------------------------------------------------------===//
+ template <typename T>
+ class IntrusiveRefCntPtr {
+ T* Obj;
+ typedef IntrusiveRefCntPtr this_type;
+ public:
+ typedef T element_type;
+
+ explicit IntrusiveRefCntPtr() : Obj(0) {}
+
+ IntrusiveRefCntPtr(T* obj) : Obj(obj) {
+ retain();
+ }
+
+ IntrusiveRefCntPtr(const IntrusiveRefCntPtr& S) : Obj(S.Obj) {
+ retain();
+ }
+
+ template <class X>
+ IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
+ : Obj(S.getPtr()) {
+ retain();
+ }
+
+ IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr& S) {
+ replace(S.getPtr());
+ return *this;
+ }
+
+ template <class X>
+ IntrusiveRefCntPtr& operator=(const IntrusiveRefCntPtr<X>& S) {
+ replace(S.getPtr());
+ return *this;
+ }
+
+ IntrusiveRefCntPtr& operator=(T * S) {
+ replace(S);
+ return *this;
+ }
+
+ ~IntrusiveRefCntPtr() { release(); }
+
+ T& operator*() const { return *Obj; }
+
+ T* operator->() const { return Obj; }
+
+ T* getPtr() const { return Obj; }
+
+ typedef T* (IntrusiveRefCntPtr::*unspecified_bool_type) () const;
+ operator unspecified_bool_type() const {
+ return Obj == 0 ? 0 : &IntrusiveRefCntPtr::getPtr;
+ }
+
+ void swap(IntrusiveRefCntPtr& other) {
+ T* tmp = other.Obj;
+ other.Obj = Obj;
+ Obj = tmp;
+ }
+
+ void reset() {
+ release();
+ Obj = 0;
+ }
+
+ void resetWithoutRelease() {
+ Obj = 0;
+ }
+
+ private:
+ void retain() { if (Obj) IntrusiveRefCntPtrInfo<T>::retain(Obj); }
+ void release() { if (Obj) IntrusiveRefCntPtrInfo<T>::release(Obj); }
+
+ void replace(T* S) {
+ this_type(S).swap(*this);
+ }
+ };
+
+ template<class T, class U>
+ inline bool operator==(const IntrusiveRefCntPtr<T>& A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A.getPtr() == B.getPtr();
+ }
+
+ template<class T, class U>
+ inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A.getPtr() != B.getPtr();
+ }
+
+ template<class T, class U>
+ inline bool operator==(const IntrusiveRefCntPtr<T>& A,
+ U* B)
+ {
+ return A.getPtr() == B;
+ }
+
+ template<class T, class U>
+ inline bool operator!=(const IntrusiveRefCntPtr<T>& A,
+ U* B)
+ {
+ return A.getPtr() != B;
+ }
+
+ template<class T, class U>
+ inline bool operator==(T* A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A == B.getPtr();
+ }
+
+ template<class T, class U>
+ inline bool operator!=(T* A,
+ const IntrusiveRefCntPtr<U>& B)
+ {
+ return A != B.getPtr();
+ }
+
+//===----------------------------------------------------------------------===//
+// LLVM-style downcasting support for IntrusiveRefCntPtr objects
+//===----------------------------------------------------------------------===//
+
+ template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
+ typedef T* SimpleType;
+ static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+ return Val.getPtr();
+ }
+ };
+
+ template<class T> struct simplify_type<const IntrusiveRefCntPtr<T> > {
+ typedef T* SimpleType;
+ static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T>& Val) {
+ return Val.getPtr();
+ }
+ };
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR
diff --git a/contrib/llvm/include/llvm/ADT/NullablePtr.h b/contrib/llvm/include/llvm/ADT/NullablePtr.h
new file mode 100644
index 000000000000..a9c47a138eca
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/NullablePtr.h
@@ -0,0 +1,52 @@
+//===- llvm/ADT/NullablePtr.h - A pointer that allows null ------*- 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 and implements the NullablePtr class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_NULLABLE_PTR_H
+#define LLVM_ADT_NULLABLE_PTR_H
+
+#include <cassert>
+#include <cstddef>
+
+namespace llvm {
+/// NullablePtr pointer wrapper - NullablePtr is used for APIs where a
+/// potentially-null pointer gets passed around that must be explicitly handled
+/// in lots of places. By putting a wrapper around the null pointer, it makes
+/// it more likely that the null pointer case will be handled correctly.
+template<class T>
+class NullablePtr {
+ T *Ptr;
+public:
+ NullablePtr(T *P = 0) : Ptr(P) {}
+
+ bool isNull() const { return Ptr == 0; }
+ bool isNonNull() const { return Ptr != 0; }
+
+ /// get - Return the pointer if it is non-null.
+ const T *get() const {
+ assert(Ptr && "Pointer wasn't checked for null!");
+ return Ptr;
+ }
+
+ /// get - Return the pointer if it is non-null.
+ T *get() {
+ assert(Ptr && "Pointer wasn't checked for null!");
+ return Ptr;
+ }
+
+ T *getPtrOrNull() { return Ptr; }
+ const T *getPtrOrNull() const { return Ptr; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/Optional.h b/contrib/llvm/include/llvm/ADT/Optional.h
new file mode 100644
index 000000000000..ee8b69f3d12f
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/Optional.h
@@ -0,0 +1,120 @@
+//===-- Optional.h - Simple variant for passing optional values ---*- 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 Optional, a template class modeled in the spirit of
+// OCaml's 'opt' variant. The idea is to strongly type whether or not
+// a value can be optional.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_OPTIONAL
+#define LLVM_ADT_OPTIONAL
+
+#include <cassert>
+
+namespace llvm {
+
+template<typename T>
+class Optional {
+ T x;
+ unsigned hasVal : 1;
+public:
+ explicit Optional() : x(), hasVal(false) {}
+ Optional(const T &y) : x(y), hasVal(true) {}
+
+ static inline Optional create(const T* y) {
+ return y ? Optional(*y) : Optional();
+ }
+
+ Optional &operator=(const T &y) {
+ x = y;
+ hasVal = true;
+ return *this;
+ }
+
+ const T* getPointer() const { assert(hasVal); return &x; }
+ const T& getValue() const { 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; }
+};
+
+template<typename T> struct simplify_type;
+
+template <typename T>
+struct simplify_type<const Optional<T> > {
+ typedef const T* SimpleType;
+ static SimpleType getSimplifiedValue(const Optional<T> &Val) {
+ return Val.getPointer();
+ }
+};
+
+template <typename T>
+struct simplify_type<Optional<T> >
+ : public simplify_type<const Optional<T> > {};
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator==(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator!=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator<(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator<=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator>=(const Optional<T> &X, const Optional<U> &Y);
+
+/// \brief Poison comparison between two \c Optional objects. Clients needs to
+/// explicitly compare the underlying values and account for empty \c Optional
+/// objects.
+///
+/// This routine will never be defined. It returns \c void to help diagnose
+/// errors at compile time.
+template<typename T, typename U>
+void operator>(const Optional<T> &X, const Optional<U> &Y);
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/OwningPtr.h b/contrib/llvm/include/llvm/ADT/OwningPtr.h
new file mode 100644
index 000000000000..6d9c30597789
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/OwningPtr.h
@@ -0,0 +1,133 @@
+//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- 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 and implements the OwningPtr class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_OWNING_PTR_H
+#define LLVM_ADT_OWNING_PTR_H
+
+#include <cassert>
+#include <cstddef>
+
+namespace llvm {
+
+/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
+/// guarantees deletion of the object pointed to, either on destruction of the
+/// OwningPtr or via an explicit reset(). Once created, ownership of the
+/// 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
+ T *Ptr;
+public:
+ explicit OwningPtr(T *P = 0) : Ptr(P) {}
+
+ ~OwningPtr() {
+ delete Ptr;
+ }
+
+ /// reset - Change the current pointee to the specified pointer. Note that
+ /// calling this with any pointer (including a null pointer) deletes the
+ /// current pointer.
+ void reset(T *P = 0) {
+ if (P == Ptr) return;
+ T *Tmp = Ptr;
+ Ptr = P;
+ delete Tmp;
+ }
+
+ /// take - Reset the owning pointer to null and return its pointer. This does
+ /// not delete the pointer before returning it.
+ T *take() {
+ T *Tmp = Ptr;
+ Ptr = 0;
+ return Tmp;
+ }
+
+ T &operator*() const {
+ assert(Ptr && "Cannot dereference null pointer");
+ return *Ptr;
+ }
+
+ T *operator->() const { return Ptr; }
+ T *get() const { return Ptr; }
+ operator bool() const { return Ptr != 0; }
+ bool operator!() const { return Ptr == 0; }
+
+ void swap(OwningPtr &RHS) {
+ T *Tmp = RHS.Ptr;
+ RHS.Ptr = Ptr;
+ Ptr = Tmp;
+ }
+};
+
+template<class T>
+inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
+ a.swap(b);
+}
+
+/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
+/// 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
+ T *Ptr;
+public:
+ explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
+
+ ~OwningArrayPtr() {
+ delete [] Ptr;
+ }
+
+ /// reset - Change the current pointee to the specified pointer. Note that
+ /// calling this with any pointer (including a null pointer) deletes the
+ /// current pointer.
+ void reset(T *P = 0) {
+ if (P == Ptr) return;
+ T *Tmp = Ptr;
+ Ptr = P;
+ delete [] Tmp;
+ }
+
+ /// take - Reset the owning pointer to null and return its pointer. This does
+ /// not delete the pointer before returning it.
+ T *take() {
+ T *Tmp = Ptr;
+ Ptr = 0;
+ return Tmp;
+ }
+
+ T &operator[](std::ptrdiff_t i) const {
+ assert(Ptr && "Cannot dereference null pointer");
+ return Ptr[i];
+ }
+
+ T *get() const { return Ptr; }
+ operator bool() const { return Ptr != 0; }
+ bool operator!() const { return Ptr == 0; }
+
+ void swap(OwningArrayPtr &RHS) {
+ T *Tmp = RHS.Ptr;
+ RHS.Ptr = Ptr;
+ Ptr = Tmp;
+ }
+};
+
+template<class T>
+inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
+ a.swap(b);
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/PackedVector.h b/contrib/llvm/include/llvm/ADT/PackedVector.h
new file mode 100644
index 000000000000..2eaddc2b4eea
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/PackedVector.h
@@ -0,0 +1,158 @@
+//===- llvm/ADT/PackedVector.h - Packed values vector -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the PackedVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_PACKEDVECTOR_H
+#define LLVM_ADT_PACKEDVECTOR_H
+
+#include "llvm/ADT/BitVector.h"
+#include <limits>
+
+namespace llvm {
+
+template <typename T, unsigned BitNum, 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> {
+protected:
+ static T getValue(const llvm::BitVector &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) {
+ 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> {
+protected:
+ static T getValue(const llvm::BitVector &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));
+ if (Bits[(Idx << (BitNum-1)) + BitNum-1])
+ val = ~val;
+ return val;
+ }
+
+ static void setValue(llvm::BitVector &Bits, unsigned Idx, T val) {
+ if (val < 0) {
+ val = ~val;
+ Bits.set((Idx << (BitNum-1)) + BitNum-1);
+ }
+ assert((val >> (BitNum-1)) == 0 && "value is too big");
+ for (unsigned i = 0; i != BitNum-1; ++i)
+ Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
+ }
+};
+
+/// \brief Store a vector of values using a specific number of bits for each
+/// value. Both signed and unsigned types can be used, e.g
+/// @code
+/// PackedVector<signed, 2> vec;
+/// @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,
+ std::numeric_limits<T>::is_signed> {
+ llvm::BitVector Bits;
+ typedef PackedVectorBase<T, BitNum, std::numeric_limits<T>::is_signed> base;
+
+public:
+ class reference {
+ PackedVector &Vec;
+ const unsigned Idx;
+
+ reference(); // Undefined
+ public:
+ reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) { }
+
+ reference &operator=(T val) {
+ Vec.setValue(Vec.Bits, Idx, val);
+ return *this;
+ }
+ operator T() const {
+ return Vec.getValue(Vec.Bits, Idx);
+ }
+ };
+
+ PackedVector() { }
+ explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { }
+
+ bool empty() const { return Bits.empty(); }
+
+ unsigned size() const { return Bits.size() >> (BitNum-1); }
+
+ void clear() { Bits.clear(); }
+
+ void resize(unsigned N) { Bits.resize(N << (BitNum-1)); }
+
+ void reserve(unsigned N) { Bits.reserve(N << (BitNum-1)); }
+
+ PackedVector &reset() {
+ Bits.reset();
+ return *this;
+ }
+
+ void push_back(T val) {
+ resize(size()+1);
+ (*this)[size()-1] = val;
+ }
+
+ reference operator[](unsigned Idx) {
+ return reference(*this, Idx);
+ }
+
+ T operator[](unsigned Idx) const {
+ return base::getValue(Bits, Idx);
+ }
+
+ bool operator==(const PackedVector &RHS) const {
+ return Bits == RHS.Bits;
+ }
+
+ bool operator!=(const PackedVector &RHS) const {
+ return Bits != RHS.Bits;
+ }
+
+ const PackedVector &operator=(const PackedVector &RHS) {
+ Bits = RHS.Bits;
+ return *this;
+ }
+
+ PackedVector &operator|=(const PackedVector &RHS) {
+ Bits |= RHS.Bits;
+ return *this;
+ }
+
+ void swap(PackedVector &RHS) {
+ Bits.swap(RHS.Bits);
+ }
+};
+
+// Leave BitNum=0 undefined.
+template <typename T>
+class PackedVector<T, 0>;
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/PointerIntPair.h b/contrib/llvm/include/llvm/ADT/PointerIntPair.h
new file mode 100644
index 000000000000..ccdcd1a8d1b9
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/PointerIntPair.h
@@ -0,0 +1,167 @@
+//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- 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 PointerIntPair class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POINTERINTPAIR_H
+#define LLVM_ADT_POINTERINTPAIR_H
+
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cassert>
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapInfo;
+
+/// PointerIntPair - This class implements a pair of a pointer and small
+/// integer. It is designed to represent this in the space required by one
+/// pointer by bitmangling the integer into the low part of the pointer. This
+/// can only be done for small integers: typically up to 3 bits, but it depends
+/// on the number of bits available according to PointerLikeTypeTraits for the
+/// type.
+///
+/// Note that PointerIntPair always puts the Int part in the highest bits
+/// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for
+/// the bool into bit #2, not bit #0, which allows the low two bits to be used
+/// for something else. For example, this allows:
+/// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
+/// ... and the two bools will land in different bits.
+///
+template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
+ typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
+class PointerIntPair {
+ intptr_t Value;
+ enum {
+ /// PointerBitMask - The bits that come from the pointer.
+ PointerBitMask =
+ ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
+
+ /// IntShift - The number of low bits that we reserve for other uses, and
+ /// keep zero.
+ IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
+
+ /// IntMask - This is the unshifted mask for valid bits of the int type.
+ IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
+
+ // ShiftedIntMask - This is the bits for the integer shifted in place.
+ ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
+ };
+public:
+ PointerIntPair() : Value(0) {}
+ PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
+ assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
+ "PointerIntPair formed with integer size too large for pointer");
+ setPointer(Ptr);
+ setInt(Int);
+ }
+
+ PointerTy getPointer() const {
+ return PtrTraits::getFromVoidPointer(
+ reinterpret_cast<void*>(Value & PointerBitMask));
+ }
+
+ IntType getInt() const {
+ return (IntType)((Value >> IntShift) & IntMask);
+ }
+
+ void setPointer(PointerTy Ptr) {
+ intptr_t PtrVal
+ = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
+ assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ "Pointer is not sufficiently aligned");
+ // Preserve all low bits, just update the pointer.
+ Value = PtrVal | (Value & ~PointerBitMask);
+ }
+
+ void setInt(IntType Int) {
+ intptr_t IntVal = Int;
+ assert(IntVal < (1 << IntBits) && "Integer too large for field");
+
+ // Preserve all bits other than the ones we are updating.
+ Value &= ~ShiftedIntMask; // Remove integer field.
+ Value |= IntVal << IntShift; // Set new integer.
+ }
+
+ PointerTy const *getAddrOfPointer() const {
+ return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
+ }
+
+ PointerTy *getAddrOfPointer() {
+ assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
+ "Can only return the address if IntBits is cleared and "
+ "PtrTraits doesn't change the pointer");
+ return reinterpret_cast<PointerTy *>(&Value);
+ }
+
+ void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
+ void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
+
+ static PointerIntPair getFromOpaqueValue(void *V) {
+ PointerIntPair P; P.setFromOpaqueValue(V); return P;
+ }
+
+ bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
+ bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
+ bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
+ bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
+ bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
+ bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
+};
+
+template <typename T> struct isPodLike;
+template<typename PointerTy, unsigned IntBits, typename IntType>
+struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
+ static const bool value = true;
+};
+
+// Provide specialization of DenseMapInfo for PointerIntPair.
+template<typename PointerTy, unsigned IntBits, typename IntType>
+struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
+ typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
+ static Ty getEmptyKey() {
+ intptr_t Val = -1;
+ Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+ return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
+ }
+ static Ty getTombstoneKey() {
+ intptr_t Val = -2;
+ Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+ return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
+ }
+ static unsigned getHashValue(Ty V) {
+ uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
+ return unsigned(IV) ^ unsigned(IV >> 9);
+ }
+ static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
+};
+
+// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
+template<typename PointerTy, unsigned IntBits, typename IntType,
+ typename PtrTraits>
+class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
+ PtrTraits> > {
+public:
+ static inline void *
+ getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerIntPair<PointerTy, IntBits, IntType>
+ getFromVoidPointer(void *P) {
+ return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
+ }
+ enum {
+ NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
+ };
+};
+
+} // end namespace llvm
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/PointerUnion.h b/contrib/llvm/include/llvm/ADT/PointerUnion.h
new file mode 100644
index 000000000000..614b59c844e3
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/PointerUnion.h
@@ -0,0 +1,452 @@
+//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- 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 PointerUnion class, which is a discriminated union of
+// pointer types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POINTERUNION_H
+#define LLVM_ADT_POINTERUNION_H
+
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace llvm {
+
+ template <typename T>
+ struct PointerUnionTypeSelectorReturn {
+ typedef T Return;
+ };
+
+ /// \brief Get a type based on whether two types are the same or not. For:
+ /// @code
+ /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
+ /// @endcode
+ /// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
+ template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
+ struct PointerUnionTypeSelector {
+ typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
+ };
+
+ template <typename T, typename RET_EQ, typename RET_NE>
+ struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
+ typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
+ };
+
+ template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
+ struct PointerUnionTypeSelectorReturn<
+ PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > {
+ typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return
+ Return;
+ };
+
+ /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
+ /// for the two template arguments.
+ template <typename PT1, typename PT2>
+ class PointerUnionUIntTraits {
+ public:
+ static inline void *getAsVoidPointer(void *P) { return P; }
+ static inline void *getFromVoidPointer(void *P) { return P; }
+ enum {
+ PT1BitsAv = PointerLikeTypeTraits<PT1>::NumLowBitsAvailable,
+ PT2BitsAv = PointerLikeTypeTraits<PT2>::NumLowBitsAvailable,
+ NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
+ };
+ };
+
+ /// PointerUnion - This implements a discriminated union of two pointer types,
+ /// and keeps the discriminator bit-mangled into the low bits of the pointer.
+ /// This allows the implementation to be extremely efficient in space, but
+ /// permits a very natural and type-safe API.
+ ///
+ /// Common use patterns would be something like this:
+ /// PointerUnion<int*, float*> P;
+ /// P = (int*)0;
+ /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
+ /// X = P.get<int*>(); // ok.
+ /// Y = P.get<float*>(); // runtime assertion failure.
+ /// Z = P.get<double*>(); // runtime assertion failure (regardless of tag)
+ /// P = (float*)0;
+ /// Y = P.get<float*>(); // ok.
+ /// X = P.get<int*>(); // runtime assertion failure.
+ template <typename PT1, typename PT2>
+ class PointerUnion {
+ public:
+ typedef PointerIntPair<void*, 1, bool,
+ PointerUnionUIntTraits<PT1,PT2> > ValTy;
+ private:
+ ValTy Val;
+
+ struct IsPT1 {
+ static const int Num = 0;
+ };
+ struct IsPT2 {
+ static const int Num = 1;
+ };
+ template <typename T>
+ struct UNION_DOESNT_CONTAIN_TYPE { };
+
+ public:
+ PointerUnion() {}
+
+ PointerUnion(PT1 V) {
+ Val.setPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V)));
+ Val.setInt(0);
+ }
+ PointerUnion(PT2 V) {
+ Val.setPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)));
+ Val.setInt(1);
+ }
+
+ /// isNull - Return true if the pointer held in the union is null,
+ /// regardless of which type it is.
+ bool isNull() const {
+ // Convert from the void* to one of the pointer types, to make sure that
+ // we recursively strip off low bits if we have a nested PointerUnion.
+ return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
+ }
+ operator bool() const { return !isNull(); }
+
+ /// is<T>() return true if the Union currently holds the type matching T.
+ template<typename T>
+ int is() const {
+ typedef typename
+ ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1,
+ ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
+ UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty;
+ int TyNo = Ty::Num;
+ return static_cast<int>(Val.getInt()) == TyNo;
+ }
+
+ /// get<T>() - Return the value of the specified pointer type. If the
+ /// specified pointer type is incorrect, assert.
+ template<typename T>
+ T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
+ }
+
+ /// dyn_cast<T>() - If the current value is of the specified pointer type,
+ /// return it, otherwise return null.
+ template<typename T>
+ T dyn_cast() const {
+ if (is<T>()) return get<T>();
+ return T();
+ }
+
+ /// \brief If the union is set to the first pointer type get an address
+ /// pointing to it.
+ PT1 const *getAddrOfPtr1() const {
+ return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
+ }
+
+ /// \brief If the union is set to the first pointer type get an address
+ /// pointing to it.
+ PT1 *getAddrOfPtr1() {
+ assert(is<PT1>() && "Val is not the first pointer");
+ assert(get<PT1>() == Val.getPointer() &&
+ "Can't get the address because PointerLikeTypeTraits changes the ptr");
+ return (PT1 *)Val.getAddrOfPointer();
+ }
+
+ /// 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(
+ 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);
+ return *this;
+ }
+
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static inline PointerUnion getFromOpaqueValue(void *VP) {
+ PointerUnion V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+ };
+
+ // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
+ // # low bits available = min(PT1bits,PT2bits)-1.
+ template<typename PT1, typename PT2>
+ class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > {
+ public:
+ static inline void *
+ getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion<PT1, PT2>
+ getFromVoidPointer(void *P) {
+ return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+ }
+
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy>
+ ::NumLowBitsAvailable
+ };
+ };
+
+
+ /// PointerUnion3 - This is a pointer union of three pointer types. See
+ /// documentation for PointerUnion for usage.
+ template <typename PT1, typename PT2, typename PT3>
+ class PointerUnion3 {
+ public:
+ typedef PointerUnion<PT1, PT2> InnerUnion;
+ typedef PointerUnion<InnerUnion, PT3> ValTy;
+ private:
+ ValTy Val;
+
+ struct IsInnerUnion {
+ ValTy Val;
+ IsInnerUnion(ValTy val) : Val(val) { }
+ template<typename T>
+ int is() const {
+ return Val.template is<InnerUnion>() &&
+ Val.template get<InnerUnion>().template is<T>();
+ }
+ template<typename T>
+ T get() const {
+ return Val.template get<InnerUnion>().template get<T>();
+ }
+ };
+
+ struct IsPT3 {
+ ValTy Val;
+ IsPT3(ValTy val) : Val(val) { }
+ template<typename T>
+ int is() const {
+ return Val.template is<T>();
+ }
+ template<typename T>
+ T get() const {
+ return Val.template get<T>();
+ }
+ };
+
+ public:
+ PointerUnion3() {}
+
+ PointerUnion3(PT1 V) {
+ Val = InnerUnion(V);
+ }
+ PointerUnion3(PT2 V) {
+ Val = InnerUnion(V);
+ }
+ PointerUnion3(PT3 V) {
+ Val = V;
+ }
+
+ /// isNull - Return true if the pointer held in the union is null,
+ /// regardless of which type it is.
+ bool isNull() const { return Val.isNull(); }
+ operator bool() const { return !isNull(); }
+
+ /// is<T>() return true if the Union currently holds the type matching T.
+ template<typename T>
+ int is() const {
+ // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
+ typedef typename
+ ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
+ ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
+ >::Return Ty;
+ return Ty(Val).template is<T>();
+ }
+
+ /// get<T>() - Return the value of the specified pointer type. If the
+ /// specified pointer type is incorrect, assert.
+ template<typename T>
+ T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
+ typedef typename
+ ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
+ ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
+ >::Return Ty;
+ return Ty(Val).template get<T>();
+ }
+
+ /// dyn_cast<T>() - If the current value is of the specified pointer type,
+ /// return it, otherwise return null.
+ template<typename T>
+ T dyn_cast() const {
+ if (is<T>()) return get<T>();
+ return T();
+ }
+
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion3 &operator=(const PT1 &RHS) {
+ Val = InnerUnion(RHS);
+ return *this;
+ }
+ const PointerUnion3 &operator=(const PT2 &RHS) {
+ Val = InnerUnion(RHS);
+ return *this;
+ }
+ const PointerUnion3 &operator=(const PT3 &RHS) {
+ Val = RHS;
+ return *this;
+ }
+
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static inline PointerUnion3 getFromOpaqueValue(void *VP) {
+ PointerUnion3 V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+ };
+
+ // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
+ // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+ template<typename PT1, typename PT2, typename PT3>
+ class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > {
+ public:
+ static inline void *
+ getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion3<PT1, PT2, PT3>
+ getFromVoidPointer(void *P) {
+ return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
+ }
+
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy>
+ ::NumLowBitsAvailable
+ };
+ };
+
+ /// PointerUnion4 - This is a pointer union of four pointer types. See
+ /// documentation for PointerUnion for usage.
+ template <typename PT1, typename PT2, typename PT3, typename PT4>
+ class PointerUnion4 {
+ public:
+ typedef PointerUnion<PT1, PT2> InnerUnion1;
+ typedef PointerUnion<PT3, PT4> InnerUnion2;
+ typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
+ private:
+ ValTy Val;
+ public:
+ PointerUnion4() {}
+
+ PointerUnion4(PT1 V) {
+ Val = InnerUnion1(V);
+ }
+ PointerUnion4(PT2 V) {
+ Val = InnerUnion1(V);
+ }
+ PointerUnion4(PT3 V) {
+ Val = InnerUnion2(V);
+ }
+ PointerUnion4(PT4 V) {
+ Val = InnerUnion2(V);
+ }
+
+ /// isNull - Return true if the pointer held in the union is null,
+ /// regardless of which type it is.
+ bool isNull() const { return Val.isNull(); }
+ operator bool() const { return !isNull(); }
+
+ /// is<T>() return true if the Union currently holds the type matching T.
+ template<typename T>
+ int is() const {
+ // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
+ typedef typename
+ ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
+ ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
+ >::Return Ty;
+ return Val.template is<Ty>() &&
+ Val.template get<Ty>().template is<T>();
+ }
+
+ /// get<T>() - Return the value of the specified pointer type. If the
+ /// specified pointer type is incorrect, assert.
+ template<typename T>
+ T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
+ typedef typename
+ ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
+ ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
+ >::Return Ty;
+ return Val.template get<Ty>().template get<T>();
+ }
+
+ /// dyn_cast<T>() - If the current value is of the specified pointer type,
+ /// return it, otherwise return null.
+ template<typename T>
+ T dyn_cast() const {
+ if (is<T>()) return get<T>();
+ return T();
+ }
+
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion4 &operator=(const PT1 &RHS) {
+ Val = InnerUnion1(RHS);
+ return *this;
+ }
+ const PointerUnion4 &operator=(const PT2 &RHS) {
+ Val = InnerUnion1(RHS);
+ return *this;
+ }
+ const PointerUnion4 &operator=(const PT3 &RHS) {
+ Val = InnerUnion2(RHS);
+ return *this;
+ }
+ const PointerUnion4 &operator=(const PT4 &RHS) {
+ Val = InnerUnion2(RHS);
+ return *this;
+ }
+
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static inline PointerUnion4 getFromOpaqueValue(void *VP) {
+ PointerUnion4 V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+ };
+
+ // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
+ // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+ template<typename PT1, typename PT2, typename PT3, typename PT4>
+ class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4> > {
+ public:
+ static inline void *
+ getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion4<PT1, PT2, PT3, PT4>
+ getFromVoidPointer(void *P) {
+ return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
+ }
+
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>
+ ::NumLowBitsAvailable
+ };
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/PostOrderIterator.h b/contrib/llvm/include/llvm/ADT/PostOrderIterator.h
new file mode 100644
index 000000000000..63a2b5219f73
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/PostOrderIterator.h
@@ -0,0 +1,240 @@
+//===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build a generic graph
+// post order iterator. This should work over any graph type that has a
+// GraphTraits specialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POSTORDERITERATOR_H
+#define LLVM_ADT_POSTORDERITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+template<class SetType, bool External> // Non-external set
+class po_iterator_storage {
+public:
+ SetType Visited;
+};
+
+/// DFSetTraits - Allow the SetType used to record depth-first search results to
+/// optionally record node postorder.
+template<class SetType>
+struct DFSetTraits {
+ static void finishPostorder(
+ typename SetType::iterator::value_type, SetType &) {}
+};
+
+template<class SetType>
+class po_iterator_storage<SetType, true> {
+public:
+ po_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+template<class GraphT,
+ class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+ bool ExtStorage = false,
+ class GT = GraphTraits<GraphT> >
+class po_iterator : public std::iterator<std::forward_iterator_tag,
+ typename GT::NodeType, ptrdiff_t>,
+ public po_iterator_storage<SetType, ExtStorage> {
+ typedef std::iterator<std::forward_iterator_tag,
+ typename GT::NodeType, ptrdiff_t> super;
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ void traverseChild() {
+ while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ NodeType *BB = *VisitStack.back().second++;
+ if (this->Visited.insert(BB)) { // If the block is not visited...
+ VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+ }
+ }
+ }
+
+ inline po_iterator(NodeType *BB) {
+ this->Visited.insert(BB);
+ VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ inline po_iterator() {} // End is when stack is empty.
+
+ inline po_iterator(NodeType *BB, SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(S) {
+ if (this->Visited.insert(BB)) {
+ VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ }
+
+ inline po_iterator(SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(S) {
+ } // End is when stack is empty.
+public:
+ typedef typename super::pointer pointer;
+ typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); }
+ static inline _Self end (GraphT G) { return _Self(); }
+
+ static inline _Self begin(GraphT G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end (GraphT G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.back().first;
+ }
+
+ // This is a nonstandard operator-> that dereferences the pointer an extra
+ // time... so that you can actually call methods ON the BasicBlock, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ DFSetTraits<SetType>::finishPostorder(VisitStack.back().first,
+ this->Visited);
+ VisitStack.pop_back();
+ if (!VisitStack.empty())
+ traverseChild();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
+template <class T>
+po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); }
+
+// Provide global definitions of external postorder iterators...
+template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
+struct po_ext_iterator : public po_iterator<T, SetType, true> {
+ po_ext_iterator(const po_iterator<T, SetType, true> &V) :
+ po_iterator<T, SetType, true>(V) {}
+};
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_begin(T G, SetType &S) {
+ return po_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
+ return po_ext_iterator<T, SetType>::end(G, S);
+}
+
+// Provide global definitions of inverse post order iterators...
+template <class T,
+ class SetType = std::set<typename GraphTraits<T>::NodeType*>,
+ bool External = false>
+struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
+ ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
+ po_iterator<Inverse<T>, SetType, External> (V) {}
+};
+
+template <class T>
+ipo_iterator<T> ipo_begin(T G, bool Reverse = false) {
+ return ipo_iterator<T>::begin(G, Reverse);
+}
+
+template <class T>
+ipo_iterator<T> ipo_end(T G){
+ return ipo_iterator<T>::end(G);
+}
+
+//Provide global definitions of external inverse postorder iterators...
+template <class T,
+ class SetType = std::set<typename GraphTraits<T>::NodeType*> >
+struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
+ ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+ ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+};
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::end(G, S);
+}
+
+//===--------------------------------------------------------------------===//
+// Reverse Post Order CFG iterator code
+//===--------------------------------------------------------------------===//
+//
+// This is used to visit basic blocks in a method in reverse post order. This
+// class is awkward to use because I don't know a good incremental algorithm to
+// computer RPO from a graph. Because of this, the construction of the
+// ReversePostOrderTraversal object is expensive (it must walk the entire graph
+// with a postorder iterator to build the data structures). The moral of this
+// story is: Don't create more ReversePostOrderTraversal classes than necessary.
+//
+// This class should be used like this:
+// {
+// ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// }
+//
+
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class ReversePostOrderTraversal {
+ typedef typename GT::NodeType NodeType;
+ std::vector<NodeType*> Blocks; // Block list in normal PO order
+ inline void Initialize(NodeType *BB) {
+ copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
+ }
+public:
+ typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
+
+ inline ReversePostOrderTraversal(GraphT G) {
+ Initialize(GT::getEntryNode(G));
+ }
+
+ // Because we want a reverse post order, use reverse iterators from the vector
+ inline rpo_iterator begin() { return Blocks.rbegin(); }
+ inline rpo_iterator end() { return Blocks.rend(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/PriorityQueue.h b/contrib/llvm/include/llvm/ADT/PriorityQueue.h
new file mode 100644
index 000000000000..bf8a68708163
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/PriorityQueue.h
@@ -0,0 +1,84 @@
+//===- llvm/ADT/PriorityQueue.h - Priority queues ---------------*- 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 PriorityQueue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_PRIORITY_QUEUE_H
+#define LLVM_ADT_PRIORITY_QUEUE_H
+
+#include <algorithm>
+#include <queue>
+
+namespace llvm {
+
+/// PriorityQueue - This class behaves like std::priority_queue and
+/// provides a few additional convenience functions.
+///
+template<class T,
+ class Sequence = std::vector<T>,
+ class Compare = std::less<typename Sequence::value_type> >
+class PriorityQueue : public std::priority_queue<T, Sequence, Compare> {
+public:
+ explicit PriorityQueue(const Compare &compare = Compare(),
+ const Sequence &sequence = Sequence())
+ : std::priority_queue<T, Sequence, Compare>(compare, sequence)
+ {}
+
+ template<class Iterator>
+ PriorityQueue(Iterator begin, Iterator end,
+ const Compare &compare = Compare(),
+ const Sequence &sequence = Sequence())
+ : std::priority_queue<T, Sequence, Compare>(begin, end, compare, sequence)
+ {}
+
+ /// erase_one - Erase one element from the queue, regardless of its
+ /// position. This operation performs a linear search to find an element
+ /// equal to t, but then uses all logarithmic-time algorithms to do
+ /// the erase operation.
+ ///
+ void erase_one(const T &t) {
+ // Linear-search to find the element.
+ typename Sequence::size_type i =
+ std::find(this->c.begin(), this->c.end(), t) - this->c.begin();
+
+ // Logarithmic-time heap bubble-up.
+ while (i != 0) {
+ typename Sequence::size_type parent = (i - 1) / 2;
+ this->c[i] = this->c[parent];
+ i = parent;
+ }
+
+ // The element we want to remove is now at the root, so we can use
+ // priority_queue's plain pop to remove it.
+ this->pop();
+ }
+
+ /// reheapify - If an element in the queue has changed in a way that
+ /// affects its standing in the comparison function, the queue's
+ /// internal state becomes invalid. Calling reheapify() resets the
+ /// queue's state, making it valid again. This operation has time
+ /// complexity proportional to the number of elements in the queue,
+ /// so don't plan to use it a lot.
+ ///
+ void reheapify() {
+ std::make_heap(this->c.begin(), this->c.end(), this->comp);
+ }
+
+ /// clear - Erase all elements from the queue.
+ ///
+ void clear() {
+ this->c.clear();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SCCIterator.h b/contrib/llvm/include/llvm/ADT/SCCIterator.h
new file mode 100644
index 000000000000..48436c667474
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SCCIterator.h
@@ -0,0 +1,220 @@
+//===---- ADT/SCCIterator.h - Strongly Connected Comp. Iter. ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected
+// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm.
+//
+// The SCC iterator has the important property that if a node in SCC S1 has an
+// edge to a node in SCC S2, then it visits S1 *after* S2.
+//
+// To visit S1 *before* S2, use the scc_iterator on the Inverse graph.
+// (NOTE: This requires some simple wrappers and is not supported yet.)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCCITERATOR_H
+#define LLVM_ADT_SCCITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// scc_iterator - Enumerate the SCCs of a directed graph, in
+/// reverse topological order of the SCC DAG.
+///
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class scc_iterator
+ : public std::iterator<std::forward_iterator_tag,
+ std::vector<typename GT::NodeType>, ptrdiff_t> {
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+ typedef std::vector<NodeType*> SccTy;
+ typedef std::iterator<std::forward_iterator_tag,
+ std::vector<typename GT::NodeType>, ptrdiff_t> super;
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ // The visit counters used to detect when a complete SCC is on the stack.
+ // visitNum is the global counter.
+ // nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
+ unsigned visitNum;
+ DenseMap<NodeType *, unsigned> nodeVisitNumbers;
+
+ // SCCNodeStack - Stack holding nodes of the SCC.
+ std::vector<NodeType *> SCCNodeStack;
+
+ // CurrentSCC - The current SCC, retrieved using operator*().
+ SccTy CurrentSCC;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ // MinVisitNumStack - Stack holding the "min" values for each node in the DFS.
+ // This is used to track the minimum uplink values for all children of
+ // the corresponding node on the VisitStack.
+ std::vector<unsigned> MinVisitNumStack;
+
+ // A single "visit" within the non-recursive DFS traversal.
+ void DFSVisitOne(NodeType *N) {
+ ++visitNum; // Global counter for the visit order
+ nodeVisitNumbers[N] = visitNum;
+ SCCNodeStack.push_back(N);
+ MinVisitNumStack.push_back(visitNum);
+ VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
+ //dbgs() << "TarjanSCC: Node " << N <<
+ // " : visitNum = " << visitNum << "\n";
+ }
+
+ // The stack-based DFS traversal; defined below.
+ void DFSVisitChildren() {
+ assert(!VisitStack.empty());
+ while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ // TOS has at least one more child so continue DFS
+ NodeType *childN = *VisitStack.back().second++;
+ if (!nodeVisitNumbers.count(childN)) {
+ // this node has never been seen.
+ DFSVisitOne(childN);
+ continue;
+ }
+
+ unsigned childNum = nodeVisitNumbers[childN];
+ if (MinVisitNumStack.back() > childNum)
+ MinVisitNumStack.back() = childNum;
+ }
+ }
+
+ // Compute the next SCC using the DFS traversal.
+ void GetNextSCC() {
+ assert(VisitStack.size() == MinVisitNumStack.size());
+ CurrentSCC.clear(); // Prepare to compute the next SCC
+ while (!VisitStack.empty()) {
+ DFSVisitChildren();
+ assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
+ NodeType *visitingN = VisitStack.back().first;
+ unsigned minVisitNum = MinVisitNumStack.back();
+ VisitStack.pop_back();
+ MinVisitNumStack.pop_back();
+ if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
+ MinVisitNumStack.back() = minVisitNum;
+
+ //dbgs() << "TarjanSCC: Popped node " << visitingN <<
+ // " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+ // nodeVisitNumbers[visitingN] << "\n";
+
+ if (minVisitNum != nodeVisitNumbers[visitingN])
+ continue;
+
+ // A full SCC is on the SCCNodeStack! It includes all nodes below
+ // visitingN on the stack. Copy those nodes to CurrentSCC,
+ // reset their minVisit values, and return (this suspends
+ // the DFS traversal till the next ++).
+ do {
+ CurrentSCC.push_back(SCCNodeStack.back());
+ SCCNodeStack.pop_back();
+ nodeVisitNumbers[CurrentSCC.back()] = ~0U;
+ } while (CurrentSCC.back() != visitingN);
+ return;
+ }
+ }
+
+ inline scc_iterator(NodeType *entryN) : visitNum(0) {
+ DFSVisitOne(entryN);
+ GetNextSCC();
+ }
+ inline scc_iterator() { /* End is when DFS stack is empty */ }
+
+public:
+ typedef scc_iterator<GraphT, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
+ static inline _Self end (const GraphT &) { return _Self(); }
+
+ // Direct loop termination test: I.isAtEnd() is more efficient than I == end()
+ inline bool isAtEnd() const {
+ assert(!CurrentSCC.empty() || VisitStack.empty());
+ return CurrentSCC.empty();
+ }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ // Iterator traversal: forward iteration only
+ inline _Self& operator++() { // Preincrement
+ GetNextSCC();
+ return *this;
+ }
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // Retrieve a reference to the current SCC
+ inline const SccTy &operator*() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+ inline SccTy &operator*() {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+
+ // hasLoop() -- Test if the current SCC has a loop. If it has more than one
+ // node, this is trivially true. If not, it may still contain a loop if the
+ // node has an edge back to itself.
+ bool hasLoop() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ if (CurrentSCC.size() > 1) return true;
+ NodeType *N = CurrentSCC.front();
+ for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI)
+ if (*CI == N)
+ return true;
+ return false;
+ }
+
+ /// ReplaceNode - This informs the scc_iterator that the specified Old node
+ /// has been deleted, and New is to be used in its place.
+ void ReplaceNode(NodeType *Old, NodeType *New) {
+ assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?");
+ nodeVisitNumbers[New] = nodeVisitNumbers[Old];
+ nodeVisitNumbers.erase(Old);
+ }
+};
+
+
+// Global constructor for the SCC iterator.
+template <class T>
+scc_iterator<T> scc_begin(const T &G) {
+ return scc_iterator<T>::begin(G);
+}
+
+template <class T>
+scc_iterator<T> scc_end(const T &G) {
+ return scc_iterator<T>::end(G);
+}
+
+template <class T>
+scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
+ return scc_iterator<Inverse<T> >::begin(G);
+}
+
+template <class T>
+scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
+ return scc_iterator<Inverse<T> >::end(G);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/STLExtras.h b/contrib/llvm/include/llvm/ADT/STLExtras.h
new file mode 100644
index 000000000000..5da906dc8cf0
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/STLExtras.h
@@ -0,0 +1,302 @@
+//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL at all.
+//
+// No library is required when using these functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STLEXTRAS_H
+#define LLVM_ADT_STLEXTRAS_H
+
+#include <cstddef> // for std::size_t
+#include <cstdlib> // for qsort
+#include <functional>
+#include <iterator>
+#include <utility> // for std::pair
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+template<class Ty>
+struct less_ptr : public std::binary_function<Ty, Ty, bool> {
+ bool operator()(const Ty* left, const Ty* right) const {
+ return *left < *right;
+ }
+};
+
+template<class Ty>
+struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
+ bool operator()(const Ty* left, const Ty* right) const {
+ return *right < *left;
+ }
+};
+
+// deleter - Very very very simple method that is used to invoke operator
+// delete on something. It is used like this:
+//
+// for_each(V.begin(), B.end(), deleter<Interval>);
+//
+template <class T>
+static inline void deleter(T *Ptr) {
+ delete Ptr;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <iterator>
+//===----------------------------------------------------------------------===//
+
+// mapped_iterator - This is a simple iterator adapter that causes a function to
+// be dereferenced whenever operator* is invoked on the iterator.
+//
+template <class RootIt, class UnaryFunc>
+class mapped_iterator {
+ RootIt current;
+ UnaryFunc Fn;
+public:
+ typedef typename std::iterator_traits<RootIt>::iterator_category
+ iterator_category;
+ typedef typename std::iterator_traits<RootIt>::difference_type
+ difference_type;
+ typedef typename UnaryFunc::result_type value_type;
+
+ typedef void pointer;
+ //typedef typename UnaryFunc::result_type *pointer;
+ typedef void reference; // Can't modify value returned by fn
+
+ typedef RootIt iterator_type;
+ typedef mapped_iterator<RootIt, UnaryFunc> _Self;
+
+ inline const RootIt &getCurrent() const { return current; }
+ inline const UnaryFunc &getFunc() const { return Fn; }
+
+ inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
+ : current(I), Fn(F) {}
+ inline mapped_iterator(const mapped_iterator &It)
+ : current(It.current), Fn(It.Fn) {}
+
+ inline value_type operator*() const { // All this work to do this
+ return Fn(*current); // little change
+ }
+
+ _Self& operator++() { ++current; return *this; }
+ _Self& operator--() { --current; return *this; }
+ _Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
+ _Self operator--(int) { _Self __tmp = *this; --current; return __tmp; }
+ _Self operator+ (difference_type n) const {
+ return _Self(current + n, Fn);
+ }
+ _Self& operator+= (difference_type n) { current += n; return *this; }
+ _Self operator- (difference_type n) const {
+ return _Self(current - n, Fn);
+ }
+ _Self& operator-= (difference_type n) { current -= n; return *this; }
+ reference operator[](difference_type n) const { return *(*this + n); }
+
+ inline bool operator!=(const _Self &X) const { return !operator==(X); }
+ inline bool operator==(const _Self &X) const { return current == X.current; }
+ inline bool operator< (const _Self &X) const { return current < X.current; }
+
+ inline difference_type operator-(const _Self &X) const {
+ return current - X.current;
+ }
+};
+
+template <class _Iterator, class Func>
+inline mapped_iterator<_Iterator, Func>
+operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
+ const mapped_iterator<_Iterator, Func>& X) {
+ return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc());
+}
+
+
+// map_iterator - Provide a convenient way to create mapped_iterators, just like
+// make_pair is useful for creating pairs...
+//
+template <class ItTy, class FuncTy>
+inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
+ return mapped_iterator<ItTy, FuncTy>(I, F);
+}
+
+
+// next/prior - These functions unlike std::advance do not modify the
+// passed iterator but return a copy.
+//
+// next(myIt) returns copy of myIt incremented once
+// next(myIt, n) returns copy of myIt incremented n times
+// prior(myIt) returns copy of myIt decremented once
+// prior(myIt, n) returns copy of myIt decremented n times
+
+template <typename ItTy, typename Dist>
+inline ItTy next(ItTy it, Dist n)
+{
+ std::advance(it, n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy next(ItTy it)
+{
+ return ++it;
+}
+
+template <typename ItTy, typename Dist>
+inline ItTy prior(ItTy it, Dist n)
+{
+ std::advance(it, -n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy prior(ItTy it)
+{
+ return --it;
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <utility>
+//===----------------------------------------------------------------------===//
+
+// tie - this function ties two objects and returns a temporary object
+// that is assignable from a std::pair. This can be used to make code
+// more readable when using values returned from functions bundled in
+// a std::pair. Since an example is worth 1000 words:
+//
+// typedef std::map<int, int> Int2IntMap;
+//
+// Int2IntMap myMap;
+// Int2IntMap::iterator where;
+// bool inserted;
+// tie(where, inserted) = myMap.insert(std::make_pair(123,456));
+//
+// if (inserted)
+// // do stuff
+// else
+// // do other stuff
+template <typename T1, typename T2>
+struct tier {
+ typedef T1 &first_type;
+ typedef T2 &second_type;
+
+ first_type first;
+ second_type second;
+
+ tier(first_type f, second_type s) : first(f), second(s) { }
+ tier& operator=(const std::pair<T1, T2>& p) {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+};
+
+template <typename T1, typename T2>
+inline tier<T1, T2> tie(T1& f, T2& s) {
+ return tier<T1, T2>(f, s);
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions for arrays
+//===----------------------------------------------------------------------===//
+
+/// Find where an array ends (for ending iterators)
+/// This returns a pointer to the byte immediately
+/// after the end of an array.
+template<class T, std::size_t N>
+inline T *array_endof(T (&x)[N]) {
+ return x+N;
+}
+
+/// Find the length of an array.
+template<class T, std::size_t N>
+inline size_t array_lengthof(T (&)[N]) {
+ return N;
+}
+
+/// array_pod_sort_comparator - This is helper function for array_pod_sort,
+/// which just uses operator< on T.
+template<typename T>
+static inline int array_pod_sort_comparator(const void *P1, const void *P2) {
+ if (*reinterpret_cast<const T*>(P1) < *reinterpret_cast<const T*>(P2))
+ return -1;
+ if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1))
+ return 1;
+ return 0;
+}
+
+/// get_array_pad_sort_comparator - This is an internal helper function used to
+/// get type deduction of T right.
+template<typename T>
+static int (*get_array_pad_sort_comparator(const T &))
+ (const void*, const void*) {
+ return array_pod_sort_comparator<T>;
+}
+
+
+/// array_pod_sort - This sorts an array with the specified start and end
+/// extent. This is just like std::sort, except that it calls qsort instead of
+/// using an inlined template. qsort is slightly slower than std::sort, but
+/// most sorts are not performance critical in LLVM and std::sort has to be
+/// template instantiated for each type, leading to significant measured code
+/// bloat. This function should generally be used instead of std::sort where
+/// possible.
+///
+/// This function assumes that you have simple POD-like types that can be
+/// compared with operator< and can be moved with memcpy. If this isn't true,
+/// you should use std::sort.
+///
+/// NOTE: If qsort_r were portable, we could allow a custom comparator and
+/// default to std::less.
+template<class IteratorTy>
+static 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));
+}
+
+template<class IteratorTy>
+static inline void array_pod_sort(IteratorTy Start, IteratorTy End,
+ int (*Compare)(const void*, const void*)) {
+ // Don't dereference start iterator of empty sequence.
+ if (Start == End) return;
+ qsort(&*Start, End-Start, sizeof(*Start), Compare);
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <algorithm>
+//===----------------------------------------------------------------------===//
+
+/// For a container of pointers, deletes the pointers and then clears the
+/// container.
+template<typename Container>
+void DeleteContainerPointers(Container &C) {
+ for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
+ delete *I;
+ C.clear();
+}
+
+/// In a container of pairs (usually a map) whose second element is a pointer,
+/// deletes the second elements and then clears the container.
+template<typename Container>
+void DeleteContainerSeconds(Container &C) {
+ for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I)
+ delete I->second;
+ C.clear();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ScopedHashTable.h b/contrib/llvm/include/llvm/ADT/ScopedHashTable.h
new file mode 100644
index 000000000000..a6803ee0eddf
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ScopedHashTable.h
@@ -0,0 +1,256 @@
+//===- ScopedHashTable.h - A simple scoped hash table ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an efficient scoped hash table, which is useful for
+// things like dominator-based optimizations. This allows clients to do things
+// like this:
+//
+// ScopedHashTable<int, int> HT;
+// {
+// ScopedHashTableScope<int, int> Scope1(HT);
+// HT.insert(0, 0);
+// HT.insert(1, 1);
+// {
+// ScopedHashTableScope<int, int> Scope2(HT);
+// HT.insert(0, 42);
+// }
+// }
+//
+// Looking up the value for "0" in the Scope2 block will return 42. Looking
+// up the value for 0 before 42 is inserted or after Scope2 is popped will
+// return 0.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCOPEDHASHTABLE_H
+#define LLVM_ADT_SCOPEDHASHTABLE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+ typename AllocatorTy = MallocAllocator>
+class ScopedHashTable;
+
+template <typename K, typename V>
+class ScopedHashTableVal {
+ ScopedHashTableVal *NextInScope;
+ ScopedHashTableVal *NextForKey;
+ K Key;
+ V Val;
+ ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {}
+public:
+
+ const K &getKey() const { return Key; }
+ const V &getValue() const { return Val; }
+ V &getValue() { return Val; }
+
+ ScopedHashTableVal *getNextForKey() { return NextForKey; }
+ const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
+ ScopedHashTableVal *getNextInScope() { return NextInScope; }
+
+ template <typename AllocatorTy>
+ static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope,
+ ScopedHashTableVal *nextForKey,
+ const K &key, const V &val,
+ AllocatorTy &Allocator) {
+ ScopedHashTableVal *New = Allocator.template Allocate<ScopedHashTableVal>();
+ // Set up the value.
+ new (New) ScopedHashTableVal(key, val);
+ New->NextInScope = nextInScope;
+ New->NextForKey = nextForKey;
+ return New;
+ }
+
+ template <typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~ScopedHashTableVal();
+ Allocator.Deallocate(this);
+ }
+};
+
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>,
+ typename AllocatorTy = MallocAllocator>
+class ScopedHashTableScope {
+ /// HT - The hashtable that we are active for.
+ ScopedHashTable<K, V, KInfo, AllocatorTy> &HT;
+
+ /// PrevScope - This is the scope that we are shadowing in HT.
+ ScopedHashTableScope *PrevScope;
+
+ /// LastValInScope - This is the last value that was inserted for this scope
+ /// or null if none have been inserted yet.
+ ScopedHashTableVal<K, V> *LastValInScope;
+ void operator=(ScopedHashTableScope&); // DO NOT IMPLEMENT
+ ScopedHashTableScope(ScopedHashTableScope&); // DO NOT IMPLEMENT
+public:
+ ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
+ ~ScopedHashTableScope();
+
+ ScopedHashTableScope *getParentScope() { return PrevScope; }
+ const ScopedHashTableScope *getParentScope() const { return PrevScope; }
+
+private:
+ friend class ScopedHashTable<K, V, KInfo, AllocatorTy>;
+ ScopedHashTableVal<K, V> *getLastValInScope() {
+ return LastValInScope;
+ }
+ void setLastValInScope(ScopedHashTableVal<K, V> *Val) {
+ LastValInScope = Val;
+ }
+};
+
+
+template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+class ScopedHashTableIterator {
+ ScopedHashTableVal<K, V> *Node;
+public:
+ ScopedHashTableIterator(ScopedHashTableVal<K, V> *node) : Node(node) {}
+
+ V &operator*() const {
+ assert(Node && "Dereference end()");
+ return Node->getValue();
+ }
+ V *operator->() const {
+ return &Node->getValue();
+ }
+
+ bool operator==(const ScopedHashTableIterator &RHS) const {
+ return Node == RHS.Node;
+ }
+ bool operator!=(const ScopedHashTableIterator &RHS) const {
+ return Node != RHS.Node;
+ }
+
+ inline ScopedHashTableIterator& operator++() { // Preincrement
+ assert(Node && "incrementing past end()");
+ Node = Node->getNextForKey();
+ return *this;
+ }
+ ScopedHashTableIterator operator++(int) { // Postincrement
+ ScopedHashTableIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+
+template <typename K, typename V, typename KInfo, typename AllocatorTy>
+class ScopedHashTable {
+public:
+ /// ScopeTy - This is a helpful typedef that allows clients to get easy access
+ /// to the name of the scope for this hash table.
+ typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
+private:
+ typedef ScopedHashTableVal<K, V> ValTy;
+ DenseMap<K, ValTy*, KInfo> TopLevelMap;
+ ScopeTy *CurScope;
+
+ AllocatorTy Allocator;
+
+ ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
+ void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
+ friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
+public:
+ ScopedHashTable() : CurScope(0) {}
+ ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {}
+ ~ScopedHashTable() {
+ assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!");
+ }
+
+
+ /// Access to the allocator.
+ typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy;
+ typedef typename ReferenceAdder<const AllocatorTy>::result AllocatorCRefTy;
+ AllocatorRefTy getAllocator() { return Allocator; }
+ AllocatorCRefTy getAllocator() const { return Allocator; }
+
+ bool count(const K &Key) const {
+ return TopLevelMap.count(Key);
+ }
+
+ V lookup(const K &Key) {
+ typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key);
+ if (I != TopLevelMap.end())
+ return I->second->getValue();
+
+ return V();
+ }
+
+ void insert(const K &Key, const V &Val) {
+ insertIntoScope(CurScope, Key, Val);
+ }
+
+ typedef ScopedHashTableIterator<K, V, KInfo> iterator;
+
+ iterator end() { return iterator(0); }
+
+ iterator begin(const K &Key) {
+ typename DenseMap<K, ValTy*, KInfo>::iterator I =
+ TopLevelMap.find(Key);
+ if (I == TopLevelMap.end()) return end();
+ return iterator(I->second);
+ }
+
+ ScopeTy *getCurScope() { return CurScope; }
+ const ScopeTy *getCurScope() const { return CurScope; }
+
+ /// insertIntoScope - This inserts the specified key/value at the specified
+ /// (possibly not the current) scope. While it is ok to insert into a scope
+ /// that isn't the current one, it isn't ok to insert *underneath* an existing
+ /// value of the specified key.
+ void insertIntoScope(ScopeTy *S, const K &Key, const V &Val) {
+ assert(S && "No scope active!");
+ ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key];
+ KeyEntry = ValTy::Create(S->getLastValInScope(), KeyEntry, Key, Val,
+ Allocator);
+ S->setLastValInScope(KeyEntry);
+ }
+};
+
+/// ScopedHashTableScope ctor - Install this as the current scope for the hash
+/// table.
+template <typename K, typename V, typename KInfo, typename Allocator>
+ScopedHashTableScope<K, V, KInfo, Allocator>::
+ ScopedHashTableScope(ScopedHashTable<K, V, KInfo, Allocator> &ht) : HT(ht) {
+ PrevScope = HT.CurScope;
+ HT.CurScope = this;
+ LastValInScope = 0;
+}
+
+template <typename K, typename V, typename KInfo, typename Allocator>
+ScopedHashTableScope<K, V, KInfo, Allocator>::~ScopedHashTableScope() {
+ assert(HT.CurScope == this && "Scope imbalance!");
+ HT.CurScope = PrevScope;
+
+ // Pop and delete all values corresponding to this scope.
+ while (ScopedHashTableVal<K, V> *ThisEntry = LastValInScope) {
+ // Pop this value out of the TopLevelMap.
+ if (ThisEntry->getNextForKey() == 0) {
+ assert(HT.TopLevelMap[ThisEntry->getKey()] == ThisEntry &&
+ "Scope imbalance!");
+ HT.TopLevelMap.erase(ThisEntry->getKey());
+ } else {
+ ScopedHashTableVal<K, V> *&KeyEntry = HT.TopLevelMap[ThisEntry->getKey()];
+ assert(KeyEntry == ThisEntry && "Scope imbalance!");
+ KeyEntry = ThisEntry->getNextForKey();
+ }
+
+ // Pop this value out of the scope.
+ LastValInScope = ThisEntry->getNextInScope();
+
+ // Delete this entry.
+ ThisEntry->Destroy(HT.getAllocator());
+ }
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SetOperations.h b/contrib/llvm/include/llvm/ADT/SetOperations.h
new file mode 100644
index 000000000000..71f5db380f6e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SetOperations.h
@@ -0,0 +1,71 @@
+//===-- llvm/ADT/SetOperations.h - Generic Set Operations -------*- 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 generic set operations that may be used on set's of
+// different types, and different element types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETOPERATIONS_H
+#define LLVM_ADT_SETOPERATIONS_H
+
+namespace llvm {
+
+/// set_union(A, B) - Compute A := A u B, return whether A changed.
+///
+template <class S1Ty, class S2Ty>
+bool set_union(S1Ty &S1, const S2Ty &S2) {
+ bool Changed = false;
+
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ if (S1.insert(*SI).second)
+ Changed = true;
+
+ return Changed;
+}
+
+/// set_intersect(A, B) - Compute A := A ^ B
+/// Identical to set_intersection, except that it works on set<>'s and
+/// is nicer to use. Functionally, this iterates through S1, removing
+/// elements that are not contained in S2.
+///
+template <class S1Ty, class S2Ty>
+void set_intersect(S1Ty &S1, const S2Ty &S2) {
+ for (typename S1Ty::iterator I = S1.begin(); I != S1.end();) {
+ const typename S1Ty::key_type &E = *I;
+ ++I;
+ if (!S2.count(E)) S1.erase(E); // Erase element if not in S2
+ }
+}
+
+/// set_difference(A, B) - Return A - B
+///
+template <class S1Ty, class S2Ty>
+S1Ty set_difference(const S1Ty &S1, const S2Ty &S2) {
+ S1Ty Result;
+ for (typename S1Ty::const_iterator SI = S1.begin(), SE = S1.end();
+ SI != SE; ++SI)
+ if (!S2.count(*SI)) // if the element is not in set2
+ Result.insert(*SI);
+ return Result;
+}
+
+/// set_subtract(A, B) - Compute A := A - B
+///
+template <class S1Ty, class S2Ty>
+void set_subtract(S1Ty &S1, const S2Ty &S2) {
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ S1.erase(*SI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SetVector.h b/contrib/llvm/include/llvm/ADT/SetVector.h
new file mode 100644
index 000000000000..965f0deacaa2
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SetVector.h
@@ -0,0 +1,184 @@
+//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- 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 set that has insertion order iteration
+// characteristics. This is useful for keeping a set of things that need to be
+// visited later but in a deterministic order (insertion order). The interface
+// is purposefully minimal.
+//
+// This file defines SetVector and SmallSetVector, which performs no allocations
+// if the SetVector has less than a certain number of elements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETVECTOR_H
+#define LLVM_ADT_SETVECTOR_H
+
+#include "llvm/ADT/SmallSet.h"
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+/// 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 {
+public:
+ typedef T value_type;
+ typedef T key_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef Set set_type;
+ typedef Vector vector_type;
+ typedef typename vector_type::const_iterator iterator;
+ typedef typename vector_type::const_iterator const_iterator;
+ typedef typename vector_type::size_type size_type;
+
+ /// @brief Construct an empty SetVector
+ SetVector() {}
+
+ /// @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.
+ bool empty() const {
+ return vector_.empty();
+ }
+
+ /// @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.
+ iterator begin() {
+ return vector_.begin();
+ }
+
+ /// @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.
+ iterator end() {
+ return vector_.end();
+ }
+
+ /// @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.
+ const T &back() const {
+ assert(!empty() && "Cannot call back() on empty SetVector!");
+ return vector_.back();
+ }
+
+ /// @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.
+ bool insert(const value_type &X) {
+ bool result = set_.insert(X);
+ if (result)
+ vector_.push_back(X);
+ return result;
+ }
+
+ /// @brief Insert a range of elements into the SetVector.
+ template<typename It>
+ void insert(It Start, It End) {
+ for (; Start != End; ++Start)
+ if (set_.insert(*Start))
+ vector_.push_back(*Start);
+ }
+
+ /// @brief Remove an item from the set vector.
+ bool remove(const value_type& X) {
+ if (set_.erase(X)) {
+ typename vector_type::iterator I =
+ std::find(vector_.begin(), vector_.end(), X);
+ assert(I != vector_.end() && "Corrupted SetVector instances!");
+ vector_.erase(I);
+ return true;
+ }
+ 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.
+ size_type count(const key_type &key) const {
+ return set_.count(key);
+ }
+
+ /// @brief Completely clear the SetVector
+ void clear() {
+ set_.clear();
+ vector_.clear();
+ }
+
+ /// @brief Remove the last element of the SetVector.
+ void pop_back() {
+ assert(!empty() && "Cannot remove an element from an empty SetVector!");
+ set_.erase(back());
+ vector_.pop_back();
+ }
+
+ T pop_back_val() {
+ T Ret = back();
+ pop_back();
+ return Ret;
+ }
+
+ bool operator==(const SetVector &that) const {
+ return vector_ == that.vector_;
+ }
+
+ bool operator!=(const SetVector &that) const {
+ return vector_ != that.vector_;
+ }
+
+private:
+ set_type set_; ///< The set.
+ vector_type vector_; ///< The vector.
+};
+
+/// SmallSetVector - 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
+ template<typename It>
+ SmallSetVector(It Start, It End) {
+ this->insert(Start, End);
+ }
+};
+
+} // End llvm namespace
+
+// vim: sw=2 ai
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SmallBitVector.h b/contrib/llvm/include/llvm/ADT/SmallBitVector.h
new file mode 100644
index 000000000000..a3469a1c6226
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SmallBitVector.h
@@ -0,0 +1,461 @@
+//===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SmallBitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLBITVECTOR_H
+#define LLVM_ADT_SMALLBITVECTOR_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+
+namespace llvm {
+
+/// SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array),
+/// optimized for the case when the array is small. It contains one
+/// pointer-sized field, which is directly used as a plain collection of bits
+/// when possible, or as a pointer to a larger heap-allocated array when
+/// necessary. This allows normal "small" cases to be fast without losing
+/// generality for large inputs.
+///
+class SmallBitVector {
+ // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
+ // unnecessary level of indirection. It would be more efficient to use a
+ // pointer to memory containing size, allocation size, and the array of bits.
+ uintptr_t X;
+
+ enum {
+ // The number of bits in this class.
+ NumBaseBits = sizeof(uintptr_t) * CHAR_BIT,
+
+ // One bit is used to discriminate between small and large mode. The
+ // remaining bits are used for the small-mode representation.
+ SmallNumRawBits = NumBaseBits - 1,
+
+ // A few more bits are used to store the size of the bit set in small mode.
+ // Theoretically this is a ceil-log2. These bits are encoded in the most
+ // significant bits of the raw bits.
+ SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
+ NumBaseBits == 64 ? 6 :
+ SmallNumRawBits),
+
+ // The remaining bits are used to store the actual set in small mode.
+ SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
+ };
+
+public:
+ // Encapsulation of a single bit.
+ class reference {
+ SmallBitVector &TheVector;
+ unsigned BitPos;
+
+ public:
+ reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
+
+ reference& operator=(reference t) {
+ *this = bool(t);
+ return *this;
+ }
+
+ reference& operator=(bool t) {
+ if (t)
+ TheVector.set(BitPos);
+ else
+ TheVector.reset(BitPos);
+ return *this;
+ }
+
+ operator bool() const {
+ return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
+ }
+ };
+
+private:
+ bool isSmall() const {
+ return X & uintptr_t(1);
+ }
+
+ BitVector *getPointer() const {
+ assert(!isSmall());
+ return reinterpret_cast<BitVector *>(X);
+ }
+
+ void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) {
+ X = 1;
+ setSmallSize(NewSize);
+ setSmallBits(NewSmallBits);
+ }
+
+ void switchToLarge(BitVector *BV) {
+ X = reinterpret_cast<uintptr_t>(BV);
+ assert(!isSmall() && "Tried to use an unaligned pointer");
+ }
+
+ // Return all the bits used for the "small" representation; this includes
+ // bits for the size as well as the element bits.
+ uintptr_t getSmallRawBits() const {
+ assert(isSmall());
+ return X >> 1;
+ }
+
+ void setSmallRawBits(uintptr_t NewRawBits) {
+ assert(isSmall());
+ X = (NewRawBits << 1) | uintptr_t(1);
+ }
+
+ // Return the size.
+ size_t getSmallSize() const {
+ return getSmallRawBits() >> SmallNumDataBits;
+ }
+
+ void setSmallSize(size_t Size) {
+ setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
+ }
+
+ // Return the element bits.
+ uintptr_t getSmallBits() const {
+ return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
+ }
+
+ void setSmallBits(uintptr_t NewBits) {
+ setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
+ (getSmallSize() << SmallNumDataBits));
+ }
+
+public:
+ /// SmallBitVector default ctor - Creates an empty bitvector.
+ SmallBitVector() : X(1) {}
+
+ /// SmallBitVector ctor - Creates a bitvector of specified number of bits. All
+ /// bits are initialized to the specified value.
+ explicit SmallBitVector(unsigned s, bool t = false) {
+ if (s <= SmallNumDataBits)
+ switchToSmall(t ? ~uintptr_t(0) : 0, s);
+ else
+ switchToLarge(new BitVector(s, t));
+ }
+
+ /// SmallBitVector copy ctor.
+ SmallBitVector(const SmallBitVector &RHS) {
+ if (RHS.isSmall())
+ X = RHS.X;
+ else
+ switchToLarge(new BitVector(*RHS.getPointer()));
+ }
+
+ ~SmallBitVector() {
+ if (!isSmall())
+ delete getPointer();
+ }
+
+ /// empty - Tests whether there are no bits in this bitvector.
+ bool empty() const {
+ return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
+ }
+
+ /// size - Returns the number of bits in this bitvector.
+ size_t size() const {
+ return isSmall() ? getSmallSize() : getPointer()->size();
+ }
+
+ /// count - Returns the number of bits which are set.
+ unsigned count() const {
+ if (isSmall()) {
+ uintptr_t Bits = getSmallBits();
+ if (sizeof(uintptr_t) * CHAR_BIT == 32)
+ return CountPopulation_32(Bits);
+ if (sizeof(uintptr_t) * CHAR_BIT == 64)
+ return CountPopulation_64(Bits);
+ llvm_unreachable("Unsupported!");
+ }
+ return getPointer()->count();
+ }
+
+ /// any - Returns true if any bit is set.
+ bool any() const {
+ if (isSmall())
+ return getSmallBits() != 0;
+ return getPointer()->any();
+ }
+
+ /// all - Returns true if all bits are set.
+ bool all() const {
+ if (isSmall())
+ return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1;
+ return getPointer()->all();
+ }
+
+ /// none - Returns true if none of the bits are set.
+ bool none() const {
+ if (isSmall())
+ return getSmallBits() == 0;
+ return getPointer()->none();
+ }
+
+ /// find_first - Returns the index of the first set bit, -1 if none
+ /// of the bits are set.
+ int find_first() const {
+ if (isSmall()) {
+ uintptr_t Bits = getSmallBits();
+ if (Bits == 0)
+ return -1;
+ if (sizeof(uintptr_t) * CHAR_BIT == 32)
+ return CountTrailingZeros_32(Bits);
+ if (sizeof(uintptr_t) * CHAR_BIT == 64)
+ return CountTrailingZeros_64(Bits);
+ llvm_unreachable("Unsupported!");
+ }
+ return getPointer()->find_first();
+ }
+
+ /// find_next - Returns the index of the next set bit following the
+ /// "Prev" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Prev) const {
+ if (isSmall()) {
+ uintptr_t Bits = getSmallBits();
+ // Mask off previous bits.
+ Bits &= ~uintptr_t(0) << (Prev + 1);
+ if (Bits == 0 || Prev + 1 >= getSmallSize())
+ return -1;
+ if (sizeof(uintptr_t) * CHAR_BIT == 32)
+ return CountTrailingZeros_32(Bits);
+ if (sizeof(uintptr_t) * CHAR_BIT == 64)
+ return CountTrailingZeros_64(Bits);
+ llvm_unreachable("Unsupported!");
+ }
+ return getPointer()->find_next(Prev);
+ }
+
+ /// clear - Clear all bits.
+ void clear() {
+ if (!isSmall())
+ delete getPointer();
+ switchToSmall(0, 0);
+ }
+
+ /// resize - Grow or shrink the bitvector.
+ void resize(unsigned N, bool t = false) {
+ if (!isSmall()) {
+ getPointer()->resize(N, t);
+ } else if (SmallNumDataBits >= N) {
+ uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0;
+ setSmallSize(N);
+ setSmallBits(NewBits | getSmallBits());
+ } else {
+ BitVector *BV = new BitVector(N, t);
+ uintptr_t OldBits = getSmallBits();
+ for (size_t i = 0, e = getSmallSize(); i != e; ++i)
+ (*BV)[i] = (OldBits >> i) & 1;
+ switchToLarge(BV);
+ }
+ }
+
+ void reserve(unsigned N) {
+ if (isSmall()) {
+ if (N > SmallNumDataBits) {
+ uintptr_t OldBits = getSmallRawBits();
+ size_t SmallSize = getSmallSize();
+ BitVector *BV = new BitVector(SmallSize);
+ for (size_t i = 0; i < SmallSize; ++i)
+ if ((OldBits >> i) & 1)
+ BV->set(i);
+ BV->reserve(N);
+ switchToLarge(BV);
+ }
+ } else {
+ getPointer()->reserve(N);
+ }
+ }
+
+ // Set, reset, flip
+ SmallBitVector &set() {
+ if (isSmall())
+ setSmallBits(~uintptr_t(0));
+ else
+ getPointer()->set();
+ return *this;
+ }
+
+ SmallBitVector &set(unsigned Idx) {
+ if (isSmall())
+ setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
+ else
+ getPointer()->set(Idx);
+ return *this;
+ }
+
+ SmallBitVector &reset() {
+ if (isSmall())
+ setSmallBits(0);
+ else
+ getPointer()->reset();
+ return *this;
+ }
+
+ SmallBitVector &reset(unsigned Idx) {
+ if (isSmall())
+ setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
+ else
+ getPointer()->reset(Idx);
+ return *this;
+ }
+
+ SmallBitVector &flip() {
+ if (isSmall())
+ setSmallBits(~getSmallBits());
+ else
+ getPointer()->flip();
+ return *this;
+ }
+
+ SmallBitVector &flip(unsigned Idx) {
+ if (isSmall())
+ setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
+ else
+ getPointer()->flip(Idx);
+ return *this;
+ }
+
+ // No argument flip.
+ SmallBitVector operator~() const {
+ return SmallBitVector(*this).flip();
+ }
+
+ // Indexing.
+ reference operator[](unsigned Idx) {
+ assert(Idx < size() && "Out-of-bounds Bit access.");
+ return reference(*this, Idx);
+ }
+
+ bool operator[](unsigned Idx) const {
+ assert(Idx < size() && "Out-of-bounds Bit access.");
+ if (isSmall())
+ return ((getSmallBits() >> Idx) & 1) != 0;
+ return getPointer()->operator[](Idx);
+ }
+
+ bool test(unsigned Idx) const {
+ return (*this)[Idx];
+ }
+
+ // Comparison operators.
+ bool operator==(const SmallBitVector &RHS) const {
+ if (size() != RHS.size())
+ return false;
+ if (isSmall())
+ return getSmallBits() == RHS.getSmallBits();
+ else
+ return *getPointer() == *RHS.getPointer();
+ }
+
+ bool operator!=(const SmallBitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Intersection, union, disjoint union.
+ SmallBitVector &operator&=(const SmallBitVector &RHS) {
+ resize(std::max(size(), RHS.size()));
+ if (isSmall())
+ setSmallBits(getSmallBits() & RHS.getSmallBits());
+ else if (!RHS.isSmall())
+ getPointer()->operator&=(*RHS.getPointer());
+ else {
+ SmallBitVector Copy = RHS;
+ Copy.resize(size());
+ getPointer()->operator&=(*Copy.getPointer());
+ }
+ return *this;
+ }
+
+ SmallBitVector &operator|=(const SmallBitVector &RHS) {
+ resize(std::max(size(), RHS.size()));
+ if (isSmall())
+ setSmallBits(getSmallBits() | RHS.getSmallBits());
+ else if (!RHS.isSmall())
+ getPointer()->operator|=(*RHS.getPointer());
+ else {
+ SmallBitVector Copy = RHS;
+ Copy.resize(size());
+ getPointer()->operator|=(*Copy.getPointer());
+ }
+ return *this;
+ }
+
+ SmallBitVector &operator^=(const SmallBitVector &RHS) {
+ resize(std::max(size(), RHS.size()));
+ if (isSmall())
+ setSmallBits(getSmallBits() ^ RHS.getSmallBits());
+ else if (!RHS.isSmall())
+ getPointer()->operator^=(*RHS.getPointer());
+ else {
+ SmallBitVector Copy = RHS;
+ Copy.resize(size());
+ getPointer()->operator^=(*Copy.getPointer());
+ }
+ return *this;
+ }
+
+ // Assignment operator.
+ const SmallBitVector &operator=(const SmallBitVector &RHS) {
+ if (isSmall()) {
+ if (RHS.isSmall())
+ X = RHS.X;
+ else
+ switchToLarge(new BitVector(*RHS.getPointer()));
+ } else {
+ if (!RHS.isSmall())
+ *getPointer() = *RHS.getPointer();
+ else {
+ delete getPointer();
+ X = RHS.X;
+ }
+ }
+ return *this;
+ }
+
+ void swap(SmallBitVector &RHS) {
+ std::swap(X, RHS.X);
+ }
+};
+
+inline SmallBitVector
+operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+ SmallBitVector Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+inline SmallBitVector
+operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+ SmallBitVector Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+inline SmallBitVector
+operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+ SmallBitVector Result(LHS);
+ Result ^= RHS;
+ return Result;
+}
+
+} // End llvm namespace
+
+namespace std {
+ /// Implement std::swap in terms of BitVector swap.
+ inline void
+ swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SmallPtrSet.h b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h
new file mode 100644
index 000000000000..498a0345d8bb
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -0,0 +1,307 @@
+//===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- 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 SmallPtrSet class. See the doxygen comment for
+// SmallPtrSetImpl for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLPTRSET_H
+#define LLVM_ADT_SMALLPTRSET_H
+
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+
+namespace llvm {
+
+class SmallPtrSetIteratorImpl;
+
+/// SmallPtrSetImpl - This is the common code shared among all the
+/// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one
+/// for small and one for large sets.
+///
+/// Small sets use an array of pointers allocated in the SmallPtrSet object,
+/// which is treated as a simple array of pointers. When a pointer is added to
+/// the set, the array is scanned to see if the element already exists, if not
+/// the element is 'pushed back' onto the array. If we run out of space in the
+/// array, we grow into the 'large set' case. SmallSet should be used when the
+/// sets are often small. In this case, no memory allocation is used, and only
+/// light-weight and cache-efficient scanning is used.
+///
+/// Large sets use a classic exponentially-probed hash table. Empty buckets are
+/// represented with an illegal pointer value (-1) to allow null pointers to be
+/// inserted. Tombstones are represented with another illegal pointer value
+/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
+/// more. When this happens, the table is doubled in size.
+///
+class SmallPtrSetImpl {
+ friend class SmallPtrSetIteratorImpl;
+protected:
+ /// SmallArray - Points to a fixed size set of buckets, used in 'small mode'.
+ const void **SmallArray;
+ /// CurArray - This is the current set of buckets. If equal to SmallArray,
+ /// then the set is in 'small mode'.
+ const void **CurArray;
+ /// CurArraySize - The allocated size of CurArray, always a power of two.
+ /// Note that CurArray points to an array that has CurArraySize+1 elements in
+ /// it, so that the end iterator actually points to valid memory.
+ unsigned CurArraySize;
+
+ // If small, this is # elts allocated consecutively
+ unsigned NumElements;
+ unsigned NumTombstones;
+
+ // Helper to copy construct a SmallPtrSet.
+ SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that);
+ explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) :
+ SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
+ assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
+ "Initial size must be a power of two!");
+ // The end pointer, always valid, is set to a valid element to help the
+ // iterator.
+ CurArray[SmallSize] = 0;
+ clear();
+ }
+ ~SmallPtrSetImpl();
+
+public:
+ bool empty() const { return size() == 0; }
+ unsigned size() const { return NumElements; }
+
+ void clear() {
+ // If the capacity of the array is huge, and the # elements used is small,
+ // shrink the array.
+ if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32)
+ return shrink_and_clear();
+
+ // Fill the array with empty markers.
+ memset(CurArray, -1, CurArraySize*sizeof(void*));
+ NumElements = 0;
+ NumTombstones = 0;
+ }
+
+protected:
+ static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
+ static void *getEmptyMarker() {
+ // Note that -1 is chosen to make clear() efficiently implementable with
+ // memset and because it's not a valid pointer value.
+ return reinterpret_cast<void*>(-1);
+ }
+
+ /// insert_imp - This returns true if the pointer was new to the set, false if
+ /// it was already in the set. This is hidden from the client so that the
+ /// derived class can check that the right type of pointer is passed in.
+ bool insert_imp(const void * Ptr);
+
+ /// erase_imp - If the set contains the specified pointer, remove it and
+ /// return true, otherwise return false. This is hidden from the client so
+ /// that the derived class can check that the right type of pointer is passed
+ /// in.
+ bool erase_imp(const void * Ptr);
+
+ bool count_imp(const void * Ptr) const {
+ if (isSmall()) {
+ // Linear search for the item.
+ for (const void *const *APtr = SmallArray,
+ *const *E = SmallArray+NumElements; APtr != E; ++APtr)
+ if (*APtr == Ptr)
+ return true;
+ return false;
+ }
+
+ // Big set case.
+ return *FindBucketFor(Ptr) == Ptr;
+ }
+
+private:
+ bool isSmall() const { return CurArray == SmallArray; }
+
+ const void * const *FindBucketFor(const void *Ptr) const;
+ void shrink_and_clear();
+
+ /// 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.
+protected:
+ /// swap - Swaps the elements of two sets.
+ /// Note: This method assumes that both sets have the same small size.
+ void swap(SmallPtrSetImpl &RHS);
+
+ void CopyFrom(const SmallPtrSetImpl &RHS);
+};
+
+/// SmallPtrSetIteratorImpl - This is the common base class shared between all
+/// instances of SmallPtrSetIterator.
+class SmallPtrSetIteratorImpl {
+protected:
+ const void *const *Bucket;
+public:
+ explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
+ AdvanceIfNotValid();
+ }
+
+ bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket == RHS.Bucket;
+ }
+ bool operator!=(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket != RHS.Bucket;
+ }
+
+protected:
+ /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket
+ /// that is. This is guaranteed to stop because the end() bucket is marked
+ /// valid.
+ void AdvanceIfNotValid() {
+ while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImpl::getTombstoneMarker())
+ ++Bucket;
+ }
+};
+
+/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
+template<typename PtrTy>
+class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
+ typedef PointerLikeTypeTraits<PtrTy> PtrTraits;
+
+public:
+ typedef PtrTy value_type;
+ typedef PtrTy reference;
+ typedef PtrTy pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ explicit SmallPtrSetIterator(const void *const *BP)
+ : SmallPtrSetIteratorImpl(BP) {}
+
+ // Most methods provided by baseclass.
+
+ const PtrTy operator*() const {
+ return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
+ }
+
+ inline SmallPtrSetIterator& operator++() { // Preincrement
+ ++Bucket;
+ AdvanceIfNotValid();
+ return *this;
+ }
+
+ SmallPtrSetIterator operator++(int) { // Postincrement
+ SmallPtrSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+/// RoundUpToPowerOfTwo - This is a helper template that rounds N up to the next
+/// power of two (which means N itself if N is already a power of two).
+template<unsigned N>
+struct RoundUpToPowerOfTwo;
+
+/// RoundUpToPowerOfTwoH - If N is not a power of two, increase it. This is a
+/// helper template used to implement RoundUpToPowerOfTwo.
+template<unsigned N, bool isPowerTwo>
+struct RoundUpToPowerOfTwoH {
+ enum { Val = N };
+};
+template<unsigned N>
+struct RoundUpToPowerOfTwoH<N, false> {
+ enum {
+ // We could just use NextVal = N+1, but this converges faster. N|(N-1) sets
+ // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111.
+ Val = RoundUpToPowerOfTwo<(N|(N-1)) + 1>::Val
+ };
+};
+
+template<unsigned N>
+struct RoundUpToPowerOfTwo {
+ enum { Val = RoundUpToPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
+};
+
+
+/// SmallPtrSet - This class implements a set which is optimized for holding
+/// SmallSize or less elements. This internally rounds up SmallSize to the next
+/// power of two if it is not already a power of two. See the comments above
+/// SmallPtrSetImpl for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl {
+ // Make sure that SmallSize is a power of two, round up if not.
+ enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
+ /// SmallStorage - Fixed size storage used in 'small mode'. The extra element
+ /// ensures that the end iterator actually points to valid memory.
+ const void *SmallStorage[SmallSizePowTwo+1];
+ typedef PointerLikeTypeTraits<PtrType> PtrTraits;
+public:
+ SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
+ SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(SmallStorage, that) {}
+
+ template<typename It>
+ SmallPtrSet(It I, It E) : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {
+ insert(I, E);
+ }
+
+ /// insert - This returns true if the pointer was new to the set, false if it
+ /// was already in the set.
+ bool insert(PtrType Ptr) {
+ return insert_imp(PtrTraits::getAsVoidPointer(Ptr));
+ }
+
+ /// erase - If the set contains the specified pointer, remove it and return
+ /// true, otherwise return false.
+ bool erase(PtrType Ptr) {
+ return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
+ }
+
+ /// count - Return true if the specified pointer is in the set.
+ bool count(PtrType Ptr) const {
+ return count_imp(PtrTraits::getAsVoidPointer(Ptr));
+ }
+
+ template <typename IterT>
+ void insert(IterT I, IterT E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+ typedef SmallPtrSetIterator<PtrType> iterator;
+ typedef SmallPtrSetIterator<PtrType> const_iterator;
+ inline iterator begin() const {
+ return iterator(CurArray);
+ }
+ inline iterator end() const {
+ return iterator(CurArray+CurArraySize);
+ }
+
+ // Allow assignment from any smallptrset with the same element type even if it
+ // doesn't have the same smallsize.
+ const SmallPtrSet<PtrType, SmallSize>&
+ operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
+ CopyFrom(RHS);
+ return *this;
+ }
+
+ /// swap - Swaps the elements of two sets.
+ void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
+ SmallPtrSetImpl::swap(RHS);
+ }
+};
+
+}
+
+namespace std {
+ /// Implement std::swap in terms of SmallPtrSet swap.
+ template<class T, unsigned N>
+ inline void swap(llvm::SmallPtrSet<T, N> &LHS, llvm::SmallPtrSet<T, N> &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SmallSet.h b/contrib/llvm/include/llvm/ADT/SmallSet.h
new file mode 100644
index 000000000000..cd117f59ba76
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SmallSet.h
@@ -0,0 +1,118 @@
+//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- 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 SmallSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSET_H
+#define LLVM_ADT_SMALLSET_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+
+namespace llvm {
+
+/// SmallSet - This maintains a set of unique values, optimizing for the case
+/// when the set is small (less than N). In this case, the set can be
+/// maintained with no mallocs. If the set gets large, we expand to using an
+/// std::set to maintain reasonable lookup times.
+///
+/// Note that this set does not provide a way to iterate over members in the
+/// set.
+template <typename T, unsigned N, typename C = std::less<T> >
+class SmallSet {
+ /// Use a SmallVector to hold the elements here (even though it will never
+ /// reach its 'large' stage) to avoid calling the default ctors of elements
+ /// we will never use.
+ SmallVector<T, N> Vector;
+ std::set<T, C> Set;
+ typedef typename SmallVector<T, N>::const_iterator VIterator;
+ typedef typename SmallVector<T, N>::iterator mutable_iterator;
+public:
+ SmallSet() {}
+
+ bool empty() const { return Vector.empty() && Set.empty(); }
+ unsigned size() const {
+ return isSmall() ? Vector.size() : Set.size();
+ }
+
+ /// count - Return true if the element is in the set.
+ bool count(const T &V) const {
+ if (isSmall()) {
+ // Since the collection is small, just do a linear search.
+ return vfind(V) != Vector.end();
+ } else {
+ return Set.count(V);
+ }
+ }
+
+ /// insert - Insert an element into the set if it isn't already there.
+ bool insert(const T &V) {
+ if (!isSmall())
+ return Set.insert(V).second;
+
+ VIterator I = vfind(V);
+ if (I != Vector.end()) // Don't reinsert if it already exists.
+ return false;
+ if (Vector.size() < N) {
+ Vector.push_back(V);
+ return true;
+ }
+
+ // Otherwise, grow from vector to set.
+ while (!Vector.empty()) {
+ Set.insert(Vector.back());
+ Vector.pop_back();
+ }
+ Set.insert(V);
+ return true;
+ }
+
+ template <typename IterT>
+ void insert(IterT I, IterT E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+ bool erase(const T &V) {
+ if (!isSmall())
+ return Set.erase(V);
+ for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V) {
+ Vector.erase(I);
+ return true;
+ }
+ return false;
+ }
+
+ void clear() {
+ Vector.clear();
+ Set.clear();
+ }
+private:
+ bool isSmall() const { return Set.empty(); }
+
+ VIterator vfind(const T &V) const {
+ for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V)
+ return I;
+ return Vector.end();
+ }
+};
+
+/// If this set is of pointer values, transparently switch over to using
+/// SmallPtrSet for performance.
+template <typename PointeeType, unsigned N>
+class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SmallString.h b/contrib/llvm/include/llvm/ADT/SmallString.h
new file mode 100644
index 000000000000..199783ba3899
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SmallString.h
@@ -0,0 +1,295 @@
+//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- 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 SmallString class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSTRING_H
+#define LLVM_ADT_SMALLSTRING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// SmallString - A SmallString is just a SmallVector with methods and accessors
+/// that make it work better as a string (e.g. operator+ etc).
+template<unsigned InternalLen>
+class SmallString : public SmallVector<char, InternalLen> {
+public:
+ /// Default ctor - Initialize to empty.
+ SmallString() {}
+
+ /// Initialize from a StringRef.
+ SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
+
+ /// Initialize with a range.
+ template<typename ItTy>
+ SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
+
+ /// Copy ctor.
+ SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
+
+ // Note that in order to add new overloads for append & assign, we have to
+ // duplicate the inherited versions so as not to inadvertently hide them.
+
+ /// @}
+ /// @name String Assignment
+ /// @{
+
+ /// Assign from a repeated element
+ void assign(unsigned NumElts, char Elt) {
+ this->SmallVectorImpl<char>::assign(NumElts, Elt);
+ }
+
+ /// 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
+ void assign(StringRef RHS) {
+ this->clear();
+ SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+ }
+
+ /// Assign from a SmallVector
+ void assign(const SmallVectorImpl<char> &RHS) {
+ this->clear();
+ SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+ }
+
+ /// @}
+ /// @name String Concatenation
+ /// @{
+
+ /// Append from an iterator pair
+ template<typename in_iter>
+ void append(in_iter S, in_iter E) {
+ SmallVectorImpl<char>::append(S, E);
+ }
+
+ /// Append from a StringRef
+ void append(StringRef RHS) {
+ SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+ }
+
+ /// Append from a SmallVector
+ void append(const SmallVectorImpl<char> &RHS) {
+ SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+ }
+
+ /// @}
+ /// @name String Comparison
+ /// @{
+
+ /// equals - 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.
+ 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.
+ int compare(StringRef RHS) const {
+ return str().compare(RHS);
+ }
+
+ /// compare_lower - Compare two strings, ignoring case.
+ int compare_lower(StringRef RHS) const {
+ return str().compare_lower(RHS);
+ }
+
+ /// compare_numeric - Compare two strings, treating sequences of digits as
+ /// numbers.
+ int compare_numeric(StringRef RHS) const {
+ return str().compare_numeric(RHS);
+ }
+
+ /// @}
+ /// @name String Predicates
+ /// @{
+
+ /// startswith - Check if this string starts with the given \arg Prefix.
+ bool startswith(StringRef Prefix) const {
+ return str().startswith(Prefix);
+ }
+
+ /// endswith - Check if this string ends with the given \arg Suffix.
+ bool endswith(StringRef Suffix) const {
+ return str().endswith(Suffix);
+ }
+
+ /// @}
+ /// @name String Searching
+ /// @{
+
+ /// find - Search for the first character \arg C in the string.
+ ///
+ /// \return - The index of the first occurrence of \arg 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.
+ ///
+ /// \return - The index of the first occurrence of \arg 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.
+ ///
+ /// \return - The index of the last occurrence of \arg 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.
+ ///
+ /// \return - The index of the last occurrence of \arg 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.
+ 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.
+ ///
+ /// Note: 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.
+ 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.
+ ///
+ /// Note: 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.
+ 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.
+ ///
+ /// Note: O(size() + Chars.size())
+ size_t find_last_of(
+ StringRef Chars, size_t From = StringRef::npos) const {
+ return str().find_last_of(Chars, From);
+ }
+
+ /// @}
+ /// @name Helpful Algorithms
+ /// @{
+
+ /// count - Return the number of occurrences of \arg 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.
+ size_t count(StringRef Str) const {
+ return str().count(Str);
+ }
+
+ /// @}
+ /// @name Substring Operations
+ /// @{
+
+ /// substr - Return a reference to the substring from [Start, Start + N).
+ ///
+ /// \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
+ /// exceeds the number of characters remaining in the string, the string
+ /// suffix (starting with \arg 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).
+ ///
+ /// \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
+ /// number of characters remaining in the string, the string suffix
+ /// (starting with \arg Start) will be returned.
+ StringRef slice(size_t Start, size_t End) const {
+ return str().slice(Start, End);
+ }
+
+ // Extra methods.
+
+ /// Explicit conversion to StringRef
+ StringRef str() const { return StringRef(this->begin(), this->size()); }
+
+ // TODO: Make this const, if it's safe...
+ const char* c_str() {
+ this->push_back(0);
+ this->pop_back();
+ return this->data();
+ }
+
+ /// Implicit conversion to StringRef.
+ operator StringRef() const { return str(); }
+
+ // Extra operators.
+ const SmallString &operator=(StringRef RHS) {
+ this->clear();
+ return *this += RHS;
+ }
+
+ SmallString &operator+=(StringRef RHS) {
+ this->append(RHS.begin(), RHS.end());
+ return *this;
+ }
+ SmallString &operator+=(char C) {
+ this->push_back(C);
+ return *this;
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SmallVector.h b/contrib/llvm/include/llvm/ADT/SmallVector.h
new file mode 100644
index 000000000000..0d9d0d12e868
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SmallVector.h
@@ -0,0 +1,748 @@
+//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- 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 SmallVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLVECTOR_H
+#define LLVM_ADT_SMALLVECTOR_H
+
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <iterator>
+#include <memory>
+
+namespace llvm {
+
+/// SmallVectorBase - This is all the non-templated stuff common to all
+/// SmallVectors.
+class SmallVectorBase {
+protected:
+ void *BeginX, *EndX, *CapacityX;
+
+ // Allocate raw space for N elements of type T. If T has a ctor or dtor, we
+ // don't want it to be automatically run, so we need to represent the space as
+ // something else. An array of char would work great, but might not be
+ // aligned sufficiently. Instead we use some number of union instances for
+ // the space, which guarantee maximal alignment.
+ union U {
+ double D;
+ long double LD;
+ long long L;
+ void *P;
+ } FirstEl;
+ // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
+
+protected:
+ SmallVectorBase(size_t Size)
+ : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {}
+
+ /// isSmall - Return true if this is a smallvector which has not had dynamic
+ /// memory allocated for it.
+ bool isSmall() const {
+ return BeginX == static_cast<const void*>(&FirstEl);
+ }
+
+ /// grow_pod - This is an implementation of the grow() method which only works
+ /// on POD-like data types and is out of line to reduce code duplication.
+ void grow_pod(size_t MinSizeInBytes, size_t TSize);
+
+public:
+ /// size_in_bytes - This returns size()*sizeof(T).
+ size_t size_in_bytes() const {
+ return size_t((char*)EndX - (char*)BeginX);
+ }
+
+ /// capacity_in_bytes - This returns capacity()*sizeof(T).
+ size_t capacity_in_bytes() const {
+ return size_t((char*)CapacityX - (char*)BeginX);
+ }
+
+ bool empty() const { return BeginX == EndX; }
+};
+
+
+template <typename T>
+class SmallVectorTemplateCommon : public SmallVectorBase {
+protected:
+ SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {}
+
+ void setEnd(T *P) { this->EndX = P; }
+public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T *iterator;
+ typedef const T *const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ typedef T &reference;
+ typedef const T &const_reference;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+
+ // forward iterator creation methods.
+ iterator begin() { return (iterator)this->BeginX; }
+ const_iterator begin() const { return (const_iterator)this->BeginX; }
+ iterator end() { return (iterator)this->EndX; }
+ const_iterator end() const { return (const_iterator)this->EndX; }
+protected:
+ iterator capacity_ptr() { return (iterator)this->CapacityX; }
+ const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
+public:
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+ size_type size() const { return end()-begin(); }
+ size_type max_size() const { return size_type(-1) / sizeof(T); }
+
+ /// capacity - Return the total number of elements in the currently allocated
+ /// buffer.
+ size_t capacity() const { return capacity_ptr() - begin(); }
+
+ /// data - Return a pointer to the vector's buffer, even if empty().
+ pointer data() { return pointer(begin()); }
+ /// data - Return a pointer to the vector's buffer, even if empty().
+ const_pointer data() const { return const_pointer(begin()); }
+
+ reference operator[](unsigned idx) {
+ assert(begin() + idx < end());
+ return begin()[idx];
+ }
+ const_reference operator[](unsigned idx) const {
+ assert(begin() + idx < end());
+ return begin()[idx];
+ }
+
+ reference front() {
+ return begin()[0];
+ }
+ const_reference front() const {
+ return begin()[0];
+ }
+
+ reference back() {
+ return end()[-1];
+ }
+ const_reference back() const {
+ return end()[-1];
+ }
+};
+
+/// SmallVectorTemplateBase<isPodLike = false> - This is where we put method
+/// implementations that are designed to work with non-POD-like T's.
+template <typename T, bool isPodLike>
+class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
+protected:
+ SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
+
+ static void destroy_range(T *S, T *E) {
+ while (S != E) {
+ --E;
+ E->~T();
+ }
+ }
+
+ /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+ /// starting with "Dest", constructing elements into it as needed.
+ template<typename It1, typename It2>
+ static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+ std::uninitialized_copy(I, E, Dest);
+ }
+
+ /// grow - double the size of the allocated memory, guaranteeing space for at
+ /// least one more element or MinSize if specified.
+ void grow(size_t MinSize = 0);
+
+public:
+ void push_back(const T &Elt) {
+ if (this->EndX < this->CapacityX) {
+ Retry:
+ new (this->end()) T(Elt);
+ this->setEnd(this->end()+1);
+ return;
+ }
+ this->grow();
+ goto Retry;
+ }
+
+ void pop_back() {
+ this->setEnd(this->end()-1);
+ this->end()->~T();
+ }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T, bool isPodLike>
+void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
+ size_t CurCapacity = this->capacity();
+ size_t CurSize = this->size();
+ size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
+ if (NewCapacity < MinSize)
+ NewCapacity = MinSize;
+ T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
+
+ // Copy the elements over.
+ this->uninitialized_copy(this->begin(), this->end(), NewElts);
+
+ // Destroy the original elements.
+ destroy_range(this->begin(), this->end());
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!this->isSmall())
+ free(this->begin());
+
+ this->setEnd(NewElts+CurSize);
+ this->BeginX = NewElts;
+ this->CapacityX = this->begin()+NewCapacity;
+}
+
+
+/// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
+/// implementations that are designed to work with POD-like T's.
+template <typename T>
+class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
+protected:
+ SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
+
+ // No need to do a destroy loop for POD's.
+ static void destroy_range(T *, T *) {}
+
+ /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+ /// starting with "Dest", constructing elements into it as needed.
+ template<typename It1, typename It2>
+ static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+ // Arbitrary iterator types; just use the basic implementation.
+ std::uninitialized_copy(I, E, Dest);
+ }
+
+ /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+ /// starting with "Dest", constructing elements into it as needed.
+ template<typename T1, typename T2>
+ static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) {
+ // Use memcpy for PODs iterated by pointers (which includes SmallVector
+ // iterators): std::uninitialized_copy optimizes to memmove, but we can
+ // use memcpy here.
+ memcpy(Dest, I, (E-I)*sizeof(T));
+ }
+
+ /// grow - double the size of the allocated memory, guaranteeing space for at
+ /// least one more element or MinSize if specified.
+ void grow(size_t MinSize = 0) {
+ this->grow_pod(MinSize*sizeof(T), sizeof(T));
+ }
+public:
+ void push_back(const T &Elt) {
+ if (this->EndX < this->CapacityX) {
+ Retry:
+ *this->end() = Elt;
+ this->setEnd(this->end()+1);
+ return;
+ }
+ this->grow();
+ goto Retry;
+ }
+
+ void pop_back() {
+ this->setEnd(this->end()-1);
+ }
+};
+
+
+/// SmallVectorImpl - This class consists of common code factored out of the
+/// SmallVector class to reduce code duplication based on the SmallVector 'N'
+/// template parameter.
+template <typename T>
+class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
+ typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
+
+ SmallVectorImpl(const SmallVectorImpl&); // DISABLED.
+public:
+ typedef typename SuperClass::iterator iterator;
+ typedef typename SuperClass::size_type size_type;
+
+protected:
+ // Default ctor - Initialize to empty.
+ explicit SmallVectorImpl(unsigned N)
+ : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
+ }
+
+public:
+ ~SmallVectorImpl() {
+ // Destroy the constructed elements in the vector.
+ this->destroy_range(this->begin(), this->end());
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!this->isSmall())
+ free(this->begin());
+ }
+
+
+ void clear() {
+ this->destroy_range(this->begin(), this->end());
+ this->EndX = this->BeginX;
+ }
+
+ void resize(unsigned N) {
+ if (N < this->size()) {
+ this->destroy_range(this->begin()+N, this->end());
+ this->setEnd(this->begin()+N);
+ } else if (N > this->size()) {
+ if (this->capacity() < N)
+ this->grow(N);
+ std::uninitialized_fill(this->end(), this->begin()+N, T());
+ this->setEnd(this->begin()+N);
+ }
+ }
+
+ void resize(unsigned N, const T &NV) {
+ if (N < this->size()) {
+ this->destroy_range(this->begin()+N, this->end());
+ this->setEnd(this->begin()+N);
+ } else if (N > this->size()) {
+ if (this->capacity() < N)
+ this->grow(N);
+ std::uninitialized_fill(this->end(), this->begin()+N, NV);
+ this->setEnd(this->begin()+N);
+ }
+ }
+
+ void reserve(unsigned N) {
+ if (this->capacity() < N)
+ this->grow(N);
+ }
+
+ T pop_back_val() {
+ T Result = this->back();
+ this->pop_back();
+ return Result;
+ }
+
+ void swap(SmallVectorImpl &RHS);
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ template<typename in_iter>
+ void append(in_iter in_start, in_iter in_end) {
+ size_type NumInputs = std::distance(in_start, in_end);
+ // Grow allocated space if needed.
+ if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+ this->grow(this->size()+NumInputs);
+
+ // Copy the new elements over.
+ // TODO: NEED To compile time dispatch on whether in_iter is a random access
+ // iterator to use the fast uninitialized_copy.
+ std::uninitialized_copy(in_start, in_end, this->end());
+ this->setEnd(this->end() + NumInputs);
+ }
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ void append(size_type NumInputs, const T &Elt) {
+ // Grow allocated space if needed.
+ if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+ this->grow(this->size()+NumInputs);
+
+ // Copy the new elements over.
+ std::uninitialized_fill_n(this->end(), NumInputs, Elt);
+ this->setEnd(this->end() + NumInputs);
+ }
+
+ void assign(unsigned NumElts, const T &Elt) {
+ clear();
+ if (this->capacity() < NumElts)
+ this->grow(NumElts);
+ this->setEnd(this->begin()+NumElts);
+ std::uninitialized_fill(this->begin(), this->end(), Elt);
+ }
+
+ iterator erase(iterator I) {
+ iterator N = I;
+ // Shift all elts down one.
+ std::copy(I+1, this->end(), I);
+ // Drop the last elt.
+ this->pop_back();
+ return(N);
+ }
+
+ iterator erase(iterator S, iterator E) {
+ iterator N = S;
+ // Shift all elts down.
+ iterator I = std::copy(E, this->end(), S);
+ // Drop the last elts.
+ this->destroy_range(I, this->end());
+ this->setEnd(I);
+ return(N);
+ }
+
+ iterator insert(iterator I, const T &Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ this->push_back(Elt);
+ return this->end()-1;
+ }
+
+ if (this->EndX < this->CapacityX) {
+ Retry:
+ new (this->end()) T(this->back());
+ this->setEnd(this->end()+1);
+ // Push everything else over.
+ std::copy_backward(I, this->end()-1, this->end());
+
+ // If we just moved the element we're inserting, be sure to update
+ // the reference.
+ const T *EltPtr = &Elt;
+ if (I <= EltPtr && EltPtr < this->EndX)
+ ++EltPtr;
+
+ *I = *EltPtr;
+ return I;
+ }
+ size_t EltNo = I-this->begin();
+ this->grow();
+ I = this->begin()+EltNo;
+ goto Retry;
+ }
+
+ iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ append(NumToInsert, Elt);
+ return this->end()-1;
+ }
+
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ // Ensure there is enough space.
+ reserve(static_cast<unsigned>(this->size() + NumToInsert));
+
+ // Uninvalidate the iterator.
+ I = this->begin()+InsertElt;
+
+ // If there are more elements between the insertion point and the end of the
+ // range than there are being inserted, we can use a simple approach to
+ // insertion. Since we already reserved space, we know that this won't
+ // reallocate the vector.
+ if (size_t(this->end()-I) >= NumToInsert) {
+ T *OldEnd = this->end();
+ append(this->end()-NumToInsert, this->end());
+
+ // Copy the existing elements that get replaced.
+ std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+ std::fill_n(I, NumToInsert, Elt);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = this->end();
+ this->setEnd(this->end() + NumToInsert);
+ size_t NumOverwritten = OldEnd-I;
+ this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+ // Replace the overwritten part.
+ std::fill_n(I, NumOverwritten, Elt);
+
+ // Insert the non-overwritten middle part.
+ std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
+ return I;
+ }
+
+ template<typename ItTy>
+ iterator insert(iterator I, ItTy From, ItTy To) {
+ if (I == this->end()) { // Important special case for empty vector.
+ append(From, To);
+ return this->end()-1;
+ }
+
+ size_t NumToInsert = std::distance(From, To);
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ // Ensure there is enough space.
+ reserve(static_cast<unsigned>(this->size() + NumToInsert));
+
+ // Uninvalidate the iterator.
+ I = this->begin()+InsertElt;
+
+ // If there are more elements between the insertion point and the end of the
+ // range than there are being inserted, we can use a simple approach to
+ // insertion. Since we already reserved space, we know that this won't
+ // reallocate the vector.
+ if (size_t(this->end()-I) >= NumToInsert) {
+ T *OldEnd = this->end();
+ append(this->end()-NumToInsert, this->end());
+
+ // Copy the existing elements that get replaced.
+ std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+ std::copy(From, To, I);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = this->end();
+ this->setEnd(this->end() + NumToInsert);
+ size_t NumOverwritten = OldEnd-I;
+ this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+ // Replace the overwritten part.
+ for (; NumOverwritten > 0; --NumOverwritten) {
+ *I = *From;
+ ++I; ++From;
+ }
+
+ // Insert the non-overwritten middle part.
+ this->uninitialized_copy(From, To, OldEnd);
+ return I;
+ }
+
+ const SmallVectorImpl
+ &operator=(const SmallVectorImpl &RHS);
+
+ bool operator==(const SmallVectorImpl &RHS) const {
+ if (this->size() != RHS.size()) return false;
+ return std::equal(this->begin(), this->end(), RHS.begin());
+ }
+ bool operator!=(const SmallVectorImpl &RHS) const {
+ return !(*this == RHS);
+ }
+
+ bool operator<(const SmallVectorImpl &RHS) const {
+ return std::lexicographical_compare(this->begin(), this->end(),
+ RHS.begin(), RHS.end());
+ }
+
+ /// set_size - Set the array size to \arg N, which the current array must have
+ /// enough capacity for.
+ ///
+ /// This does not construct or destroy any elements in the vector.
+ ///
+ /// Clients can use this in conjunction with capacity() to write past the end
+ /// of the buffer when they know that more elements are available, and only
+ /// update the size later. This avoids the cost of value initializing elements
+ /// which will only be overwritten.
+ void set_size(unsigned N) {
+ assert(N <= this->capacity());
+ this->setEnd(this->begin() + N);
+ }
+};
+
+
+template <typename T>
+void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
+ if (this == &RHS) return;
+
+ // We can only avoid copying elements if neither vector is small.
+ if (!this->isSmall() && !RHS.isSmall()) {
+ std::swap(this->BeginX, RHS.BeginX);
+ std::swap(this->EndX, RHS.EndX);
+ std::swap(this->CapacityX, RHS.CapacityX);
+ return;
+ }
+ if (RHS.size() > this->capacity())
+ this->grow(RHS.size());
+ if (this->size() > RHS.capacity())
+ RHS.grow(this->size());
+
+ // Swap the shared elements.
+ size_t NumShared = this->size();
+ if (NumShared > RHS.size()) NumShared = RHS.size();
+ for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
+ std::swap((*this)[i], RHS[i]);
+
+ // Copy over the extra elts.
+ if (this->size() > RHS.size()) {
+ size_t EltDiff = this->size() - RHS.size();
+ this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
+ RHS.setEnd(RHS.end()+EltDiff);
+ this->destroy_range(this->begin()+NumShared, this->end());
+ this->setEnd(this->begin()+NumShared);
+ } else if (RHS.size() > this->size()) {
+ size_t EltDiff = RHS.size() - this->size();
+ this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
+ this->setEnd(this->end() + EltDiff);
+ this->destroy_range(RHS.begin()+NumShared, RHS.end());
+ RHS.setEnd(RHS.begin()+NumShared);
+ }
+}
+
+template <typename T>
+const SmallVectorImpl<T> &SmallVectorImpl<T>::
+ operator=(const SmallVectorImpl<T> &RHS) {
+ // Avoid self-assignment.
+ if (this == &RHS) return *this;
+
+ // If we already have sufficient space, assign the common elements, then
+ // destroy any excess.
+ size_t RHSSize = RHS.size();
+ size_t CurSize = this->size();
+ if (CurSize >= RHSSize) {
+ // Assign common elements.
+ iterator NewEnd;
+ if (RHSSize)
+ NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
+ else
+ NewEnd = this->begin();
+
+ // Destroy excess elements.
+ this->destroy_range(NewEnd, this->end());
+
+ // Trim.
+ this->setEnd(NewEnd);
+ return *this;
+ }
+
+ // If we have to grow to have enough elements, destroy the current elements.
+ // This allows us to avoid copying them during the grow.
+ if (this->capacity() < RHSSize) {
+ // Destroy current elements.
+ this->destroy_range(this->begin(), this->end());
+ this->setEnd(this->begin());
+ CurSize = 0;
+ this->grow(RHSSize);
+ } else if (CurSize) {
+ // Otherwise, use assignment for the already-constructed elements.
+ std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
+ }
+
+ // Copy construct the new elements in place.
+ this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
+ this->begin()+CurSize);
+
+ // Set end.
+ this->setEnd(this->begin()+RHSSize);
+ return *this;
+}
+
+
+/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
+/// for the case when the array is small. It contains some number of elements
+/// in-place, which allows it to avoid heap allocation when the actual number of
+/// elements is below that threshold. This allows normal "small" cases to be
+/// fast without losing generality for large inputs.
+///
+/// Note that this does not attempt to be exception safe.
+///
+template <typename T, unsigned N>
+class SmallVector : public SmallVectorImpl<T> {
+ /// InlineElts - These are 'N-1' elements that are stored inline in the body
+ /// of the vector. The extra '1' element is stored in SmallVectorImpl.
+ typedef typename SmallVectorImpl<T>::U U;
+ enum {
+ // MinUs - The number of U's require to cover N T's.
+ MinUs = (static_cast<unsigned int>(sizeof(T))*N +
+ static_cast<unsigned int>(sizeof(U)) - 1) /
+ static_cast<unsigned int>(sizeof(U)),
+
+ // NumInlineEltsElts - The number of elements actually in this array. There
+ // is already one in the parent class, and we have to round up to avoid
+ // having a zero-element array.
+ NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1,
+
+ // NumTsAvailable - The number of T's we actually have space for, which may
+ // be more than N due to rounding.
+ NumTsAvailable = (NumInlineEltsElts+1)*static_cast<unsigned int>(sizeof(U))/
+ static_cast<unsigned int>(sizeof(T))
+ };
+ U InlineElts[NumInlineEltsElts];
+public:
+ SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
+ }
+
+ explicit SmallVector(unsigned Size, const T &Value = T())
+ : SmallVectorImpl<T>(NumTsAvailable) {
+ this->assign(Size, Value);
+ }
+
+ template<typename ItTy>
+ SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
+ this->append(S, E);
+ }
+
+ SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
+ if (!RHS.empty())
+ SmallVectorImpl<T>::operator=(RHS);
+ }
+
+ const SmallVector &operator=(const SmallVector &RHS) {
+ SmallVectorImpl<T>::operator=(RHS);
+ return *this;
+ }
+
+};
+
+/// Specialize SmallVector at N=0. This specialization guarantees
+/// that it can be instantiated at an incomplete T if none of its
+/// members are required.
+template <typename T>
+class SmallVector<T,0> : public SmallVectorImpl<T> {
+public:
+ SmallVector() : SmallVectorImpl<T>(0) {}
+
+ explicit SmallVector(unsigned Size, const T &Value = T())
+ : SmallVectorImpl<T>(0) {
+ this->assign(Size, Value);
+ }
+
+ template<typename ItTy>
+ SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(0) {
+ this->append(S, E);
+ }
+
+ SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(0) {
+ SmallVectorImpl<T>::operator=(RHS);
+ }
+
+ SmallVector &operator=(const SmallVectorImpl<T> &RHS) {
+ return SmallVectorImpl<T>::operator=(RHS);
+ }
+
+};
+
+template<typename T, unsigned N>
+static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
+ return X.capacity_in_bytes();
+}
+
+} // End llvm namespace
+
+namespace std {
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T>
+ inline void
+ swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
+ LHS.swap(RHS);
+ }
+
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T, unsigned N>
+ inline void
+ swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SparseBitVector.h b/contrib/llvm/include/llvm/ADT/SparseBitVector.h
new file mode 100644
index 000000000000..89774c3f5628
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SparseBitVector.h
@@ -0,0 +1,881 @@
+//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- 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 SparseBitVector class. See the doxygen comment for
+// SparseBitVector for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSEBITVECTOR_H
+#define LLVM_ADT_SPARSEBITVECTOR_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <climits>
+
+namespace llvm {
+
+/// SparseBitVector is an implementation of a bitvector that is sparse by only
+/// storing the elements that have non-zero bits set. In order to make this
+/// fast for the most common cases, SparseBitVector is implemented as a linked
+/// list of SparseBitVectorElements. We maintain a pointer to the last
+/// SparseBitVectorElement accessed (in the form of a list iterator), in order
+/// to make multiple in-order test/set constant time after the first one is
+/// executed. Note that using vectors to store SparseBitVectorElement's does
+/// not work out very well because it causes insertion in the middle to take
+/// enormous amounts of time with a large amount of bits. Other structures that
+/// have better worst cases for insertion in the middle (various balanced trees,
+/// etc) do not perform as well in practice as a linked list with this iterator
+/// kept up to date. They are also significantly more memory intensive.
+
+
+template <unsigned ElementSize = 128>
+struct SparseBitVectorElement
+ : public ilist_node<SparseBitVectorElement<ElementSize> > {
+public:
+ typedef unsigned long BitWord;
+ enum {
+ BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
+ BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
+ BITS_PER_ELEMENT = ElementSize
+ };
+
+private:
+ // Index of Element in terms of where first bit starts.
+ unsigned ElementIndex;
+ BitWord Bits[BITWORDS_PER_ELEMENT];
+ // Needed for sentinels
+ friend struct ilist_sentinel_traits<SparseBitVectorElement>;
+ SparseBitVectorElement() {
+ ElementIndex = ~0U;
+ memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+ }
+
+public:
+ explicit SparseBitVectorElement(unsigned Idx) {
+ ElementIndex = Idx;
+ memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
+ }
+
+ // Comparison.
+ bool operator==(const SparseBitVectorElement &RHS) const {
+ if (ElementIndex != RHS.ElementIndex)
+ return false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+ return true;
+ }
+
+ bool operator!=(const SparseBitVectorElement &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Return the bits that make up word Idx in our element.
+ BitWord word(unsigned Idx) const {
+ assert (Idx < BITWORDS_PER_ELEMENT);
+ return Bits[Idx];
+ }
+
+ unsigned index() const {
+ return ElementIndex;
+ }
+
+ bool empty() const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i])
+ return false;
+ return true;
+ }
+
+ void set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ }
+
+ bool test_and_set (unsigned Idx) {
+ bool old = test(Idx);
+ if (!old) {
+ set(Idx);
+ return true;
+ }
+ return false;
+ }
+
+ void reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ }
+
+ bool test(unsigned Idx) const {
+ return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
+ }
+
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ llvm_unreachable("Unsupported!");
+ return NumBits;
+ }
+
+ /// find_first - Returns the index of the first set bit.
+ int find_first() const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ llvm_unreachable("Unsupported!");
+ }
+ llvm_unreachable("Illegal empty element");
+ }
+
+ /// find_next - Returns the index of the next set bit starting from the
+ /// "Curr" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Curr) const {
+ if (Curr >= BITS_PER_ELEMENT)
+ return -1;
+
+ unsigned WordPos = Curr / BITWORD_SIZE;
+ unsigned BitPos = Curr % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ assert (WordPos <= BITWORDS_PER_ELEMENT
+ && "Word Position outside of element");
+
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
+ if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ llvm_unreachable("Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ llvm_unreachable("Unsupported!");
+ }
+ return -1;
+ }
+
+ // Union this element with RHS and return true if this one changed.
+ bool unionWith(const SparseBitVectorElement &RHS) {
+ bool changed = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] |= RHS.Bits[i];
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ return changed;
+ }
+
+ // Return true if we have any bits in common with RHS
+ bool intersects(const SparseBitVectorElement &RHS) const {
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ if (RHS.Bits[i] & Bits[i])
+ return true;
+ }
+ return false;
+ }
+
+ // Intersect this Element with RHS and return true if this one changed.
+ // BecameZero is set to true if this element became all-zero bits.
+ bool intersectWith(const SparseBitVectorElement &RHS,
+ bool &BecameZero) {
+ bool changed = false;
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] &= RHS.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ BecameZero = allzero;
+ return changed;
+ }
+ // Intersect this Element with the complement of RHS and return true if this
+ // one changed. BecameZero is set to true if this element became all-zero
+ // bits.
+ bool intersectWithComplement(const SparseBitVectorElement &RHS,
+ bool &BecameZero) {
+ bool changed = false;
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ BitWord old = changed ? 0 : Bits[i];
+
+ Bits[i] &= ~RHS.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+
+ if (!changed && old != Bits[i])
+ changed = true;
+ }
+ BecameZero = allzero;
+ return changed;
+ }
+ // Three argument version of intersectWithComplement that intersects
+ // RHS1 & ~RHS2 into this element
+ void intersectWithComplement(const SparseBitVectorElement &RHS1,
+ const SparseBitVectorElement &RHS2,
+ bool &BecameZero) {
+ bool allzero = true;
+
+ BecameZero = false;
+ for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
+ Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
+ if (Bits[i] != 0)
+ allzero = false;
+ }
+ BecameZero = allzero;
+ }
+};
+
+template <unsigned ElementSize = 128>
+class SparseBitVector {
+ typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
+ typedef typename ElementList::iterator ElementListIter;
+ typedef typename ElementList::const_iterator ElementListConstIter;
+ enum {
+ BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
+ };
+
+ // Pointer to our current Element.
+ ElementListIter CurrElementIter;
+ ElementList Elements;
+
+ // This is like std::lower_bound, except we do linear searching from the
+ // current position.
+ ElementListIter FindLowerBound(unsigned ElementIndex) {
+
+ if (Elements.empty()) {
+ CurrElementIter = Elements.begin();
+ return Elements.begin();
+ }
+
+ // Make sure our current iterator is valid.
+ if (CurrElementIter == Elements.end())
+ --CurrElementIter;
+
+ // Search from our current iterator, either backwards or forwards,
+ // depending on what element we are looking for.
+ ElementListIter ElementIter = CurrElementIter;
+ if (CurrElementIter->index() == ElementIndex) {
+ return ElementIter;
+ } else if (CurrElementIter->index() > ElementIndex) {
+ while (ElementIter != Elements.begin()
+ && ElementIter->index() > ElementIndex)
+ --ElementIter;
+ } else {
+ while (ElementIter != Elements.end() &&
+ ElementIter->index() < ElementIndex)
+ ++ElementIter;
+ }
+ CurrElementIter = ElementIter;
+ return ElementIter;
+ }
+
+ // Iterator to walk set bits in the bitmap. This iterator is a lot uglier
+ // than it would be, in order to be efficient.
+ class SparseBitVectorIterator {
+ private:
+ bool AtEnd;
+
+ const SparseBitVector<ElementSize> *BitVector;
+
+ // Current element inside of bitmap.
+ ElementListConstIter Iter;
+
+ // Current bit number inside of our bitmap.
+ unsigned BitNumber;
+
+ // Current word number inside of our element.
+ unsigned WordNumber;
+
+ // Current bits from the element.
+ typename SparseBitVectorElement<ElementSize>::BitWord Bits;
+
+ // Move our iterator to the first non-zero bit in the bitmap.
+ void AdvanceToFirstNonZero() {
+ if (AtEnd)
+ return;
+ if (BitVector->Elements.empty()) {
+ AtEnd = true;
+ return;
+ }
+ Iter = BitVector->Elements.begin();
+ BitNumber = Iter->index() * ElementSize;
+ unsigned BitPos = Iter->find_first();
+ BitNumber += BitPos;
+ WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= BitPos % BITWORD_SIZE;
+ }
+
+ // Move our iterator to the next non-zero bit.
+ void AdvanceToNextNonZero() {
+ if (AtEnd)
+ return;
+
+ while (Bits && !(Bits & 1)) {
+ Bits >>= 1;
+ BitNumber += 1;
+ }
+
+ // See if we ran out of Bits in this word.
+ if (!Bits) {
+ int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
+ // If we ran out of set bits in this element, move to next element.
+ if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
+ ++Iter;
+ WordNumber = 0;
+
+ // We may run out of elements in the bitmap.
+ if (Iter == BitVector->Elements.end()) {
+ AtEnd = true;
+ return;
+ }
+ // Set up for next non zero word in bitmap.
+ BitNumber = Iter->index() * ElementSize;
+ NextSetBitNumber = Iter->find_first();
+ BitNumber += NextSetBitNumber;
+ WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= NextSetBitNumber % BITWORD_SIZE;
+ } else {
+ WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
+ Bits = Iter->word(WordNumber);
+ Bits >>= NextSetBitNumber % BITWORD_SIZE;
+ BitNumber = Iter->index() * ElementSize;
+ BitNumber += NextSetBitNumber;
+ }
+ }
+ }
+ public:
+ // Preincrement.
+ inline SparseBitVectorIterator& operator++() {
+ ++BitNumber;
+ Bits >>= 1;
+ AdvanceToNextNonZero();
+ return *this;
+ }
+
+ // Postincrement.
+ inline SparseBitVectorIterator operator++(int) {
+ SparseBitVectorIterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Return the current set bit number.
+ unsigned operator*() const {
+ return BitNumber;
+ }
+
+ bool operator==(const SparseBitVectorIterator &RHS) const {
+ // If they are both at the end, ignore the rest of the fields.
+ if (AtEnd && RHS.AtEnd)
+ return true;
+ // Otherwise they are the same if they have the same bit number and
+ // bitmap.
+ return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
+ }
+ bool operator!=(const SparseBitVectorIterator &RHS) const {
+ return !(*this == RHS);
+ }
+ SparseBitVectorIterator(): BitVector(NULL) {
+ }
+
+
+ SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
+ bool end = false):BitVector(RHS) {
+ Iter = BitVector->Elements.begin();
+ BitNumber = 0;
+ Bits = 0;
+ WordNumber = ~0;
+ AtEnd = end;
+ AdvanceToFirstNonZero();
+ }
+ };
+public:
+ typedef SparseBitVectorIterator iterator;
+
+ SparseBitVector () {
+ CurrElementIter = Elements.begin ();
+ }
+
+ ~SparseBitVector() {
+ }
+
+ // SparseBitVector copy ctor.
+ SparseBitVector(const SparseBitVector &RHS) {
+ ElementListConstIter ElementIter = RHS.Elements.begin();
+ while (ElementIter != RHS.Elements.end()) {
+ Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+ ++ElementIter;
+ }
+
+ CurrElementIter = Elements.begin ();
+ }
+
+ // Clear.
+ void clear() {
+ Elements.clear();
+ }
+
+ // Assignment
+ SparseBitVector& operator=(const SparseBitVector& RHS) {
+ Elements.clear();
+
+ ElementListConstIter ElementIter = RHS.Elements.begin();
+ while (ElementIter != RHS.Elements.end()) {
+ Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
+ ++ElementIter;
+ }
+
+ CurrElementIter = Elements.begin ();
+
+ return *this;
+ }
+
+ // Test, Reset, and Set a bit in the bitmap.
+ bool test(unsigned Idx) {
+ if (Elements.empty())
+ return false;
+
+ unsigned ElementIndex = Idx / ElementSize;
+ ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+ // If we can't find an element that is supposed to contain this bit, there
+ // is nothing more to do.
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex)
+ return false;
+ return ElementIter->test(Idx % ElementSize);
+ }
+
+ void reset(unsigned Idx) {
+ if (Elements.empty())
+ return;
+
+ unsigned ElementIndex = Idx / ElementSize;
+ ElementListIter ElementIter = FindLowerBound(ElementIndex);
+
+ // If we can't find an element that is supposed to contain this bit, there
+ // is nothing more to do.
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex)
+ return;
+ ElementIter->reset(Idx % ElementSize);
+
+ // When the element is zeroed out, delete it.
+ if (ElementIter->empty()) {
+ ++CurrElementIter;
+ Elements.erase(ElementIter);
+ }
+ }
+
+ void set(unsigned Idx) {
+ unsigned ElementIndex = Idx / ElementSize;
+ SparseBitVectorElement<ElementSize> *Element;
+ ElementListIter ElementIter;
+ if (Elements.empty()) {
+ Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+ ElementIter = Elements.insert(Elements.end(), Element);
+
+ } else {
+ ElementIter = FindLowerBound(ElementIndex);
+
+ if (ElementIter == Elements.end() ||
+ ElementIter->index() != ElementIndex) {
+ Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
+ // We may have hit the beginning of our SparseBitVector, in which case,
+ // we may need to insert right after this element, which requires moving
+ // the current iterator forward one, because insert does insert before.
+ if (ElementIter != Elements.end() &&
+ ElementIter->index() < ElementIndex)
+ ElementIter = Elements.insert(++ElementIter, Element);
+ else
+ ElementIter = Elements.insert(ElementIter, Element);
+ }
+ }
+ CurrElementIter = ElementIter;
+
+ ElementIter->set(Idx % ElementSize);
+ }
+
+ bool test_and_set (unsigned Idx) {
+ bool old = test(Idx);
+ if (!old) {
+ set(Idx);
+ return true;
+ }
+ return false;
+ }
+
+ bool operator!=(const SparseBitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ bool operator==(const SparseBitVector &RHS) const {
+ ElementListConstIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
+ ++Iter1, ++Iter2) {
+ if (*Iter1 != *Iter2)
+ return false;
+ }
+ return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
+ }
+
+ // Union our bitmap with the RHS and return true if we changed.
+ bool operator|=(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // If RHS is empty, we are done
+ if (RHS.Elements.empty())
+ return false;
+
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
+ Elements.insert(Iter1,
+ new SparseBitVectorElement<ElementSize>(*Iter2));
+ ++Iter2;
+ changed = true;
+ } else if (Iter1->index() == Iter2->index()) {
+ changed |= Iter1->unionWith(*Iter2);
+ ++Iter1;
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ // Intersect our bitmap with the RHS and return true if ours changed.
+ bool operator&=(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // Check if both bitmaps are empty.
+ if (Elements.empty() && RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end()) {
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero;
+ changed |= Iter1->intersectWith(*Iter2, BecameZero);
+ if (BecameZero) {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ } else {
+ ++Iter1;
+ }
+ ++Iter2;
+ } else {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ }
+ }
+ Elements.erase(Iter1, Elements.end());
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ // Intersect our bitmap with the complement of the RHS and return true
+ // if ours changed.
+ bool intersectWithComplement(const SparseBitVector &RHS) {
+ bool changed = false;
+ ElementListIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // If either our bitmap or RHS is empty, we are done
+ if (Elements.empty() || RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end()) {
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero;
+ changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
+ if (BecameZero) {
+ ElementListIter IterTmp = Iter1;
+ ++Iter1;
+ Elements.erase(IterTmp);
+ } else {
+ ++Iter1;
+ }
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ CurrElementIter = Elements.begin();
+ return changed;
+ }
+
+ bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
+ return intersectWithComplement(*RHS);
+ }
+
+
+ // Three argument version of intersectWithComplement.
+ // Result of RHS1 & ~RHS2 is stored into this bitmap.
+ void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
+ const SparseBitVector<ElementSize> &RHS2)
+ {
+ Elements.clear();
+ CurrElementIter = Elements.begin();
+ ElementListConstIter Iter1 = RHS1.Elements.begin();
+ ElementListConstIter Iter2 = RHS2.Elements.begin();
+
+ // If RHS1 is empty, we are done
+ // If RHS2 is empty, we still have to copy RHS1
+ if (RHS1.Elements.empty())
+ return;
+
+ // Loop through, intersecting as we go, erasing elements when necessary.
+ while (Iter2 != RHS2.Elements.end()) {
+ if (Iter1 == RHS1.Elements.end())
+ return;
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ bool BecameZero = false;
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(Iter1->index());
+ NewElement->intersectWithComplement(*Iter1, *Iter2, BecameZero);
+ if (!BecameZero) {
+ Elements.push_back(NewElement);
+ }
+ else
+ delete NewElement;
+ ++Iter1;
+ ++Iter2;
+ } else {
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(*Iter1);
+ Elements.push_back(NewElement);
+ ++Iter1;
+ }
+ }
+
+ // copy the remaining elements
+ while (Iter1 != RHS1.Elements.end()) {
+ SparseBitVectorElement<ElementSize> *NewElement =
+ new SparseBitVectorElement<ElementSize>(*Iter1);
+ Elements.push_back(NewElement);
+ ++Iter1;
+ }
+
+ return;
+ }
+
+ void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
+ const SparseBitVector<ElementSize> *RHS2) {
+ intersectWithComplement(*RHS1, *RHS2);
+ }
+
+ bool intersects(const SparseBitVector<ElementSize> *RHS) const {
+ return intersects(*RHS);
+ }
+
+ // Return true if we share any bits in common with RHS
+ bool intersects(const SparseBitVector<ElementSize> &RHS) const {
+ ElementListConstIter Iter1 = Elements.begin();
+ ElementListConstIter Iter2 = RHS.Elements.begin();
+
+ // Check if both bitmaps are empty.
+ if (Elements.empty() && RHS.Elements.empty())
+ return false;
+
+ // Loop through, intersecting stopping when we hit bits in common.
+ while (Iter2 != RHS.Elements.end()) {
+ if (Iter1 == Elements.end())
+ return false;
+
+ if (Iter1->index() > Iter2->index()) {
+ ++Iter2;
+ } else if (Iter1->index() == Iter2->index()) {
+ if (Iter1->intersects(*Iter2))
+ return true;
+ ++Iter1;
+ ++Iter2;
+ } else {
+ ++Iter1;
+ }
+ }
+ return false;
+ }
+
+ // Return true iff all bits set in this SparseBitVector are
+ // also set in RHS.
+ bool contains(const SparseBitVector<ElementSize> &RHS) const {
+ SparseBitVector<ElementSize> Result(*this);
+ Result &= RHS;
+ return (Result == RHS);
+ }
+
+ // Return the first set bit in the bitmap. Return -1 if no bits are set.
+ int find_first() const {
+ if (Elements.empty())
+ return -1;
+ const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
+ return (First.index() * ElementSize) + First.find_first();
+ }
+
+ // Return true if the SparseBitVector is empty
+ bool empty() const {
+ return Elements.empty();
+ }
+
+ unsigned count() const {
+ unsigned BitCount = 0;
+ for (ElementListConstIter Iter = Elements.begin();
+ Iter != Elements.end();
+ ++Iter)
+ BitCount += Iter->count();
+
+ return BitCount;
+ }
+ iterator begin() const {
+ return iterator(this);
+ }
+
+ iterator end() const {
+ return iterator(this, true);
+ }
+};
+
+// Convenience functions to allow Or and And without dereferencing in the user
+// code.
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> *RHS) {
+ return LHS |= *RHS;
+}
+
+template <unsigned ElementSize>
+inline bool operator |=(SparseBitVector<ElementSize> *LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ return LHS->operator|=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> *LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ return LHS->operator&=(RHS);
+}
+
+template <unsigned ElementSize>
+inline bool operator &=(SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> *RHS) {
+ return LHS &= *RHS;
+}
+
+// Convenience functions for infix union, intersection, difference operators.
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator|(const SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ SparseBitVector<ElementSize> Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator&(const SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ SparseBitVector<ElementSize> Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+template <unsigned ElementSize>
+inline SparseBitVector<ElementSize>
+operator-(const SparseBitVector<ElementSize> &LHS,
+ const SparseBitVector<ElementSize> &RHS) {
+ SparseBitVector<ElementSize> Result;
+ Result.intersectWithComplement(LHS, RHS);
+ return Result;
+}
+
+
+
+
+// Dump a SparseBitVector to a stream
+template <unsigned ElementSize>
+void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
+ out << "[";
+
+ typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
+ be = LHS.end();
+ if (bi != be) {
+ out << *bi;
+ for (++bi; bi != be; ++bi) {
+ out << " " << *bi;
+ }
+ }
+ out << "]\n";
+}
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/SparseSet.h b/contrib/llvm/include/llvm/ADT/SparseSet.h
new file mode 100644
index 000000000000..923c6a5954d0
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/SparseSet.h
@@ -0,0 +1,268 @@
+//===--- llvm/ADT/SparseSet.h - Sparse set ----------------------*- 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 SparseSet class derived from the version described in
+// Briggs, Torczon, "An efficient representation for sparse sets", ACM Letters
+// on Programming Languages and Systems, Volume 2 Issue 1-4, March-Dec. 1993.
+//
+// A sparse set holds a small number of objects identified by integer keys from
+// a moderately sized universe. The sparse set uses more memory than other
+// containers in order to provide faster operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSESET_H
+#define LLVM_ADT_SPARSESET_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <limits>
+
+namespace llvm {
+
+/// SparseSetFunctor - Objects in a SparseSet are identified by small integer
+/// keys. A functor object is used to compute the key of an object. The
+/// functor's operator() must return an unsigned smaller than the universe.
+///
+/// The default functor implementation forwards to a getSparseSetKey() method
+/// on the object. It is intended for sparse sets holding ad-hoc structs.
+///
+template<typename ValueT>
+struct SparseSetFunctor {
+ unsigned operator()(const ValueT &Val) {
+ return Val.getSparseSetKey();
+ }
+};
+
+/// SparseSetFunctor<unsigned> - Provide a trivial identity functor for
+/// SparseSet<unsigned>.
+///
+template<> struct SparseSetFunctor<unsigned> {
+ unsigned operator()(unsigned Val) { return Val; }
+};
+
+/// SparseSet - Fast set implementation for objects that can be identified by
+/// small unsigned keys.
+///
+/// SparseSet allocates memory proportional to the size of the key universe, so
+/// it is not recommended for building composite data structures. It is useful
+/// for algorithms that require a single set with fast operations.
+///
+/// Compared to DenseSet and DenseMap, SparseSet provides constant-time fast
+/// clear() and iteration as fast as a vector. The find(), insert(), and
+/// erase() operations are all constant time, and typically faster than a hash
+/// table. The iteration order doesn't depend on numerical key values, it only
+/// depends on the order of insert() and erase() operations. When no elements
+/// have been erased, the iteration order is the insertion order.
+///
+/// Compared to BitVector, SparseSet<unsigned> uses 8x-40x more memory, but
+/// offers constant-time clear() and size() operations as well as fast
+/// iteration independent on the size of the universe.
+///
+/// SparseSet contains a dense vector holding all the objects and a sparse
+/// array holding indexes into the dense vector. Most of the memory is used by
+/// the sparse array which is the size of the key universe. The SparseT
+/// template parameter provides a space/speed tradeoff for sets holding many
+/// elements.
+///
+/// When SparseT is uint32_t, find() only touches 2 cache lines, but the sparse
+/// array uses 4 x Universe bytes.
+///
+/// When SparseT is uint8_t (the default), find() touches up to 2+[N/256] cache
+/// lines, but the sparse array is 4x smaller. N is the number of elements in
+/// the set.
+///
+/// For sets that may grow to thousands of elements, SparseT should be set to
+/// uint16_t or uint32_t.
+///
+/// @param ValueT The type of objects in the set.
+/// @param SparseT An unsigned integer type. See above.
+/// @param KeyFunctorT A functor that computes the unsigned key of a ValueT.
+///
+template<typename ValueT,
+ typename SparseT = uint8_t,
+ typename KeyFunctorT = SparseSetFunctor<ValueT> >
+class SparseSet {
+ typedef SmallVector<ValueT, 8> DenseT;
+ DenseT Dense;
+ SparseT *Sparse;
+ unsigned Universe;
+ KeyFunctorT KeyOf;
+
+ // 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.
+
+public:
+ typedef ValueT value_type;
+ typedef ValueT &reference;
+ typedef const ValueT &const_reference;
+ typedef ValueT *pointer;
+ typedef const ValueT *const_pointer;
+
+ SparseSet() : Sparse(0), Universe(0) {}
+ ~SparseSet() { free(Sparse); }
+
+ /// setUniverse - Set the universe size which determines the largest key the
+ /// set can hold. The universe must be sized before any elements can be
+ /// added.
+ ///
+ /// @param U Universe size. All object keys must be less than U.
+ ///
+ void setUniverse(unsigned U) {
+ // It's not hard to resize the universe on a non-empty set, but it doesn't
+ // seem like a likely use case, so we can add that code when we need it.
+ assert(empty() && "Can only resize universe on an empty map");
+ // Hysteresis prevents needless reallocations.
+ if (U >= Universe/4 && U <= Universe)
+ return;
+ free(Sparse);
+ // The Sparse array doesn't actually need to be initialized, so malloc
+ // would be enough here, but that will cause tools like valgrind to
+ // complain about branching on uninitialized data.
+ Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
+ Universe = U;
+ }
+
+ // Import trivial vector stuff from DenseT.
+ typedef typename DenseT::iterator iterator;
+ typedef typename DenseT::const_iterator const_iterator;
+
+ const_iterator begin() const { return Dense.begin(); }
+ const_iterator end() const { return Dense.end(); }
+ iterator begin() { return Dense.begin(); }
+ iterator end() { return Dense.end(); }
+
+ /// empty - Returns true if the set is empty.
+ ///
+ /// This is not the same as BitVector::empty().
+ ///
+ bool empty() const { return Dense.empty(); }
+
+ /// size - Returns the number of elements in the set.
+ ///
+ /// This is not the same as BitVector::size() which returns the size of the
+ /// universe.
+ ///
+ unsigned size() const { return Dense.size(); }
+
+ /// clear - Clears the set. This is a very fast constant time operation.
+ ///
+ void clear() {
+ // Sparse does not need to be cleared, see find().
+ Dense.clear();
+ }
+
+ /// find - Find an element by its key.
+ ///
+ /// @param Key A valid key to find.
+ /// @returns An iterator to the element identified by key, or end().
+ ///
+ iterator find(unsigned Key) {
+ assert(Key < Universe && "Key out of range");
+ assert(std::numeric_limits<SparseT>::is_integer &&
+ !std::numeric_limits<SparseT>::is_signed &&
+ "SparseT must be an unsigned integer type");
+ const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
+ for (unsigned i = Sparse[Key], e = size(); i < e; i += Stride) {
+ const unsigned FoundKey = KeyOf(Dense[i]);
+ assert(FoundKey < Universe && "Invalid key in set. Did object mutate?");
+ if (Key == FoundKey)
+ return begin() + i;
+ // Stride is 0 when SparseT >= unsigned. We don't need to loop.
+ if (!Stride)
+ break;
+ }
+ return end();
+ }
+
+ const_iterator find(unsigned Key) const {
+ return const_cast<SparseSet*>(this)->find(Key);
+ }
+
+ /// count - Returns true if this set contains an element identified by Key.
+ ///
+ bool count(unsigned Key) const {
+ return find(Key) != end();
+ }
+
+ /// insert - Attempts to insert a new element.
+ ///
+ /// If Val is successfully inserted, return (I, true), where I is an iterator
+ /// pointing to the newly inserted element.
+ ///
+ /// If the set already contains an element with the same key as Val, return
+ /// (I, false), where I is an iterator pointing to the existing element.
+ ///
+ /// Insertion invalidates all iterators.
+ ///
+ std::pair<iterator, bool> insert(const ValueT &Val) {
+ unsigned Key = KeyOf(Val);
+ iterator I = find(Key);
+ if (I != end())
+ return std::make_pair(I, false);
+ Sparse[Key] = size();
+ Dense.push_back(Val);
+ return std::make_pair(end() - 1, true);
+ }
+
+ /// array subscript - If an element already exists with this key, return it.
+ /// Otherwise, automatically construct a new value from Key, insert it,
+ /// and return the newly inserted element.
+ ValueT &operator[](unsigned Key) {
+ return *insert(ValueT(Key)).first;
+ }
+
+ /// erase - Erases an existing element identified by a valid iterator.
+ ///
+ /// This invalidates all iterators, but erase() returns an iterator pointing
+ /// to the next element. This makes it possible to erase selected elements
+ /// while iterating over the set:
+ ///
+ /// for (SparseSet::iterator I = Set.begin(); I != Set.end();)
+ /// if (test(*I))
+ /// I = Set.erase(I);
+ /// else
+ /// ++I;
+ ///
+ /// Note that end() changes when elements are erased, unlike std::list.
+ ///
+ iterator erase(iterator I) {
+ assert(unsigned(I - begin()) < size() && "Invalid iterator");
+ if (I != end() - 1) {
+ *I = Dense.back();
+ unsigned BackKey = KeyOf(Dense.back());
+ assert(BackKey < Universe && "Invalid key in set. Did object mutate?");
+ Sparse[BackKey] = I - begin();
+ }
+ // This depends on SmallVector::pop_back() not invalidating iterators.
+ // std::vector::pop_back() doesn't give that guarantee.
+ Dense.pop_back();
+ return I;
+ }
+
+ /// erase - Erases an element identified by Key, if it exists.
+ ///
+ /// @param Key The key identifying the element to erase.
+ /// @returns True when an element was erased, false if no element was found.
+ ///
+ bool erase(unsigned Key) {
+ iterator I = find(Key);
+ if (I == end())
+ return false;
+ erase(I);
+ return true;
+ }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/Statistic.h b/contrib/llvm/include/llvm/ADT/Statistic.h
new file mode 100644
index 000000000000..b54d10b9dd33
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/Statistic.h
@@ -0,0 +1,139 @@
+//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- 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 'Statistic' class, which is designed to be an easy way
+// to expose various metrics from passes. These statistics are printed at the
+// end of a run (from llvm_shutdown), when the -stats command line option is
+// passed on the command line.
+//
+// This is useful for reporting information like the number of instructions
+// simplified, optimized or removed by various transformations, like this:
+//
+// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
+//
+// Later, in the code: ++NumInstsKilled;
+//
+// NOTE: Statistics *must* be declared as global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STATISTIC_H
+#define LLVM_ADT_STATISTIC_H
+
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Valgrind.h"
+
+namespace llvm {
+class raw_ostream;
+
+class Statistic {
+public:
+ const char *Name;
+ const char *Desc;
+ volatile llvm::sys::cas_flag Value;
+ bool Initialized;
+
+ llvm::sys::cas_flag getValue() const { return Value; }
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+
+ /// construct - This should only be called for non-global statistics.
+ void construct(const char *name, const char *desc) {
+ Name = name; Desc = desc;
+ Value = 0; Initialized = 0;
+ }
+
+ // Allow use of this class as the value itself.
+ operator unsigned() const { return Value; }
+ const Statistic &operator=(unsigned Val) {
+ Value = Val;
+ return init();
+ }
+
+ const Statistic &operator++() {
+ // FIXME: This function and all those that follow carefully use an
+ // atomic operation to update the value safely in the presence of
+ // concurrent accesses, but not to read the return value, so the
+ // return value is not thread safe.
+ sys::AtomicIncrement(&Value);
+ return init();
+ }
+
+ unsigned operator++(int) {
+ init();
+ unsigned OldValue = Value;
+ sys::AtomicIncrement(&Value);
+ return OldValue;
+ }
+
+ const Statistic &operator--() {
+ sys::AtomicDecrement(&Value);
+ return init();
+ }
+
+ unsigned operator--(int) {
+ init();
+ unsigned OldValue = Value;
+ sys::AtomicDecrement(&Value);
+ return OldValue;
+ }
+
+ const Statistic &operator+=(const unsigned &V) {
+ if (!V) return *this;
+ sys::AtomicAdd(&Value, V);
+ return init();
+ }
+
+ const Statistic &operator-=(const unsigned &V) {
+ if (!V) return *this;
+ sys::AtomicAdd(&Value, -V);
+ return init();
+ }
+
+ const Statistic &operator*=(const unsigned &V) {
+ sys::AtomicMul(&Value, V);
+ return init();
+ }
+
+ const Statistic &operator/=(const unsigned &V) {
+ sys::AtomicDiv(&Value, V);
+ return init();
+ }
+
+protected:
+ Statistic &init() {
+ bool tmp = Initialized;
+ sys::MemoryFence();
+ if (!tmp) RegisterStatistic();
+ TsanHappensAfter(this);
+ return *this;
+ }
+ void RegisterStatistic();
+};
+
+// STATISTIC - A macro to make definition of statistics really simple. This
+// automatically passes the DEBUG_TYPE of the file into the statistic.
+#define STATISTIC(VARNAME, DESC) \
+ static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
+
+/// \brief Enable the collection and printing of statistics.
+void EnableStatistics();
+
+/// \brief Check if statistics are enabled.
+bool AreStatisticsEnabled();
+
+/// \brief Print statistics to the file returned by CreateInfoOutputFile().
+void PrintStatistics();
+
+/// \brief Print statistics to the given output stream.
+void PrintStatistics(raw_ostream &OS);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/StringExtras.h b/contrib/llvm/include/llvm/ADT/StringExtras.h
new file mode 100644
index 000000000000..655d884e7baa
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/StringExtras.h
@@ -0,0 +1,134 @@
+//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful when dealing with strings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGEXTRAS_H
+#define LLVM_ADT_STRINGEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/StringRef.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).
+static inline char hexdigit(unsigned X, bool LowerCase = false) {
+ const char HexChar = LowerCase ? 'a' : 'A';
+ return X < 10 ? '0' + X : HexChar + X - 10;
+}
+
+/// utohex_buffer - Emit the specified number into the buffer specified by
+/// BufferEnd, returning a pointer to the start of the string. This can be used
+/// like this: (note that the buffer must be large enough to handle any number):
+/// char Buffer[40];
+/// printf("0x%s", utohex_buffer(X, Buffer+40));
+///
+/// This should only be used with unsigned types.
+///
+template<typename IntTy>
+static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
+ char *BufPtr = BufferEnd;
+ *--BufPtr = 0; // Null terminate buffer.
+ if (X == 0) {
+ *--BufPtr = '0'; // Handle special case.
+ return BufPtr;
+ }
+
+ while (X) {
+ unsigned char Mod = static_cast<unsigned char>(X) & 15;
+ *--BufPtr = hexdigit(Mod);
+ X >>= 4;
+ }
+ return BufPtr;
+}
+
+static inline std::string utohexstr(uint64_t X) {
+ char Buffer[17];
+ return utohex_buffer(X, Buffer+17);
+}
+
+static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
+ char Buffer[11];
+ char *BufPtr = Buffer+11;
+
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+
+ return std::string(BufPtr, Buffer+11);
+}
+
+static inline std::string utostr(uint64_t X, bool isNeg = false) {
+ char Buffer[21];
+ char *BufPtr = Buffer+21;
+
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+ return std::string(BufPtr, Buffer+21);
+}
+
+
+static inline std::string itostr(int64_t X) {
+ if (X < 0)
+ return utostr(static_cast<uint64_t>(-X), true);
+ else
+ return utostr(static_cast<uint64_t>(X));
+}
+
+/// StrInStrNoCase - Portable version of strcasestr. Locates the first
+/// occurrence of string 's1' in string 's2', ignoring case. Returns
+/// the offset of s2 in s1 or npos if s2 cannot be found.
+StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
+
+/// getToken - This function extracts one token from source, ignoring any
+/// leading characters that appear in the Delimiters string, and ending the
+/// token at any of the characters that appear in the Delimiters string. If
+/// there are no tokens in the source string, an empty string is returned.
+/// The function returns a pair containing the extracted token and the
+/// remaining tail string.
+std::pair<StringRef, StringRef> getToken(StringRef Source,
+ StringRef Delimiters = " \t\n\v\f\r");
+
+/// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+void SplitString(StringRef Source,
+ SmallVectorImpl<StringRef> &OutFragments,
+ StringRef Delimiters = " \t\n\v\f\r");
+
+/// HashString - Hash function for strings.
+///
+/// This is the Bernstein hash function.
+//
+// FIXME: Investigate whether a modified bernstein hash function performs
+// better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
+// X*33+c -> X*33^c
+static inline unsigned HashString(StringRef Str, unsigned Result = 0) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ Result = Result * 33 + Str[i];
+ return Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/StringMap.h b/contrib/llvm/include/llvm/ADT/StringMap.h
new file mode 100644
index 000000000000..b4497a276d0e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/StringMap.h
@@ -0,0 +1,463 @@
+//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StringMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGMAP_H
+#define LLVM_ADT_STRINGMAP_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include <cstring>
+
+namespace llvm {
+ template<typename ValueT>
+ class StringMapConstIterator;
+ template<typename ValueT>
+ class StringMapIterator;
+ template<typename ValueTy>
+ class StringMapEntry;
+
+/// StringMapEntryInitializer - This datatype can be partially specialized for
+/// various datatypes in a stringmap to allow them to be initialized when an
+/// entry is default constructed for the map.
+template<typename ValueTy>
+class StringMapEntryInitializer {
+public:
+ template <typename InitTy>
+ static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) {
+ T.second = InitVal;
+ }
+};
+
+
+/// StringMapEntryBase - Shared base class of StringMapEntry instances.
+class StringMapEntryBase {
+ unsigned StrLen;
+public:
+ explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+
+ unsigned getKeyLength() const { return StrLen; }
+};
+
+/// StringMapImpl - This is the base class of StringMap that is shared among
+/// all of its instantiations.
+class StringMapImpl {
+protected:
+ // Array of NumBuckets pointers to entries, null pointers are holes.
+ // TheTable[NumBuckets] contains a sentinel value for easy iteration. Follwed
+ // by an array of the actual hash values as unsigned integers.
+ StringMapEntryBase **TheTable;
+ unsigned NumBuckets;
+ unsigned NumItems;
+ unsigned NumTombstones;
+ unsigned ItemSize;
+protected:
+ explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
+ // Initialize the map with zero buckets to allocation.
+ TheTable = 0;
+ NumBuckets = 0;
+ NumItems = 0;
+ NumTombstones = 0;
+ }
+ StringMapImpl(unsigned InitSize, unsigned ItemSize);
+ void RehashTable();
+
+ /// LookupBucketFor - Look up the bucket that the specified string should end
+ /// up in. If it already exists as a key in the map, the Item pointer for the
+ /// specified bucket will be non-null. Otherwise, it will be null. In either
+ /// case, the FullHashValue field of the bucket will be set to the hash value
+ /// of the string.
+ unsigned LookupBucketFor(StringRef Key);
+
+ /// FindKey - Look up the bucket that contains the specified key. If it exists
+ /// in the map, return the bucket number of the key. Otherwise return -1.
+ /// This does not modify the map.
+ int FindKey(StringRef Key) const;
+
+ /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+ /// delete it. This aborts if the value isn't in the table.
+ void RemoveKey(StringMapEntryBase *V);
+
+ /// RemoveKey - Remove the StringMapEntry for the specified key from the
+ /// table, returning it. If the key is not in the table, this returns null.
+ StringMapEntryBase *RemoveKey(StringRef Key);
+private:
+ void init(unsigned Size);
+public:
+ static StringMapEntryBase *getTombstoneVal() {
+ return (StringMapEntryBase*)-1;
+ }
+
+ unsigned getNumBuckets() const { return NumBuckets; }
+ unsigned getNumItems() const { return NumItems; }
+
+ bool empty() const { return NumItems == 0; }
+ unsigned size() const { return NumItems; }
+};
+
+/// StringMapEntry - This is used to represent one value that is inserted into
+/// a StringMap. It contains the Value itself and the key: the string length
+/// and data.
+template<typename ValueTy>
+class StringMapEntry : public StringMapEntryBase {
+public:
+ ValueTy second;
+
+ explicit StringMapEntry(unsigned strLen)
+ : StringMapEntryBase(strLen), second() {}
+ StringMapEntry(unsigned strLen, const ValueTy &V)
+ : StringMapEntryBase(strLen), second(V) {}
+
+ StringRef getKey() const {
+ return StringRef(getKeyData(), getKeyLength());
+ }
+
+ const ValueTy &getValue() const { return second; }
+ ValueTy &getValue() { return second; }
+
+ void setValue(const ValueTy &V) { second = V; }
+
+ /// getKeyData - Return the start of the string data that is the key for this
+ /// value. The string data is always stored immediately after the
+ /// StringMapEntry object.
+ const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
+
+ StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
+
+ /// Create - Create a StringMapEntry for the specified key and default
+ /// construct the value.
+ template<typename AllocatorTy, typename InitType>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator,
+ InitType InitVal) {
+ unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart);
+
+ // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
+ // in. Allocate a new item with space for the string at the end and a null
+ // terminator.
+
+ unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+
+ KeyLength+1;
+ unsigned Alignment = alignOf<StringMapEntry>();
+
+ StringMapEntry *NewItem =
+ static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
+
+ // Default construct the value.
+ new (NewItem) StringMapEntry(KeyLength);
+
+ // Copy the string information.
+ char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
+ memcpy(StrBuffer, KeyStart, KeyLength);
+ StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
+
+ // Initialize the value if the client wants to.
+ StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal);
+ return NewItem;
+ }
+
+ template<typename AllocatorTy>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator) {
+ 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,
+ InitType InitVal) {
+ MallocAllocator A;
+ return Create(KeyStart, KeyEnd, A, InitVal);
+ }
+
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) {
+ return Create(KeyStart, KeyEnd, ValueTy());
+ }
+
+ /// GetStringMapEntryFromValue - Given a value that is known to be embedded
+ /// into a StringMapEntry, return the StringMapEntry itself.
+ static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) {
+ StringMapEntry *EPtr = 0;
+ char *Ptr = reinterpret_cast<char*>(&V) -
+ (reinterpret_cast<char*>(&EPtr->second) -
+ reinterpret_cast<char*>(EPtr));
+ return *reinterpret_cast<StringMapEntry*>(Ptr);
+ }
+ static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
+ return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));
+ }
+
+ /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded
+ /// into a StringMapEntry, return the StringMapEntry itself.
+ static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) {
+ char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>);
+ return *reinterpret_cast<StringMapEntry*>(Ptr);
+ }
+
+
+ /// Destroy - Destroy this StringMapEntry, releasing memory back to the
+ /// specified allocator.
+ template<typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~StringMapEntry();
+ Allocator.Deallocate(this);
+ }
+
+ /// Destroy this object, releasing memory back to the malloc allocator.
+ void Destroy() {
+ MallocAllocator A;
+ Destroy(A);
+ }
+};
+
+
+/// StringMap - This is an unconventional map that is specialized for handling
+/// keys that are "strings", which are basically ranges of bytes. This does some
+/// funky memory allocation and hashing things to make it extremely efficient,
+/// storing the string data *after* the value in the map.
+template<typename ValueTy, typename AllocatorTy = MallocAllocator>
+class StringMap : public StringMapImpl {
+ AllocatorTy Allocator;
+public:
+ typedef StringMapEntry<ValueTy> MapEntryTy;
+
+ StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
+ explicit StringMap(unsigned InitialSize)
+ : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
+
+ explicit StringMap(AllocatorTy A)
+ : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
+
+ StringMap(const StringMap &RHS)
+ : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
+ assert(RHS.empty() &&
+ "Copy ctor from non-empty stringmap not implemented yet!");
+ (void)RHS;
+ }
+ void operator=(const StringMap &RHS) {
+ assert(RHS.empty() &&
+ "assignment from non-empty stringmap not implemented yet!");
+ (void)RHS;
+ clear();
+ }
+
+ typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy;
+ typedef typename ReferenceAdder<const AllocatorTy>::result AllocatorCRefTy;
+ AllocatorRefTy getAllocator() { return Allocator; }
+ AllocatorCRefTy getAllocator() const { return Allocator; }
+
+ typedef const char* key_type;
+ typedef ValueTy mapped_type;
+ typedef StringMapEntry<ValueTy> value_type;
+ typedef size_t size_type;
+
+ typedef StringMapConstIterator<ValueTy> const_iterator;
+ typedef StringMapIterator<ValueTy> iterator;
+
+ iterator begin() {
+ return iterator(TheTable, NumBuckets == 0);
+ }
+ iterator end() {
+ return iterator(TheTable+NumBuckets, true);
+ }
+ const_iterator begin() const {
+ return const_iterator(TheTable, NumBuckets == 0);
+ }
+ const_iterator end() const {
+ return const_iterator(TheTable+NumBuckets, true);
+ }
+
+ iterator find(StringRef Key) {
+ int Bucket = FindKey(Key);
+ if (Bucket == -1) return end();
+ return iterator(TheTable+Bucket, true);
+ }
+
+ const_iterator find(StringRef Key) const {
+ int Bucket = FindKey(Key);
+ if (Bucket == -1) return end();
+ return const_iterator(TheTable+Bucket, true);
+ }
+
+ /// 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);
+ if (it != end())
+ return it->second;
+ return ValueTy();
+ }
+
+ ValueTy &operator[](StringRef Key) {
+ return GetOrCreateValue(Key).getValue();
+ }
+
+ size_type count(StringRef Key) const {
+ return find(Key) == end() ? 0 : 1;
+ }
+
+ /// insert - Insert the specified key/value pair into the map. If the key
+ /// already exists in the map, return false and ignore the request, otherwise
+ /// insert it and return true.
+ bool insert(MapEntryTy *KeyValue) {
+ unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
+ StringMapEntryBase *&Bucket = TheTable[BucketNo];
+ if (Bucket && Bucket != getTombstoneVal())
+ return false; // Already exists in map.
+
+ if (Bucket == getTombstoneVal())
+ --NumTombstones;
+ Bucket = KeyValue;
+ ++NumItems;
+ assert(NumItems + NumTombstones <= NumBuckets);
+
+ RehashTable();
+ return true;
+ }
+
+ // clear - Empties out the StringMap
+ void clear() {
+ if (empty()) return;
+
+ // Zap all values, resetting the keys back to non-present (not tombstone),
+ // which is safe because we're removing all elements.
+ for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+ StringMapEntryBase *&Bucket = TheTable[I];
+ if (Bucket && Bucket != getTombstoneVal()) {
+ static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+ Bucket = 0;
+ }
+ }
+
+ NumItems = 0;
+ NumTombstones = 0;
+ }
+
+ /// GetOrCreateValue - Look up the specified key in the table. If a value
+ /// exists, return it. Otherwise, default construct a value, insert it, and
+ /// return.
+ template <typename InitTy>
+ MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
+ unsigned BucketNo = LookupBucketFor(Key);
+ StringMapEntryBase *&Bucket = TheTable[BucketNo];
+ if (Bucket && Bucket != getTombstoneVal())
+ return *static_cast<MapEntryTy*>(Bucket);
+
+ MapEntryTy *NewItem =
+ MapEntryTy::Create(Key.begin(), Key.end(), Allocator, Val);
+
+ if (Bucket == getTombstoneVal())
+ --NumTombstones;
+ ++NumItems;
+ assert(NumItems + NumTombstones <= NumBuckets);
+
+ // Fill in the bucket for the hash table. The FullHashValue was already
+ // filled in by LookupBucketFor.
+ Bucket = NewItem;
+
+ RehashTable();
+ return *NewItem;
+ }
+
+ MapEntryTy &GetOrCreateValue(StringRef Key) {
+ return GetOrCreateValue(Key, ValueTy());
+ }
+
+ /// remove - Remove the specified key/value pair from the map, but do not
+ /// erase it. This aborts if the key is not in the map.
+ void remove(MapEntryTy *KeyValue) {
+ RemoveKey(KeyValue);
+ }
+
+ void erase(iterator I) {
+ MapEntryTy &V = *I;
+ remove(&V);
+ V.Destroy(Allocator);
+ }
+
+ bool erase(StringRef Key) {
+ iterator I = find(Key);
+ if (I == end()) return false;
+ erase(I);
+ return true;
+ }
+
+ ~StringMap() {
+ clear();
+ free(TheTable);
+ }
+};
+
+
+template<typename ValueTy>
+class StringMapConstIterator {
+protected:
+ StringMapEntryBase **Ptr;
+public:
+ typedef StringMapEntry<ValueTy> value_type;
+
+ explicit StringMapConstIterator(StringMapEntryBase **Bucket,
+ bool NoAdvance = false)
+ : Ptr(Bucket) {
+ if (!NoAdvance) AdvancePastEmptyBuckets();
+ }
+
+ const value_type &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(*Ptr);
+ }
+ const value_type *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(*Ptr);
+ }
+
+ bool operator==(const StringMapConstIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const StringMapConstIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline StringMapConstIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ StringMapConstIterator operator++(int) { // Postincrement
+ StringMapConstIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ while (*Ptr == 0 || *Ptr == StringMapImpl::getTombstoneVal())
+ ++Ptr;
+ }
+};
+
+template<typename ValueTy>
+class StringMapIterator : public StringMapConstIterator<ValueTy> {
+public:
+ explicit StringMapIterator(StringMapEntryBase **Bucket,
+ bool NoAdvance = false)
+ : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
+ }
+ StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
+ }
+ StringMapEntry<ValueTy> *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/StringRef.h b/contrib/llvm/include/llvm/ADT/StringRef.h
new file mode 100644
index 000000000000..76ba66e746ce
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/StringRef.h
@@ -0,0 +1,528 @@
+//===--- StringRef.h - Constant String Reference Wrapper --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGREF_H
+#define LLVM_ADT_STRINGREF_H
+
+#include "llvm/Support/type_traits.h"
+
+#include <cassert>
+#include <cstring>
+#include <limits>
+#include <string>
+#include <utility>
+
+namespace llvm {
+ template<typename T>
+ class SmallVectorImpl;
+ class APInt;
+ class hash_code;
+ class StringRef;
+
+ /// Helper functions for StringRef::getAsInteger.
+ bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
+ unsigned long long &Result);
+
+ bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
+
+ /// StringRef - Represent a constant reference to a string, i.e. a character
+ /// array and a length, which need not be null terminated.
+ ///
+ /// This class does not own the string data, it is expected to be used in
+ /// situations where the character data resides in some other buffer, whose
+ /// lifetime extends past that of the StringRef. For this reason, it is not in
+ /// general safe to store a StringRef.
+ class StringRef {
+ public:
+ typedef const char *iterator;
+ typedef const char *const_iterator;
+ static const size_t npos = ~size_t(0);
+ typedef size_t size_type;
+
+ private:
+ /// The start of the string, in an external buffer.
+ const char *Data;
+
+ /// The length of the string.
+ size_t Length;
+
+ // Workaround PR5482: nearly all gcc 4.x miscompile StringRef and std::min()
+ // Changing the arg of min to be an integer, instead of a reference to an
+ // integer works around this bug.
+ static size_t min(size_t a, size_t b) { return a < b ? a : b; }
+ static size_t max(size_t a, size_t b) { return a > b ? a : b; }
+
+ // Workaround memcmp issue with null pointers (undefined behavior)
+ // by providing a specialized version
+ static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
+ if (Length == 0) { return 0; }
+ return ::memcmp(Lhs,Rhs,Length);
+ }
+
+ public:
+ /// @name Constructors
+ /// @{
+
+ /// Construct an empty string ref.
+ /*implicit*/ StringRef() : Data(0), Length(0) {}
+
+ /// Construct a string ref from a cstring.
+ /*implicit*/ StringRef(const char *Str)
+ : Data(Str) {
+ assert(Str && "StringRef cannot be built from a NULL argument");
+ Length = ::strlen(Str); // invoking strlen(NULL) is undefined behavior
+ }
+
+ /// Construct a string ref from a pointer and length.
+ /*implicit*/ StringRef(const char *data, size_t length)
+ : Data(data), Length(length) {
+ assert((data || length == 0) &&
+ "StringRef cannot be built from a NULL argument with non-null length");
+ }
+
+ /// Construct a string ref from an std::string.
+ /*implicit*/ StringRef(const std::string &Str)
+ : Data(Str.data()), Length(Str.length()) {}
+
+ /// @}
+ /// @name Iterators
+ /// @{
+
+ iterator begin() const { return Data; }
+
+ iterator end() const { return Data + Length; }
+
+ /// @}
+ /// @name String Operations
+ /// @{
+
+ /// data - Get a pointer to the start of the string (which may not be null
+ /// terminated).
+ const char *data() const { return Data; }
+
+ /// empty - Check if the string is empty.
+ bool empty() const { return Length == 0; }
+
+ /// size - Get the string size.
+ size_t size() const { return Length; }
+
+ /// front - Get the first character in the string.
+ char front() const {
+ assert(!empty());
+ return Data[0];
+ }
+
+ /// back - Get the last character in the string.
+ char back() const {
+ assert(!empty());
+ return Data[Length-1];
+ }
+
+ /// equals - 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 (Length == RHS.Length &&
+ compareMemory(Data, RHS.Data, RHS.Length) == 0);
+ }
+
+ /// equals_lower - Check for string equality, ignoring case.
+ bool equals_lower(StringRef RHS) const {
+ return Length == RHS.Length && compare_lower(RHS) == 0;
+ }
+
+ /// 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.
+ int compare(StringRef RHS) const {
+ // Check the prefix for a mismatch.
+ if (int Res = compareMemory(Data, RHS.Data, min(Length, RHS.Length)))
+ return Res < 0 ? -1 : 1;
+
+ // Otherwise the prefixes match, so we only need to check the lengths.
+ if (Length == RHS.Length)
+ return 0;
+ return Length < RHS.Length ? -1 : 1;
+ }
+
+ /// compare_lower - Compare two strings, ignoring case.
+ int compare_lower(StringRef RHS) const;
+
+ /// compare_numeric - Compare two strings, treating sequences of digits as
+ /// numbers.
+ int compare_numeric(StringRef RHS) const;
+
+ /// \brief Determine the edit distance between this string and another
+ /// string.
+ ///
+ /// \param Other the string to compare this string against.
+ ///
+ /// \param AllowReplacements whether to allow character
+ /// replacements (change one character into another) as a single
+ /// operation, rather than as two operations (an insertion and a
+ /// removal).
+ ///
+ /// \param MaxEditDistance If non-zero, the maximum edit distance that
+ /// this routine is allowed to compute. If the edit distance will exceed
+ /// that maximum, returns \c MaxEditDistance+1.
+ ///
+ /// \returns the minimum number of character insertions, removals,
+ /// or (if \p AllowReplacements is \c true) replacements needed to
+ /// transform one of the given strings into the other. If zero,
+ /// the strings are identical.
+ unsigned edit_distance(StringRef Other, bool AllowReplacements = true,
+ unsigned MaxEditDistance = 0);
+
+ /// str - Get the contents as an std::string.
+ std::string str() const {
+ if (Data == 0) return std::string();
+ return std::string(Data, Length);
+ }
+
+ /// @}
+ /// @name Operator Overloads
+ /// @{
+
+ char operator[](size_t Index) const {
+ assert(Index < Length && "Invalid index!");
+ return Data[Index];
+ }
+
+ /// @}
+ /// @name Type Conversions
+ /// @{
+
+ operator std::string() const {
+ return str();
+ }
+
+ /// @}
+ /// @name String Predicates
+ /// @{
+
+ /// startswith - Check if this string starts with the given \arg 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.
+ bool endswith(StringRef Suffix) const {
+ return Length >= Suffix.Length &&
+ compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
+ }
+
+ /// @}
+ /// @name String Searching
+ /// @{
+
+ /// find - Search for the first character \arg C in the string.
+ ///
+ /// \return - The index of the first occurrence of \arg 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)
+ if (Data[i] == C)
+ return i;
+ return npos;
+ }
+
+ /// find - Search for the first string \arg Str in the string.
+ ///
+ /// \return - The index of the first occurrence of \arg 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.
+ ///
+ /// \return - The index of the last occurrence of \arg C, or npos if not
+ /// found.
+ size_t rfind(char C, size_t From = npos) const {
+ From = min(From, Length);
+ size_t i = From;
+ while (i != 0) {
+ --i;
+ if (Data[i] == C)
+ return i;
+ }
+ return npos;
+ }
+
+ /// rfind - Search for the last string \arg Str in the string.
+ ///
+ /// \return - The index of the last occurrence of \arg 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.
+ 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.
+ ///
+ /// Note: 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.
+ 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.
+ ///
+ /// Note: 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.
+ 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.
+ ///
+ /// Note: O(size() + Chars.size())
+ size_type find_last_of(StringRef Chars, size_t From = npos) const;
+
+ /// @}
+ /// @name Helpful Algorithms
+ /// @{
+
+ /// count - Return the number of occurrences of \arg C in the string.
+ size_t count(char C) const {
+ size_t Count = 0;
+ for (size_t i = 0, e = Length; i != e; ++i)
+ if (Data[i] == C)
+ ++Count;
+ return Count;
+ }
+
+ /// count - Return the number of non-overlapped occurrences of \arg 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
+ /// 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 {
+ long long LLVal;
+ if (getAsSignedInteger(*this, Radix, LLVal) ||
+ static_cast<T>(LLVal) != LLVal)
+ return true;
+ Result = LLVal;
+ return false;
+ }
+
+ template <typename T>
+ typename enable_if_c<!std::numeric_limits<T>::is_signed, bool>::type
+ getAsInteger(unsigned Radix, T &Result) const {
+ unsigned long long ULLVal;
+ if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
+ static_cast<T>(ULLVal) != ULLVal)
+ return true;
+ Result = ULLVal;
+ 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.
+ ///
+ /// Returns true if the string does not solely consist of a valid
+ /// non-empty number in the appropriate base.
+ ///
+ /// APInt::fromString is superficially similar but assumes the
+ /// string is well-formed in the given radix.
+ bool getAsInteger(unsigned Radix, APInt &Result) const;
+
+ /// @}
+ /// @name String Operations
+ /// @{
+
+ // lower - Convert the given ASCII string to lowercase.
+ std::string lower() const;
+
+ /// upper - 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).
+ ///
+ /// \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
+ /// exceeds the number of characters remaining in the string, the string
+ /// suffix (starting with \arg 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.
+ 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.
+ 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).
+ ///
+ /// \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
+ /// number of characters remaining in the string, the string suffix
+ /// (starting with \arg 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.
+ ///
+ /// If \arg 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
+ /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+ ///
+ /// \param Separator - The character to split on.
+ /// \return - The split substrings.
+ std::pair<StringRef, StringRef> split(char Separator) const {
+ size_t Idx = find(Separator);
+ if (Idx == npos)
+ return std::make_pair(*this, StringRef());
+ return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
+ }
+
+ /// split - 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)
+ /// 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
+ /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+ ///
+ /// \param Separator - The string to split on.
+ /// \return - The split substrings.
+ std::pair<StringRef, StringRef> split(StringRef Separator) const {
+ size_t Idx = find(Separator);
+ if (Idx == npos)
+ return std::make_pair(*this, StringRef());
+ return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
+ }
+
+ /// split - 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
+ /// 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
+ /// An useful invariant is that
+ /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
+ ///
+ /// \param A - Where to put the substrings.
+ /// \param Separator - The string to split on.
+ /// \param MaxSplit - The maximum number of times the string is split.
+ /// \param KeepEmpty - True if empty substring should be added.
+ void split(SmallVectorImpl<StringRef> &A,
+ StringRef Separator, int MaxSplit = -1,
+ bool KeepEmpty = true) const;
+
+ /// rsplit - 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)
+ /// 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
+ /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+ ///
+ /// \param Separator - The character to split on.
+ /// \return - The split substrings.
+ std::pair<StringRef, StringRef> rsplit(char Separator) const {
+ size_t Idx = rfind(Separator);
+ if (Idx == npos)
+ return std::make_pair(*this, StringRef());
+ return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
+ }
+
+ /// @}
+ };
+
+ /// @name StringRef Comparison Operators
+ /// @{
+
+ inline bool operator==(StringRef LHS, StringRef RHS) {
+ return LHS.equals(RHS);
+ }
+
+ inline bool operator!=(StringRef LHS, StringRef RHS) {
+ return !(LHS == RHS);
+ }
+
+ inline bool operator<(StringRef LHS, StringRef RHS) {
+ return LHS.compare(RHS) == -1;
+ }
+
+ inline bool operator<=(StringRef LHS, StringRef RHS) {
+ return LHS.compare(RHS) != 1;
+ }
+
+ inline bool operator>(StringRef LHS, StringRef RHS) {
+ return LHS.compare(RHS) == 1;
+ }
+
+ inline bool operator>=(StringRef LHS, StringRef RHS) {
+ return LHS.compare(RHS) != -1;
+ }
+
+ inline std::string &operator+=(std::string &buffer, llvm::StringRef string) {
+ return buffer.append(string.data(), string.size());
+ }
+
+ /// @}
+
+ /// \brief Compute a hash_code for a StringRef.
+ hash_code hash_value(StringRef S);
+
+ // StringRefs can be treated like a POD type.
+ template <typename T> struct isPodLike;
+ template <> struct isPodLike<StringRef> { static const bool value = true; };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/StringSet.h b/contrib/llvm/include/llvm/ADT/StringSet.h
new file mode 100644
index 000000000000..9c55f6b70e36
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/StringSet.h
@@ -0,0 +1,38 @@
+//===--- StringSet.h - The LLVM Compiler Driver -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// StringSet - A set-like wrapper for the StringMap.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGSET_H
+#define LLVM_ADT_STRINGSET_H
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+
+ /// StringSet - A wrapper for StringMap that provides set-like
+ /// functionality. Only insert() and count() methods are used by my
+ /// code.
+ template <class AllocatorTy = llvm::MallocAllocator>
+ class StringSet : public llvm::StringMap<char, AllocatorTy> {
+ typedef llvm::StringMap<char, AllocatorTy> base;
+ public:
+ bool insert(StringRef InLang) {
+ 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(), '+'));
+ }
+ };
+}
+
+#endif // LLVM_ADT_STRINGSET_H
diff --git a/contrib/llvm/include/llvm/ADT/StringSwitch.h b/contrib/llvm/include/llvm/ADT/StringSwitch.h
new file mode 100644
index 000000000000..74805830d854
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/StringSwitch.h
@@ -0,0 +1,126 @@
+//===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+// This file implements the StringSwitch template, which mimics a switch()
+// statement whose cases are string literals.
+//
+//===----------------------------------------------------------------------===/
+#ifndef LLVM_ADT_STRINGSWITCH_H
+#define LLVM_ADT_STRINGSWITCH_H
+
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+
+/// \brief A switch()-like statement whose cases are string literals.
+///
+/// The StringSwitch class is a simple form of a switch() statement that
+/// determines whether the given string matches one of the given string
+/// literals. The template type parameter \p T is the type of the value that
+/// will be returned from the string-switch expression. For example,
+/// the following code switches on the name of a color in \c argv[i]:
+///
+/// \code
+/// Color color = StringSwitch<Color>(argv[i])
+/// .Case("red", Red)
+/// .Case("orange", Orange)
+/// .Case("yellow", Yellow)
+/// .Case("green", Green)
+/// .Case("blue", Blue)
+/// .Case("indigo", Indigo)
+/// .Cases("violet", "purple", Violet)
+/// .Default(UnknownColor);
+/// \endcode
+template<typename T, typename R = T>
+class StringSwitch {
+ /// \brief The string we are matching.
+ StringRef Str;
+
+ /// \brief The pointer to the result of this switch statement, once known,
+ /// null before that.
+ const T *Result;
+
+public:
+ explicit StringSwitch(StringRef Str)
+ : Str(Str), Result(0) { }
+
+ template<unsigned N>
+ StringSwitch& Case(const char (&S)[N], const T& Value) {
+ if (!Result && N-1 == Str.size() &&
+ (std::memcmp(S, Str.data(), N-1) == 0)) {
+ Result = &Value;
+ }
+
+ return *this;
+ }
+
+ template<unsigned N>
+ StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
+ if (!Result && Str.size() >= N-1 &&
+ std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
+ Result = &Value;
+ }
+
+ return *this;
+ }
+
+ template<unsigned N>
+ StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
+ if (!Result && Str.size() >= N-1 &&
+ std::memcmp(S, Str.data(), N-1) == 0) {
+ Result = &Value;
+ }
+
+ return *this;
+ }
+
+ template<unsigned N0, unsigned N1>
+ StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+ const T& Value) {
+ return Case(S0, Value).Case(S1, Value);
+ }
+
+ template<unsigned N0, unsigned N1, unsigned N2>
+ StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+ const char (&S2)[N2], const T& Value) {
+ return Case(S0, Value).Case(S1, Value).Case(S2, Value);
+ }
+
+ template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
+ StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+ const char (&S2)[N2], const char (&S3)[N3],
+ const T& Value) {
+ return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value);
+ }
+
+ template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
+ StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
+ const char (&S2)[N2], const char (&S3)[N3],
+ const char (&S4)[N4], const T& Value) {
+ return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value)
+ .Case(S4, Value);
+ }
+
+ R Default(const T& Value) const {
+ if (Result)
+ return *Result;
+
+ return Value;
+ }
+
+ operator R() const {
+ assert(Result && "Fell off the end of a string-switch");
+ return *Result;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_STRINGSWITCH_H
diff --git a/contrib/llvm/include/llvm/ADT/TinyPtrVector.h b/contrib/llvm/include/llvm/ADT/TinyPtrVector.h
new file mode 100644
index 000000000000..5014517c9e05
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/TinyPtrVector.h
@@ -0,0 +1,165 @@
+//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TINYPTRVECTOR_H
+#define LLVM_ADT_TINYPTRVECTOR_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerUnion.h"
+
+namespace llvm {
+
+/// TinyPtrVector - This class is specialized for cases where there are
+/// normally 0 or 1 element in a vector, but is general enough to go beyond that
+/// when required.
+///
+/// NOTE: This container doesn't allow you to store a null pointer into it.
+///
+template <typename EltTy>
+class TinyPtrVector {
+public:
+ typedef llvm::SmallVector<EltTy, 4> VecTy;
+ llvm::PointerUnion<EltTy, VecTy*> Val;
+
+ TinyPtrVector() {}
+ TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
+ if (VecTy *V = Val.template dyn_cast<VecTy*>())
+ Val = new VecTy(*V);
+ }
+ ~TinyPtrVector() {
+ if (VecTy *V = Val.template dyn_cast<VecTy*>())
+ delete V;
+ }
+
+ // implicit conversion operator to ArrayRef.
+ operator ArrayRef<EltTy>() const {
+ if (Val.isNull())
+ return ArrayRef<EltTy>();
+ if (Val.template is<EltTy>())
+ return *Val.getAddrOfPtr1();
+ return *Val.template get<VecTy*>();
+ }
+
+ bool empty() const {
+ // This vector can be empty if it contains no element, or if it
+ // contains a pointer to an empty vector.
+ if (Val.isNull()) return true;
+ if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
+ return Vec->empty();
+ return false;
+ }
+
+ unsigned size() const {
+ if (empty())
+ return 0;
+ if (Val.template is<EltTy>())
+ return 1;
+ return Val.template get<VecTy*>()->size();
+ }
+
+ typedef const EltTy *const_iterator;
+ typedef EltTy *iterator;
+
+ iterator begin() {
+ if (empty())
+ return 0;
+
+ if (Val.template is<EltTy>())
+ return Val.getAddrOfPtr1();
+
+ return Val.template get<VecTy *>()->begin();
+
+ }
+ iterator end() {
+ if (empty())
+ return 0;
+
+ if (Val.template is<EltTy>())
+ return begin() + 1;
+
+ return Val.template get<VecTy *>()->end();
+ }
+
+ const_iterator begin() const {
+ return (const_iterator)const_cast<TinyPtrVector*>(this)->begin();
+ }
+
+ const_iterator end() const {
+ return (const_iterator)const_cast<TinyPtrVector*>(this)->end();
+ }
+
+ EltTy operator[](unsigned i) const {
+ assert(!Val.isNull() && "can't index into an empty vector");
+ if (EltTy V = Val.template dyn_cast<EltTy>()) {
+ assert(i == 0 && "tinyvector index out of range");
+ return V;
+ }
+
+ assert(i < Val.template get<VecTy*>()->size() &&
+ "tinyvector index out of range");
+ return (*Val.template get<VecTy*>())[i];
+ }
+
+ EltTy front() const {
+ assert(!empty() && "vector empty");
+ if (EltTy V = Val.template dyn_cast<EltTy>())
+ return V;
+ return Val.template get<VecTy*>()->front();
+ }
+
+ void push_back(EltTy NewVal) {
+ assert(NewVal != 0 && "Can't add a null value");
+
+ // If we have nothing, add something.
+ if (Val.isNull()) {
+ Val = NewVal;
+ return;
+ }
+
+ // If we have a single value, convert to a vector.
+ if (EltTy V = Val.template dyn_cast<EltTy>()) {
+ Val = new VecTy();
+ Val.template get<VecTy*>()->push_back(V);
+ }
+
+ // Add the new value, we know we have a vector.
+ Val.template get<VecTy*>()->push_back(NewVal);
+ }
+
+ void clear() {
+ // If we have a single value, convert to empty.
+ if (Val.template is<EltTy>()) {
+ Val = (EltTy)0;
+ } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+ // If we have a vector form, just clear it.
+ Vec->clear();
+ }
+ // Otherwise, we're already empty.
+ }
+
+ iterator erase(iterator I) {
+ // If we have a single value, convert to empty.
+ if (Val.template is<EltTy>()) {
+ if (I == begin())
+ Val = (EltTy)0;
+ } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
+ // multiple items in a vector; just do the erase, there is no
+ // benefit to collapsing back to a pointer
+ return Vec->erase(I);
+ }
+
+ return 0;
+ }
+
+private:
+ void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
+};
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/Trie.h b/contrib/llvm/include/llvm/ADT/Trie.h
new file mode 100644
index 000000000000..845af015b052
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/Trie.h
@@ -0,0 +1,334 @@
+//===- llvm/ADT/Trie.h ---- Generic trie structure --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines a generic trie structure. The trie structure
+// is immutable after creation, but the payload contained within it is not.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TRIE_H
+#define LLVM_ADT_TRIE_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/DOTGraphTraits.h"
+
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+
+// FIXME:
+// - Labels are usually small, maybe it's better to use SmallString
+// - Should we use char* during construction?
+// - Should we templatize Empty with traits-like interface?
+
+template<class Payload>
+class Trie {
+ friend class GraphTraits<Trie<Payload> >;
+ friend class DOTGraphTraits<Trie<Payload> >;
+public:
+ class Node {
+ friend class Trie;
+
+ public:
+ typedef std::vector<Node*> NodeVectorType;
+ typedef typename NodeVectorType::iterator iterator;
+ typedef typename NodeVectorType::const_iterator const_iterator;
+
+ private:
+ enum QueryResult {
+ Same = -3,
+ StringIsPrefix = -2,
+ LabelIsPrefix = -1,
+ DontMatch = 0,
+ HaveCommonPart
+ };
+
+ struct NodeCmp {
+ bool operator() (Node* N1, Node* N2) {
+ return (N1->Label[0] < N2->Label[0]);
+ }
+ bool operator() (Node* N, char Id) {
+ return (N->Label[0] < Id);
+ }
+ };
+
+ std::string Label;
+ Payload Data;
+ NodeVectorType Children;
+
+ // Do not implement
+ Node(const Node&);
+ Node& operator=(const Node&);
+
+ inline void addEdge(Node* N) {
+ if (Children.empty())
+ Children.push_back(N);
+ else {
+ iterator I = std::lower_bound(Children.begin(), Children.end(),
+ N, NodeCmp());
+ // FIXME: no dups are allowed
+ Children.insert(I, N);
+ }
+ }
+
+ inline void setEdge(Node* N) {
+ char Id = N->Label[0];
+ iterator I = std::lower_bound(Children.begin(), Children.end(),
+ Id, NodeCmp());
+ assert(I != Children.end() && "Node does not exists!");
+ *I = N;
+ }
+
+ QueryResult query(const std::string& s) const {
+ unsigned i, l;
+ unsigned l1 = s.length();
+ unsigned l2 = Label.length();
+
+ // Find the length of common part
+ l = std::min(l1, l2);
+ i = 0;
+ while ((i < l) && (s[i] == Label[i]))
+ ++i;
+
+ if (i == l) { // One is prefix of another, find who is who
+ if (l1 == l2)
+ return Same;
+ else if (i == l1)
+ return StringIsPrefix;
+ else
+ return LabelIsPrefix;
+ } else // s and Label have common (possible empty) part, return its length
+ return (QueryResult)i;
+ }
+
+ public:
+ inline explicit Node(const Payload& data, const std::string& label = ""):
+ Label(label), Data(data) { }
+
+ inline const Payload& data() const { return Data; }
+ inline void setData(const Payload& data) { Data = data; }
+
+ inline const std::string& label() const { return Label; }
+
+#if 0
+ inline void dump() {
+ llvm::cerr << "Node: " << this << "\n"
+ << "Label: " << Label << "\n"
+ << "Children:\n";
+
+ for (iterator I = Children.begin(), E = Children.end(); I != E; ++I)
+ llvm::cerr << (*I)->Label << "\n";
+ }
+#endif
+
+ inline Node* getEdge(char Id) {
+ Node* fNode = NULL;
+ iterator I = std::lower_bound(Children.begin(), Children.end(),
+ Id, NodeCmp());
+ if (I != Children.end() && (*I)->Label[0] == Id)
+ fNode = *I;
+
+ return fNode;
+ }
+
+ inline iterator begin() { return Children.begin(); }
+ inline const_iterator begin() const { return Children.begin(); }
+ inline iterator end () { return Children.end(); }
+ inline const_iterator end () const { return Children.end(); }
+
+ inline size_t size () const { return Children.size(); }
+ inline bool empty() const { return Children.empty(); }
+ inline const Node* &front() const { return Children.front(); }
+ inline Node* &front() { return Children.front(); }
+ inline const Node* &back() const { return Children.back(); }
+ inline Node* &back() { return Children.back(); }
+
+ };
+
+private:
+ std::vector<Node*> Nodes;
+ Payload Empty;
+
+ inline Node* addNode(const Payload& data, const std::string label = "") {
+ Node* N = new Node(data, label);
+ Nodes.push_back(N);
+ return N;
+ }
+
+ inline Node* splitEdge(Node* N, char Id, size_t index) {
+ Node* eNode = N->getEdge(Id);
+ assert(eNode && "Node doesn't exist");
+
+ const std::string &l = eNode->Label;
+ assert(index > 0 && index < l.length() && "Trying to split too far!");
+ std::string l1 = l.substr(0, index);
+ std::string l2 = l.substr(index);
+
+ Node* nNode = addNode(Empty, l1);
+ N->setEdge(nNode);
+
+ eNode->Label = l2;
+ nNode->addEdge(eNode);
+
+ return nNode;
+ }
+
+ // Do not implement
+ Trie(const Trie&);
+ Trie& operator=(const Trie&);
+
+public:
+ inline explicit Trie(const Payload& empty):Empty(empty) {
+ addNode(Empty);
+ }
+ inline ~Trie() {
+ for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
+ delete Nodes[i];
+ }
+
+ inline Node* getRoot() const { return Nodes[0]; }
+
+ bool addString(const std::string& s, const Payload& data);
+ const Payload& lookup(const std::string& s) const;
+
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template<class Payload>
+bool Trie<Payload>::addString(const std::string& s, const Payload& data) {
+ Node* cNode = getRoot();
+ Node* tNode = NULL;
+ std::string s1(s);
+
+ while (tNode == NULL) {
+ char Id = s1[0];
+ if (Node* nNode = cNode->getEdge(Id)) {
+ typename Node::QueryResult r = nNode->query(s1);
+
+ switch (r) {
+ case Node::Same:
+ case Node::StringIsPrefix:
+ // Currently we don't allow to have two strings in the trie one
+ // being a prefix of another. This should be fixed.
+ assert(0 && "FIXME!");
+ return false;
+ case Node::DontMatch:
+ llvm_unreachable("Impossible!");
+ case Node::LabelIsPrefix:
+ s1 = s1.substr(nNode->label().length());
+ cNode = nNode;
+ break;
+ default:
+ nNode = splitEdge(cNode, Id, r);
+ tNode = addNode(data, s1.substr(r));
+ nNode->addEdge(tNode);
+ }
+ } else {
+ tNode = addNode(data, s1);
+ cNode->addEdge(tNode);
+ }
+ }
+
+ return true;
+}
+
+template<class Payload>
+const Payload& Trie<Payload>::lookup(const std::string& s) const {
+ Node* cNode = getRoot();
+ Node* tNode = NULL;
+ std::string s1(s);
+
+ while (tNode == NULL) {
+ char Id = s1[0];
+ if (Node* nNode = cNode->getEdge(Id)) {
+ typename Node::QueryResult r = nNode->query(s1);
+
+ switch (r) {
+ case Node::Same:
+ tNode = nNode;
+ break;
+ case Node::StringIsPrefix:
+ return Empty;
+ case Node::DontMatch:
+ llvm_unreachable("Impossible!");
+ case Node::LabelIsPrefix:
+ s1 = s1.substr(nNode->label().length());
+ cNode = nNode;
+ break;
+ default:
+ return Empty;
+ }
+ } else
+ return Empty;
+ }
+
+ return tNode->data();
+}
+
+template<class Payload>
+struct GraphTraits<Trie<Payload> > {
+ typedef Trie<Payload> TrieType;
+ typedef typename TrieType::Node NodeType;
+ typedef typename NodeType::iterator ChildIteratorType;
+
+ static inline NodeType *getEntryNode(const TrieType& T) {
+ return T.getRoot();
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) { return N->end(); }
+
+ typedef typename std::vector<NodeType*>::const_iterator nodes_iterator;
+
+ static inline nodes_iterator nodes_begin(const TrieType& G) {
+ return G.Nodes.begin();
+ }
+ static inline nodes_iterator nodes_end(const TrieType& G) {
+ return G.Nodes.end();
+ }
+
+};
+
+template<class Payload>
+struct DOTGraphTraits<Trie<Payload> > : public DefaultDOTGraphTraits {
+ typedef typename Trie<Payload>::Node NodeType;
+ typedef typename GraphTraits<Trie<Payload> >::ChildIteratorType EdgeIter;
+
+ static std::string getGraphName(const Trie<Payload>& T) {
+ return "Trie";
+ }
+
+ static std::string getNodeLabel(NodeType* Node, const Trie<Payload>& T) {
+ if (T.getRoot() == Node)
+ return "<Root>";
+ else
+ return Node->label();
+ }
+
+ static std::string getEdgeSourceLabel(NodeType* Node, EdgeIter I) {
+ NodeType* N = *I;
+ return N->label().substr(0, 1);
+ }
+
+ static std::string getNodeAttributes(const NodeType* Node,
+ const Trie<Payload>& T) {
+ if (Node->data() != T.Empty)
+ return "color=blue";
+
+ return "";
+ }
+
+};
+
+} // end of llvm namespace
+
+#endif // LLVM_ADT_TRIE_H
diff --git a/contrib/llvm/include/llvm/ADT/Triple.h b/contrib/llvm/include/llvm/ADT/Triple.h
new file mode 100644
index 000000000000..f5f99d0f1b82
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/Triple.h
@@ -0,0 +1,432 @@
+//===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TRIPLE_H
+#define LLVM_ADT_TRIPLE_H
+
+#include "llvm/ADT/Twine.h"
+
+// Some system headers or GCC predefined macros conflict with identifiers in
+// this file. Undefine them here.
+#undef mips
+#undef sparc
+
+namespace llvm {
+
+/// Triple - Helper class for working with target triples.
+///
+/// Target triples are strings in the canonical form:
+/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM
+/// or
+/// ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT
+///
+/// This class is used for clients which want to support arbitrary
+/// target triples, but also want to implement certain special
+/// behavior for particular targets. This class isolates the mapping
+/// from the components of the target triple to well known IDs.
+///
+/// At its core the Triple class is designed to be a wrapper for a triple
+/// string; the constructor does not change or normalize the triple string.
+/// Clients that need to handle the non-canonical triples that users often
+/// specify should use the normalize method.
+///
+/// See autoconf/config.guess for a glimpse into what triples look like in
+/// practice.
+class Triple {
+public:
+ enum ArchType {
+ UnknownArch,
+
+ arm, // ARM; arm, armv.*, xscale
+ cellspu, // CellSPU: spu, cellspu
+ hexagon, // Hexagon: hexagon
+ mips, // MIPS: mips, mipsallegrex
+ mipsel, // MIPSEL: mipsel, mipsallegrexel
+ mips64, // MIPS64: mips64
+ mips64el,// MIPS64EL: mips64el
+ msp430, // MSP430: msp430
+ ppc, // PPC: powerpc
+ ppc64, // PPC64: powerpc64, ppu
+ r600, // R600: AMD GPUs HD2XXX - HD6XXX
+ sparc, // Sparc: sparc
+ sparcv9, // Sparcv9: Sparcv9
+ tce, // TCE (http://tce.cs.tut.fi/): tce
+ thumb, // Thumb: thumb, thumbv.*
+ x86, // X86: i[3-9]86
+ x86_64, // X86-64: amd64, x86_64
+ xcore, // XCore: xcore
+ mblaze, // MBlaze: mblaze
+ ptx32, // PTX: ptx (32-bit)
+ ptx64, // PTX: ptx (64-bit)
+ le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
+ amdil // amdil: amd IL
+ };
+ enum VendorType {
+ UnknownVendor,
+
+ Apple,
+ PC,
+ SCEI,
+ BGP,
+ BGQ
+ };
+ enum OSType {
+ UnknownOS,
+
+ AuroraUX,
+ Cygwin,
+ Darwin,
+ DragonFly,
+ FreeBSD,
+ IOS,
+ KFreeBSD,
+ Linux,
+ Lv2, // PS3
+ MacOSX,
+ MinGW32, // i*86-pc-mingw32, *-w64-mingw32
+ NetBSD,
+ OpenBSD,
+ Solaris,
+ Win32,
+ Haiku,
+ Minix,
+ RTEMS,
+ NativeClient,
+ CNK // BG/P Compute-Node Kernel
+ };
+ enum EnvironmentType {
+ UnknownEnvironment,
+
+ GNU,
+ GNUEABI,
+ GNUEABIHF,
+ EABI,
+ MachO,
+ ANDROIDEABI
+ };
+
+private:
+ std::string Data;
+
+ /// The parsed arch type.
+ ArchType Arch;
+
+ /// The parsed vendor type.
+ VendorType Vendor;
+
+ /// The parsed OS type.
+ OSType OS;
+
+ /// The parsed Environment type.
+ EnvironmentType Environment;
+
+public:
+ /// @name Constructors
+ /// @{
+
+ /// \brief Default constructor is the same as an empty string and leaves all
+ /// triple fields unknown.
+ Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
+
+ explicit Triple(const Twine &Str);
+ Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
+ Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
+ const Twine &EnvironmentStr);
+
+ /// @}
+ /// @name Normalization
+ /// @{
+
+ /// normalize - Turn an arbitrary machine specification into the canonical
+ /// triple form (or something sensible that the Triple class understands if
+ /// nothing better can reasonably be done). In particular, it handles the
+ /// common case in which otherwise valid components are in the wrong order.
+ static std::string normalize(StringRef Str);
+
+ /// @}
+ /// @name Typed Component Access
+ /// @{
+
+ /// getArch - Get the parsed architecture type of this triple.
+ ArchType getArch() const { return Arch; }
+
+ /// getVendor - Get the parsed vendor type of this triple.
+ VendorType getVendor() const { return Vendor; }
+
+ /// getOS - Get the parsed operating system type of this triple.
+ OSType getOS() const { return OS; }
+
+ /// hasEnvironment - Does this triple have the optional environment
+ /// (fourth) component?
+ bool hasEnvironment() const {
+ return getEnvironmentName() != "";
+ }
+
+ /// getEnvironment - Get the parsed environment type of this triple.
+ EnvironmentType getEnvironment() const { return Environment; }
+
+ /// getOSVersion - Parse the version number from the OS name component of the
+ /// triple, if present.
+ ///
+ /// For example, "fooos1.2.3" would return (1, 2, 3).
+ ///
+ /// If an entry is not defined, it will be returned as 0.
+ void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const;
+
+ /// getOSMajorVersion - Return just the major version number, this is
+ /// specialized because it is a common query.
+ unsigned getOSMajorVersion() const {
+ unsigned Maj, Min, Micro;
+ getOSVersion(Maj, Min, Micro);
+ return Maj;
+ }
+
+ /// getMacOSXVersion - Parse the version number as with getOSVersion and then
+ /// translate generic "darwin" versions to the corresponding OS X versions.
+ /// This may also be called with IOS triples but the OS X version number is
+ /// just set to a constant 10.4.0 in that case. Returns true if successful.
+ bool getMacOSXVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const;
+
+ /// @}
+ /// @name Direct Component Access
+ /// @{
+
+ const std::string &str() const { return Data; }
+
+ const std::string &getTriple() const { return Data; }
+
+ /// getArchName - Get the architecture (first) component of the
+ /// triple.
+ StringRef getArchName() const;
+
+ /// getVendorName - Get the vendor (second) component of the triple.
+ StringRef getVendorName() const;
+
+ /// getOSName - Get the operating system (third) component of the
+ /// triple.
+ StringRef getOSName() const;
+
+ /// getEnvironmentName - Get the optional environment (fourth)
+ /// component of the triple, or "" if empty.
+ StringRef getEnvironmentName() const;
+
+ /// getOSAndEnvironmentName - Get the operating system and optional
+ /// environment components as a single string (separated by a '-'
+ /// if the environment component is present).
+ StringRef getOSAndEnvironmentName() const;
+
+ /// @}
+ /// @name Convenience Predicates
+ /// @{
+
+ /// \brief Test whether the architecture is 64-bit
+ ///
+ /// Note that this tests for 64-bit pointer width, and nothing else. Note
+ /// that we intentionally expose only three predicates, 64-bit, 32-bit, and
+ /// 16-bit. The inner details of pointer width for particular architectures
+ /// is not summed up in the triple, and so only a coarse grained predicate
+ /// system is provided.
+ bool isArch64Bit() const;
+
+ /// \brief Test whether the architecture is 32-bit
+ ///
+ /// Note that this tests for 32-bit pointer width, and nothing else.
+ bool isArch32Bit() const;
+
+ /// \brief Test whether the architecture is 16-bit
+ ///
+ /// Note that this tests for 16-bit pointer width, and nothing else.
+ bool isArch16Bit() const;
+
+ /// isOSVersionLT - Helper function for doing comparisons against version
+ /// numbers included in the target triple.
+ bool isOSVersionLT(unsigned Major, unsigned Minor = 0,
+ unsigned Micro = 0) const {
+ unsigned LHS[3];
+ getOSVersion(LHS[0], LHS[1], LHS[2]);
+
+ if (LHS[0] != Major)
+ return LHS[0] < Major;
+ if (LHS[1] != Minor)
+ return LHS[1] < Minor;
+ if (LHS[2] != Micro)
+ return LHS[1] < Micro;
+
+ return false;
+ }
+
+ /// isMacOSXVersionLT - Comparison function for checking OS X version
+ /// compatibility, which handles supporting skewed version numbering schemes
+ /// used by the "darwin" triples.
+ unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
+ unsigned Micro = 0) const {
+ assert(isMacOSX() && "Not an OS X triple!");
+
+ // If this is OS X, expect a sane version number.
+ if (getOS() == Triple::MacOSX)
+ return isOSVersionLT(Major, Minor, Micro);
+
+ // Otherwise, compare to the "Darwin" number.
+ assert(Major == 10 && "Unexpected major version");
+ return isOSVersionLT(Minor + 4, Micro, 0);
+ }
+
+ /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
+ /// "darwin" and "osx" as OS X triples.
+ bool isMacOSX() const {
+ return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
+ }
+
+ /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
+ bool isOSDarwin() const {
+ return isMacOSX() || getOS() == Triple::IOS;
+ }
+
+ /// \brief Tests for either Cygwin or MinGW OS
+ bool isOSCygMing() const {
+ return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32;
+ }
+
+ /// isOSWindows - Is this a "Windows" OS.
+ bool isOSWindows() const {
+ return getOS() == Triple::Win32 || isOSCygMing();
+ }
+
+ /// \brief Tests whether the OS uses the ELF binary format.
+ bool isOSBinFormatELF() const {
+ return !isOSDarwin() && !isOSWindows();
+ }
+
+ /// \brief Tests whether the OS uses the COFF binary format.
+ bool isOSBinFormatCOFF() const {
+ return isOSWindows();
+ }
+
+ /// \brief Tests whether the environment is MachO.
+ // FIXME: Should this be an OSBinFormat predicate?
+ bool isEnvironmentMachO() const {
+ return getEnvironment() == Triple::MachO || isOSDarwin();
+ }
+
+ /// @}
+ /// @name Mutators
+ /// @{
+
+ /// setArch - Set the architecture (first) component of the triple
+ /// to a known type.
+ void setArch(ArchType Kind);
+
+ /// setVendor - Set the vendor (second) component of the triple to a
+ /// known type.
+ void setVendor(VendorType Kind);
+
+ /// setOS - Set the operating system (third) component of the triple
+ /// to a known type.
+ void setOS(OSType Kind);
+
+ /// setEnvironment - Set the environment (fourth) component of the triple
+ /// to a known type.
+ void setEnvironment(EnvironmentType Kind);
+
+ /// setTriple - Set all components to the new triple \arg Str.
+ void setTriple(const Twine &Str);
+
+ /// setArchName - Set the architecture (first) component of the
+ /// triple by name.
+ void setArchName(StringRef Str);
+
+ /// setVendorName - Set the vendor (second) component of the triple
+ /// by name.
+ void setVendorName(StringRef Str);
+
+ /// setOSName - Set the operating system (third) component of the
+ /// triple by name.
+ void setOSName(StringRef Str);
+
+ /// setEnvironmentName - Set the optional environment (fourth)
+ /// component of the triple by name.
+ void setEnvironmentName(StringRef Str);
+
+ /// setOSAndEnvironmentName - Set the operating system and optional
+ /// environment components with a single string.
+ void setOSAndEnvironmentName(StringRef Str);
+
+ /// getArchNameForAssembler - Get an architecture name that is understood by
+ /// the target assembler.
+ const char *getArchNameForAssembler();
+
+ /// @}
+ /// @name Helpers to build variants of a particular triple.
+ /// @{
+
+ /// \brief Form a triple with a 32-bit variant of the current architecture.
+ ///
+ /// This can be used to move across "families" of architectures where useful.
+ ///
+ /// \returns A new triple with a 32-bit architecture or an unknown
+ /// architecture if no such variant can be found.
+ llvm::Triple get32BitArchVariant() const;
+
+ /// \brief Form a triple with a 64-bit variant of the current architecture.
+ ///
+ /// This can be used to move across "families" of architectures where useful.
+ ///
+ /// \returns A new triple with a 64-bit architecture or an unknown
+ /// architecture if no such variant can be found.
+ llvm::Triple get64BitArchVariant() const;
+
+ /// @}
+ /// @name Static helpers for IDs.
+ /// @{
+
+ /// getArchTypeName - Get the canonical name for the \arg Kind
+ /// architecture.
+ static const char *getArchTypeName(ArchType Kind);
+
+ /// getArchTypePrefix - Get the "prefix" canonical name for the \arg Kind
+ /// architecture. This is the prefix used by the architecture specific
+ /// builtins, and is suitable for passing to \see
+ /// Intrinsic::getIntrinsicForGCCBuiltin().
+ ///
+ /// \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.
+ static const char *getVendorTypeName(VendorType Kind);
+
+ /// getOSTypeName - Get the canonical name for the \arg Kind operating
+ /// system.
+ static const char *getOSTypeName(OSType Kind);
+
+ /// getEnvironmentTypeName - Get the canonical name for the \arg Kind
+ /// environment.
+ static const char *getEnvironmentTypeName(EnvironmentType Kind);
+
+ /// @}
+ /// @name Static helpers for converting alternate architecture names.
+ /// @{
+
+ /// getArchTypeForLLVMName - The canonical type for the given LLVM
+ /// 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);
+
+ /// @}
+};
+
+} // End llvm namespace
+
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/Twine.h b/contrib/llvm/include/llvm/ADT/Twine.h
new file mode 100644
index 000000000000..9101df8cee37
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/Twine.h
@@ -0,0 +1,524 @@
+//===-- Twine.h - Fast Temporary String Concatenation -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TWINE_H
+#define LLVM_ADT_TWINE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+ template <typename T>
+ class SmallVectorImpl;
+ class StringRef;
+ class raw_ostream;
+
+ /// Twine - A lightweight data structure for efficiently representing the
+ /// concatenation of temporary values as strings.
+ ///
+ /// A Twine is a kind of rope, it represents a concatenated string using a
+ /// binary-tree, where the string is the preorder of the nodes. Since the
+ /// Twine can be efficiently rendered into a buffer when its result is used,
+ /// it avoids the cost of generating temporary values for intermediate string
+ /// results -- particularly in cases when the Twine result is never
+ /// required. By explicitly tracking the type of leaf nodes, we can also avoid
+ /// the creation of temporary strings for conversions operations (such as
+ /// appending an integer to a string).
+ ///
+ /// A Twine is not intended for use directly and should not be stored, its
+ /// implementation relies on the ability to store pointers to temporary stack
+ /// objects which may be deallocated at the end of a statement. Twines should
+ /// only be used accepted as const references in arguments, when an API wishes
+ /// to accept possibly-concatenated strings.
+ ///
+ /// Twines support a special 'null' value, which always concatenates to form
+ /// 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
+ ///
+ /// Given the nature of a Twine, it is not possible for the Twine's
+ /// concatenation method to construct interior nodes; the result must be
+ /// represented inside the returned value. For this reason a Twine object
+ /// actually holds two values, the left- and right-hand sides of a
+ /// concatenation. We also have nullary Twine objects, which are effectively
+ /// sentinel values that represent empty strings.
+ ///
+ /// Thus, a Twine can effectively have zero, one, or two children. The \see
+ /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
+ /// testing the number of children.
+ ///
+ /// We maintain a number of invariants on Twine objects (FIXME: Why):
+ /// - Nullary twines are always represented with their Kind on the left-hand
+ /// side, and the Empty kind on the right-hand side.
+ /// - Unary twines are always represented with the value on the left-hand
+ /// side, and the Empty kind on the right-hand side.
+ /// - If a Twine has another Twine as a child, that child should always be
+ /// binary (otherwise it could have been folded into the parent).
+ ///
+ /// These invariants are check by \see isValid().
+ ///
+ /// \b Efficiency Considerations \n
+ ///
+ /// The Twine is designed to yield efficient and small code for common
+ /// situations. For this reason, the concat() method is inlined so that
+ /// concatenations of leaf nodes can be optimized into stores directly into a
+ /// single stack allocated object.
+ ///
+ /// In practice, not all compilers can be trusted to optimize concat() fully,
+ /// so we provide two additional methods (and accompanying operator+
+ /// overloads) to guarantee that particularly important cases (cstring plus
+ /// StringRef) codegen as desired.
+ class Twine {
+ /// NodeKind - Represent the type of an argument.
+ enum NodeKind {
+ /// An empty string; the result of concatenating anything with it is also
+ /// empty.
+ NullKind,
+
+ /// The empty string.
+ EmptyKind,
+
+ /// A pointer to a Twine instance.
+ TwineKind,
+
+ /// A pointer to a C string instance.
+ CStringKind,
+
+ /// A pointer to an std::string instance.
+ StdStringKind,
+
+ /// A pointer to a StringRef instance.
+ StringRefKind,
+
+ /// A char value reinterpreted as a pointer, to render as a character.
+ CharKind,
+
+ /// An unsigned int value reinterpreted as a pointer, to render as an
+ /// unsigned decimal integer.
+ DecUIKind,
+
+ /// An int value reinterpreted as a pointer, to render as a signed
+ /// decimal integer.
+ DecIKind,
+
+ /// A pointer to an unsigned long value, to render as an unsigned decimal
+ /// integer.
+ DecULKind,
+
+ /// A pointer to a long value, to render as a signed decimal integer.
+ DecLKind,
+
+ /// A pointer to an unsigned long long value, to render as an unsigned
+ /// decimal integer.
+ DecULLKind,
+
+ /// A pointer to a long long value, to render as a signed decimal integer.
+ DecLLKind,
+
+ /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
+ /// integer.
+ UHexKind
+ };
+
+ union Child
+ {
+ const Twine *twine;
+ const char *cString;
+ const std::string *stdString;
+ const StringRef *stringRef;
+ char character;
+ unsigned int decUI;
+ int decI;
+ const unsigned long *decUL;
+ const long *decL;
+ const unsigned long long *decULL;
+ const long long *decLL;
+ const uint64_t *uHex;
+ };
+
+ private:
+ /// LHS - The prefix in the concatenation, which may be uninitialized for
+ /// Null or Empty kinds.
+ Child LHS;
+ /// RHS - The suffix in the concatenation, which may be uninitialized for
+ /// Null or Empty kinds.
+ Child RHS;
+ // enums stored as unsigned chars to save on space while some compilers
+ // don't support specifying the backing type for an enum
+ /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
+ unsigned char LHSKind;
+ /// RHSKind - The NodeKind of the left hand side, \see getLHSKind().
+ unsigned char RHSKind;
+
+ private:
+ /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
+ explicit Twine(NodeKind Kind)
+ : LHSKind(Kind), RHSKind(EmptyKind) {
+ assert(isNullary() && "Invalid kind!");
+ }
+
+ /// Construct a binary twine.
+ explicit Twine(const Twine &_LHS, const Twine &_RHS)
+ : LHSKind(TwineKind), RHSKind(TwineKind) {
+ LHS.twine = &_LHS;
+ RHS.twine = &_RHS;
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Construct a twine from explicit values.
+ explicit Twine(Child _LHS, NodeKind _LHSKind,
+ Child _RHS, NodeKind _RHSKind)
+ : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// isNull - Check for the null twine.
+ bool isNull() const {
+ return getLHSKind() == NullKind;
+ }
+
+ /// isEmpty - Check for the empty twine.
+ bool isEmpty() const {
+ return getLHSKind() == EmptyKind;
+ }
+
+ /// isNullary - Check if this is a nullary twine (null or empty).
+ bool isNullary() const {
+ return isNull() || isEmpty();
+ }
+
+ /// isUnary - Check if this is a unary twine.
+ bool isUnary() const {
+ return getRHSKind() == EmptyKind && !isNullary();
+ }
+
+ /// isBinary - Check if this is a binary twine.
+ bool isBinary() const {
+ return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
+ }
+
+ /// isValid - Check if this is a valid twine (satisfying the invariants on
+ /// order and number of arguments).
+ bool isValid() const {
+ // Nullary twines always have Empty on the RHS.
+ if (isNullary() && getRHSKind() != EmptyKind)
+ return false;
+
+ // Null should never appear on the RHS.
+ if (getRHSKind() == NullKind)
+ return false;
+
+ // The RHS cannot be non-empty if the LHS is empty.
+ if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
+ return false;
+
+ // A twine child should always be binary.
+ if (getLHSKind() == TwineKind &&
+ !LHS.twine->isBinary())
+ return false;
+ if (getRHSKind() == TwineKind &&
+ !RHS.twine->isBinary())
+ return false;
+
+ return true;
+ }
+
+ /// getLHSKind - Get the NodeKind of the left-hand side.
+ NodeKind getLHSKind() const { return (NodeKind) LHSKind; }
+
+ /// getRHSKind - Get the NodeKind of the left-hand side.
+ NodeKind getRHSKind() const { return (NodeKind) RHSKind; }
+
+ /// printOneChild - Print one child from a twine.
+ void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
+
+ /// printOneChildRepr - Print the representation of one child from a twine.
+ void printOneChildRepr(raw_ostream &OS, Child Ptr,
+ NodeKind Kind) const;
+
+ public:
+ /// @name Constructors
+ /// @{
+
+ /// Construct from an empty string.
+ /*implicit*/ Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) {
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Construct from a C string.
+ ///
+ /// We take care here to optimize "" into the empty twine -- this will be
+ /// optimized out for string constants. This allows Twine arguments have
+ /// default "" values, without introducing unnecessary string constants.
+ /*implicit*/ Twine(const char *Str)
+ : RHSKind(EmptyKind) {
+ if (Str[0] != '\0') {
+ LHS.cString = Str;
+ LHSKind = CStringKind;
+ } else
+ LHSKind = EmptyKind;
+
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Construct from an std::string.
+ /*implicit*/ Twine(const std::string &Str)
+ : LHSKind(StdStringKind), RHSKind(EmptyKind) {
+ LHS.stdString = &Str;
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Construct from a StringRef.
+ /*implicit*/ Twine(const StringRef &Str)
+ : LHSKind(StringRefKind), RHSKind(EmptyKind) {
+ LHS.stringRef = &Str;
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Construct from a char.
+ explicit Twine(char Val)
+ : LHSKind(CharKind), RHSKind(EmptyKind) {
+ LHS.character = Val;
+ }
+
+ /// Construct from a signed char.
+ explicit Twine(signed char Val)
+ : LHSKind(CharKind), RHSKind(EmptyKind) {
+ LHS.character = static_cast<char>(Val);
+ }
+
+ /// Construct from an unsigned char.
+ explicit Twine(unsigned char Val)
+ : LHSKind(CharKind), RHSKind(EmptyKind) {
+ LHS.character = static_cast<char>(Val);
+ }
+
+ /// Construct a twine to print \arg 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.
+ explicit Twine(int Val)
+ : LHSKind(DecIKind), RHSKind(EmptyKind) {
+ LHS.decI = Val;
+ }
+
+ /// Construct a twine to print \arg 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.
+ explicit Twine(const long &Val)
+ : LHSKind(DecLKind), RHSKind(EmptyKind) {
+ LHS.decL = &Val;
+ }
+
+ /// Construct a twine to print \arg 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.
+ explicit Twine(const long long &Val)
+ : LHSKind(DecLLKind), RHSKind(EmptyKind) {
+ LHS.decLL = &Val;
+ }
+
+ // FIXME: Unfortunately, to make sure this is as efficient as possible we
+ // need extra binary constructors from particular types. We can't rely on
+ // the compiler to be smart enough to fold operator+()/concat() down to the
+ // right thing. Yet.
+
+ /// Construct as the concatenation of a C string and a StringRef.
+ /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
+ : LHSKind(CStringKind), RHSKind(StringRefKind) {
+ LHS.cString = _LHS;
+ RHS.stringRef = &_RHS;
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Construct as the concatenation of a StringRef and a C string.
+ /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
+ : LHSKind(StringRefKind), RHSKind(CStringKind) {
+ LHS.stringRef = &_LHS;
+ RHS.cString = _RHS;
+ assert(isValid() && "Invalid twine!");
+ }
+
+ /// Create a 'null' string, which is an empty string that always
+ /// concatenates to form another empty string.
+ static Twine createNull() {
+ return Twine(NullKind);
+ }
+
+ /// @}
+ /// @name Numeric Conversions
+ /// @{
+
+ // Construct a twine to print \arg Val as an unsigned hexadecimal integer.
+ static Twine utohexstr(const uint64_t &Val) {
+ Child LHS, RHS;
+ LHS.uHex = &Val;
+ RHS.twine = 0;
+ return Twine(LHS, UHexKind, RHS, EmptyKind);
+ }
+
+ /// @}
+ /// @name Predicate Operations
+ /// @{
+
+ /// isTriviallyEmpty - Check if this twine is trivially empty; a false
+ /// return value does not necessarily mean the twine is empty.
+ bool isTriviallyEmpty() const {
+ return isNullary();
+ }
+
+ /// isSingleStringRef - Return true if this twine can be dynamically
+ /// accessed as a single StringRef value with getSingleStringRef().
+ bool isSingleStringRef() const {
+ if (getRHSKind() != EmptyKind) return false;
+
+ switch (getLHSKind()) {
+ case EmptyKind:
+ case CStringKind:
+ case StdStringKind:
+ case StringRefKind:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// @}
+ /// @name String Operations
+ /// @{
+
+ Twine concat(const Twine &Suffix) const;
+
+ /// @}
+ /// @name Output & Conversion.
+ /// @{
+
+ /// str - Return the twine contents as a std::string.
+ std::string str() const;
+
+ /// toVector - Write the concatenated string into the given SmallString or
+ /// SmallVector.
+ void toVector(SmallVectorImpl<char> &Out) const;
+
+ /// getSingleStringRef - This returns the twine as a single StringRef. This
+ /// method is only valid if isSingleStringRef() is true.
+ StringRef getSingleStringRef() const {
+ assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
+ switch (getLHSKind()) {
+ default: llvm_unreachable("Out of sync with isSingleStringRef");
+ case EmptyKind: return StringRef();
+ case CStringKind: return StringRef(LHS.cString);
+ case StdStringKind: return StringRef(*LHS.stdString);
+ case StringRefKind: return *LHS.stringRef;
+ }
+ }
+
+ /// toStringRef - This returns the twine as a single StringRef if it can be
+ /// represented as such. Otherwise the twine is written into the given
+ /// SmallVector and a StringRef to the SmallVector's data is returned.
+ StringRef toStringRef(SmallVectorImpl<char> &Out) const;
+
+ /// toNullTerminatedStringRef - This returns the twine as a single null
+ /// terminated StringRef if it can be represented as such. Otherwise the
+ /// twine is written into the given SmallVector and a StringRef to the
+ /// SmallVector's data is returned.
+ ///
+ /// 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.
+ void print(raw_ostream &OS) const;
+
+ /// dump - 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.
+ void printRepr(raw_ostream &OS) const;
+
+ /// dumpRepr - Dump the representation of this twine to stderr.
+ void dumpRepr() const;
+
+ /// @}
+ };
+
+ /// @name Twine Inline Implementations
+ /// @{
+
+ inline Twine Twine::concat(const Twine &Suffix) const {
+ // Concatenation with null is null.
+ if (isNull() || Suffix.isNull())
+ return Twine(NullKind);
+
+ // Concatenation with empty yields the other side.
+ if (isEmpty())
+ return Suffix;
+ if (Suffix.isEmpty())
+ return *this;
+
+ // Otherwise we need to create a new node, taking care to fold in unary
+ // twines.
+ Child NewLHS, NewRHS;
+ NewLHS.twine = this;
+ NewRHS.twine = &Suffix;
+ NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
+ if (isUnary()) {
+ NewLHS = LHS;
+ NewLHSKind = getLHSKind();
+ }
+ if (Suffix.isUnary()) {
+ NewRHS = Suffix.LHS;
+ NewRHSKind = Suffix.getLHSKind();
+ }
+
+ return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
+ }
+
+ inline Twine operator+(const Twine &LHS, const Twine &RHS) {
+ return LHS.concat(RHS);
+ }
+
+ /// Additional overload to guarantee simplified codegen; this is equivalent to
+ /// concat().
+
+ inline Twine operator+(const char *LHS, const StringRef &RHS) {
+ return Twine(LHS, RHS);
+ }
+
+ /// Additional overload to guarantee simplified codegen; this is equivalent to
+ /// concat().
+
+ inline Twine operator+(const StringRef &LHS, const char *RHS) {
+ return Twine(LHS, RHS);
+ }
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
+ RHS.print(OS);
+ return OS;
+ }
+
+ /// @}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/UniqueVector.h b/contrib/llvm/include/llvm/ADT/UniqueVector.h
new file mode 100644
index 000000000000..2d02d1ce166f
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/UniqueVector.h
@@ -0,0 +1,89 @@
+//===-- llvm/ADT/UniqueVector.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_UNIQUEVECTOR_H
+#define LLVM_ADT_UNIQUEVECTOR_H
+
+#include <cassert>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// UniqueVector - This class produces a sequential ID number (base 1) for each
+/// unique entry that is added. T is the type of entries in the vector. This
+/// class should have an implementation of operator== and of operator<.
+/// Entries can be fetched using operator[] with the entry ID.
+template<class T> class UniqueVector {
+private:
+ // Map - Used to handle the correspondence of entry to ID.
+ std::map<T, unsigned> Map;
+
+ // Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
+ //
+ std::vector<T> Vector;
+
+public:
+ /// insert - Append entry to the vector if it doesn't already exist. Returns
+ /// the entry's index + 1 to be used as a unique ID.
+ unsigned insert(const T &Entry) {
+ // Check if the entry is already in the map.
+ unsigned &Val = Map[Entry];
+
+ // See if entry exists, if so return prior ID.
+ if (Val) return Val;
+
+ // Compute ID for entry.
+ Val = static_cast<unsigned>(Vector.size()) + 1;
+
+ // Insert in vector.
+ Vector.push_back(Entry);
+ return Val;
+ }
+
+ /// idFor - return the ID for an existing entry. Returns 0 if the entry is
+ /// not found.
+ unsigned idFor(const T &Entry) const {
+ // Search for entry in the map.
+ typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry);
+
+ // See if entry exists, if so return ID.
+ if (MI != Map.end()) return MI->second;
+
+ // No luck.
+ return 0;
+ }
+
+ /// operator[] - Returns a reference to the entry with the specified ID.
+ ///
+ const T &operator[](unsigned ID) const {
+ assert(ID-1 < size() && "ID is 0 or out of range!");
+ return Vector[ID - 1];
+ }
+
+ /// size - Returns the number of entries in the vector.
+ ///
+ size_t size() const { return Vector.size(); }
+
+ /// empty - Returns true if the vector is empty.
+ ///
+ bool empty() const { return Vector.empty(); }
+
+ /// reset - Clears all the entries.
+ ///
+ void reset() {
+ Map.clear();
+ Vector.resize(0, 0);
+ }
+};
+
+} // End of namespace llvm
+
+#endif // LLVM_ADT_UNIQUEVECTOR_H
diff --git a/contrib/llvm/include/llvm/ADT/ValueMap.h b/contrib/llvm/include/llvm/ADT/ValueMap.h
new file mode 100644
index 000000000000..707d07d32cbc
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ValueMap.h
@@ -0,0 +1,366 @@
+//===- llvm/ADT/ValueMap.h - Safe map from Values to data -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ValueMap class. ValueMap maps Value* or any subclass
+// to an arbitrary other type. It provides the DenseMap interface but updates
+// itself to remain safe when keys are RAUWed or deleted. By default, when a
+// key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new
+// mapping V2->target is added. If V2 already existed, its old target is
+// overwritten. When a key is deleted, its mapping is removed.
+//
+// You can override a ValueMap's Config parameter to control exactly what
+// happens on RAUW and destruction and to get called back on each event. It's
+// legal to call back into the ValueMap from a Config's callbacks. Config
+// parameters should inherit from ValueMapConfig<KeyT> to get default
+// implementations of all the methods ValueMap uses. See ValueMapConfig for
+// documentation of the functions you can override.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_VALUEMAP_H
+#define LLVM_ADT_VALUEMAP_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/ValueHandle.h"
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Mutex.h"
+
+#include <iterator>
+
+namespace llvm {
+
+template<typename KeyT, typename ValueT, typename Config>
+class ValueMapCallbackVH;
+
+template<typename DenseMapT, typename KeyT>
+class ValueMapIterator;
+template<typename DenseMapT, typename KeyT>
+class ValueMapConstIterator;
+
+/// This class defines the default behavior for configurable aspects of
+/// ValueMap<>. User Configs should inherit from this class to be as compatible
+/// as possible with future versions of ValueMap.
+template<typename KeyT>
+struct ValueMapConfig {
+ /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
+ /// false, the ValueMap will leave the original mapping in place.
+ enum { FollowRAUW = true };
+
+ // All methods will be called with a first argument of type ExtraData. The
+ // default implementations in this class take a templated first argument so
+ // that users' subclasses can use any type they want without having to
+ // override all the defaults.
+ struct ExtraData {};
+
+ template<typename ExtraDataT>
+ static void onRAUW(const ExtraDataT & /*Data*/, KeyT /*Old*/, KeyT /*New*/) {}
+ template<typename ExtraDataT>
+ static void onDelete(const ExtraDataT &/*Data*/, KeyT /*Old*/) {}
+
+ /// Returns a mutex that should be acquired around any changes to the map.
+ /// This is only acquired from the CallbackVH (and held around calls to onRAUW
+ /// and onDelete) and not inside other ValueMap methods. NULL means that no
+ /// mutex is necessary.
+ template<typename ExtraDataT>
+ static sys::Mutex *getMutex(const ExtraDataT &/*Data*/) { return NULL; }
+};
+
+/// See the file comment.
+template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> >
+class ValueMap {
+ friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
+ typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH;
+ typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT;
+ typedef typename Config::ExtraData ExtraData;
+ MapT Map;
+ ExtraData Data;
+ ValueMap(const ValueMap&); // DO NOT IMPLEMENT
+ ValueMap& operator=(const ValueMap&); // DO NOT IMPLEMENT
+public:
+ typedef KeyT key_type;
+ typedef ValueT mapped_type;
+ typedef std::pair<KeyT, ValueT> value_type;
+
+ explicit ValueMap(unsigned NumInitBuckets = 64)
+ : Map(NumInitBuckets), Data() {}
+ explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
+ : Map(NumInitBuckets), Data(Data) {}
+
+ ~ValueMap() {}
+
+ typedef ValueMapIterator<MapT, KeyT> iterator;
+ typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
+ inline iterator begin() { return iterator(Map.begin()); }
+ inline iterator end() { return iterator(Map.end()); }
+ inline const_iterator begin() const { return const_iterator(Map.begin()); }
+ inline const_iterator end() const { return const_iterator(Map.end()); }
+
+ bool empty() const { return Map.empty(); }
+ unsigned size() const { return Map.size(); }
+
+ /// Grow the map so that it has at least Size buckets. Does not shrink
+ void resize(size_t Size) { Map.resize(Size); }
+
+ void clear() { Map.clear(); }
+
+ /// count - Return true if the specified key is in the map.
+ bool count(const KeyT &Val) const {
+ return Map.count(Wrap(Val));
+ }
+
+ iterator find(const KeyT &Val) {
+ return iterator(Map.find(Wrap(Val)));
+ }
+ const_iterator find(const KeyT &Val) const {
+ return const_iterator(Map.find(Wrap(Val)));
+ }
+
+ /// lookup - Return the entry for the specified key, or a default
+ /// constructed value if no such entry exists.
+ ValueT lookup(const KeyT &Val) const {
+ return Map.lookup(Wrap(Val));
+ }
+
+ // Inserts key,value pair into the map if the key isn't already in the map.
+ // If the key is already in the map, it returns false and doesn't update the
+ // value.
+ std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+ std::pair<typename MapT::iterator, bool> map_result=
+ Map.insert(std::make_pair(Wrap(KV.first), KV.second));
+ return std::make_pair(iterator(map_result.first), map_result.second);
+ }
+
+ /// insert - Range insertion of pairs.
+ template<typename InputIt>
+ void insert(InputIt I, InputIt E) {
+ for (; I != E; ++I)
+ insert(*I);
+ }
+
+
+ bool erase(const KeyT &Val) {
+ return Map.erase(Wrap(Val));
+ }
+ void erase(iterator I) {
+ return Map.erase(I.base());
+ }
+
+ value_type& FindAndConstruct(const KeyT &Key) {
+ return Map.FindAndConstruct(Wrap(Key));
+ }
+
+ ValueT &operator[](const KeyT &Key) {
+ return Map[Wrap(Key)];
+ }
+
+ /// isPointerIntoBucketsArray - Return true if the specified pointer points
+ /// somewhere into the ValueMap's array of buckets (i.e. either to a key or
+ /// value in the ValueMap).
+ bool isPointerIntoBucketsArray(const void *Ptr) const {
+ return Map.isPointerIntoBucketsArray(Ptr);
+ }
+
+ /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
+ /// array. In conjunction with the previous method, this can be used to
+ /// determine whether an insertion caused the ValueMap to reallocate.
+ const void *getPointerIntoBucketsArray() const {
+ return Map.getPointerIntoBucketsArray();
+ }
+
+private:
+ // Takes a key being looked up in the map and wraps it into a
+ // ValueMapCallbackVH, the actual key type of the map. We use a helper
+ // function because ValueMapCVH is constructed with a second parameter.
+ ValueMapCVH Wrap(KeyT key) const {
+ // The only way the resulting CallbackVH could try to modify *this (making
+ // the const_cast incorrect) is if it gets inserted into the map. But then
+ // this function must have been called from a non-const method, making the
+ // const_cast ok.
+ return ValueMapCVH(key, const_cast<ValueMap*>(this));
+ }
+};
+
+// This CallbackVH updates its ValueMap when the contained Value changes,
+// according to the user's preferences expressed through the Config object.
+template<typename KeyT, typename ValueT, typename Config>
+class ValueMapCallbackVH : public CallbackVH {
+ friend class ValueMap<KeyT, ValueT, Config>;
+ friend struct DenseMapInfo<ValueMapCallbackVH>;
+ typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
+ typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT;
+
+ ValueMapT *Map;
+
+ ValueMapCallbackVH(KeyT Key, ValueMapT *Map)
+ : CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))),
+ Map(Map) {}
+
+public:
+ KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
+
+ virtual void deleted() {
+ // Make a copy that won't get changed even when *this is destroyed.
+ ValueMapCallbackVH Copy(*this);
+ sys::Mutex *M = Config::getMutex(Copy.Map->Data);
+ if (M)
+ M->acquire();
+ Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this.
+ Copy.Map->Map.erase(Copy); // Definitely destroys *this.
+ if (M)
+ M->release();
+ }
+ virtual void allUsesReplacedWith(Value *new_key) {
+ assert(isa<KeySansPointerT>(new_key) &&
+ "Invalid RAUW on key of ValueMap<>");
+ // Make a copy that won't get changed even when *this is destroyed.
+ ValueMapCallbackVH Copy(*this);
+ sys::Mutex *M = Config::getMutex(Copy.Map->Data);
+ if (M)
+ M->acquire();
+
+ KeyT typed_new_key = cast<KeySansPointerT>(new_key);
+ // Can destroy *this:
+ Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key);
+ if (Config::FollowRAUW) {
+ typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy);
+ // I could == Copy.Map->Map.end() if the onRAUW callback already
+ // removed the old mapping.
+ if (I != Copy.Map->Map.end()) {
+ ValueT Target(I->second);
+ Copy.Map->Map.erase(I); // Definitely destroys *this.
+ Copy.Map->insert(std::make_pair(typed_new_key, Target));
+ }
+ }
+ if (M)
+ M->release();
+ }
+};
+
+template<typename KeyT, typename ValueT, typename Config>
+struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > {
+ typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH;
+ typedef DenseMapInfo<KeyT> PointerInfo;
+
+ static inline VH getEmptyKey() {
+ return VH(PointerInfo::getEmptyKey(), NULL);
+ }
+ static inline VH getTombstoneKey() {
+ return VH(PointerInfo::getTombstoneKey(), NULL);
+ }
+ static unsigned getHashValue(const VH &Val) {
+ return PointerInfo::getHashValue(Val.Unwrap());
+ }
+ static bool isEqual(const VH &LHS, const VH &RHS) {
+ return LHS == RHS;
+ }
+};
+
+
+template<typename DenseMapT, typename KeyT>
+class ValueMapIterator :
+ public std::iterator<std::forward_iterator_tag,
+ std::pair<KeyT, typename DenseMapT::mapped_type>,
+ ptrdiff_t> {
+ typedef typename DenseMapT::iterator BaseT;
+ typedef typename DenseMapT::mapped_type ValueT;
+ BaseT I;
+public:
+ ValueMapIterator() : I() {}
+
+ ValueMapIterator(BaseT I) : I(I) {}
+
+ BaseT base() const { return I; }
+
+ struct ValueTypeProxy {
+ const KeyT first;
+ ValueT& second;
+ ValueTypeProxy *operator->() { return this; }
+ operator std::pair<KeyT, ValueT>() const {
+ return std::make_pair(first, second);
+ }
+ };
+
+ ValueTypeProxy operator*() const {
+ ValueTypeProxy Result = {I->first.Unwrap(), I->second};
+ return Result;
+ }
+
+ ValueTypeProxy operator->() const {
+ return operator*();
+ }
+
+ bool operator==(const ValueMapIterator &RHS) const {
+ return I == RHS.I;
+ }
+ bool operator!=(const ValueMapIterator &RHS) const {
+ return I != RHS.I;
+ }
+
+ inline ValueMapIterator& operator++() { // Preincrement
+ ++I;
+ return *this;
+ }
+ ValueMapIterator operator++(int) { // Postincrement
+ ValueMapIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+template<typename DenseMapT, typename KeyT>
+class ValueMapConstIterator :
+ public std::iterator<std::forward_iterator_tag,
+ std::pair<KeyT, typename DenseMapT::mapped_type>,
+ ptrdiff_t> {
+ typedef typename DenseMapT::const_iterator BaseT;
+ typedef typename DenseMapT::mapped_type ValueT;
+ BaseT I;
+public:
+ ValueMapConstIterator() : I() {}
+ ValueMapConstIterator(BaseT I) : I(I) {}
+ ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
+ : I(Other.base()) {}
+
+ BaseT base() const { return I; }
+
+ struct ValueTypeProxy {
+ const KeyT first;
+ const ValueT& second;
+ ValueTypeProxy *operator->() { return this; }
+ operator std::pair<KeyT, ValueT>() const {
+ return std::make_pair(first, second);
+ }
+ };
+
+ ValueTypeProxy operator*() const {
+ ValueTypeProxy Result = {I->first.Unwrap(), I->second};
+ return Result;
+ }
+
+ ValueTypeProxy operator->() const {
+ return operator*();
+ }
+
+ bool operator==(const ValueMapConstIterator &RHS) const {
+ return I == RHS.I;
+ }
+ bool operator!=(const ValueMapConstIterator &RHS) const {
+ return I != RHS.I;
+ }
+
+ inline ValueMapConstIterator& operator++() { // Preincrement
+ ++I;
+ return *this;
+ }
+ ValueMapConstIterator operator++(int) { // Postincrement
+ ValueMapConstIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/VariadicFunction.h b/contrib/llvm/include/llvm/ADT/VariadicFunction.h
new file mode 100644
index 000000000000..a9a0dc6b6e20
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/VariadicFunction.h
@@ -0,0 +1,331 @@
+//===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements compile-time type-safe variadic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_VARIADIC_FUNCTION_H
+#define LLVM_ADT_VARIADIC_FUNCTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+
+// Define macros to aid in expanding a comma separated series with the index of
+// the series pasted onto the last token.
+#define LLVM_COMMA_JOIN1(x) x ## 0
+#define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1
+#define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2
+#define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3
+#define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4
+#define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5
+#define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6
+#define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7
+#define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8
+#define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9
+#define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10
+#define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11
+#define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12
+#define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13
+#define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14
+#define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15
+#define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16
+#define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17
+#define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18
+#define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19
+#define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20
+#define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21
+#define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22
+#define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23
+#define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24
+#define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25
+#define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26
+#define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27
+#define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28
+#define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29
+#define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
+#define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
+
+/// \brief Class which can simulate a type-safe variadic function.
+///
+/// The VariadicFunction class template makes it easy to define
+/// type-safe variadic functions where all arguments have the same
+/// type.
+///
+/// Suppose we need a variadic function like this:
+///
+/// ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N);
+///
+/// Instead of many overloads of Foo(), we only need to define a helper
+/// function that takes an array of arguments:
+///
+/// ResultT FooImpl(ArrayRef<const ArgT *> Args) {
+/// // 'Args[i]' is a pointer to the i-th argument passed to Foo().
+/// ...
+/// }
+///
+/// and then define Foo() like this:
+///
+/// const VariadicFunction<ResultT, ArgT, FooImpl> Foo;
+///
+/// VariadicFunction takes care of defining the overloads of Foo().
+///
+/// Actually, Foo is a function object (i.e. functor) instead of a plain
+/// function. This object is stateless and its constructor/destructor
+/// does nothing, so it's safe to create global objects and call Foo(...) at
+/// any time.
+///
+/// Sometimes we need a variadic function to have some fixed leading
+/// arguments whose types may be different from that of the optional
+/// arguments. For example:
+///
+/// bool FullMatch(const StringRef &S, const RE &Regex,
+/// const ArgT &A_0, ..., const ArgT &A_N);
+///
+/// VariadicFunctionN is for such cases, where N is the number of fixed
+/// arguments. It is like VariadicFunction, except that it takes N more
+/// template arguments for the types of the fixed arguments:
+///
+/// bool FullMatchImpl(const StringRef &S, const RE &Regex,
+/// ArrayRef<const ArgT *> Args) { ... }
+/// const VariadicFunction2<bool, const StringRef&,
+/// const RE&, ArgT, FullMatchImpl>
+/// FullMatch;
+///
+/// Currently VariadicFunction and friends support up-to 3
+/// fixed leading arguments and up-to 32 optional arguments.
+template <typename ResultT, typename ArgT,
+ ResultT (*Func)(ArrayRef<const ArgT *>)>
+struct VariadicFunction {
+ ResultT operator()() const {
+ return Func(ArrayRef<const ArgT *>());
+ }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+ ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+ const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+ return Func(makeArrayRef(Args)); \
+ }
+ LLVM_DEFINE_OVERLOAD(1)
+ LLVM_DEFINE_OVERLOAD(2)
+ LLVM_DEFINE_OVERLOAD(3)
+ LLVM_DEFINE_OVERLOAD(4)
+ LLVM_DEFINE_OVERLOAD(5)
+ LLVM_DEFINE_OVERLOAD(6)
+ LLVM_DEFINE_OVERLOAD(7)
+ LLVM_DEFINE_OVERLOAD(8)
+ LLVM_DEFINE_OVERLOAD(9)
+ LLVM_DEFINE_OVERLOAD(10)
+ LLVM_DEFINE_OVERLOAD(11)
+ LLVM_DEFINE_OVERLOAD(12)
+ LLVM_DEFINE_OVERLOAD(13)
+ LLVM_DEFINE_OVERLOAD(14)
+ LLVM_DEFINE_OVERLOAD(15)
+ LLVM_DEFINE_OVERLOAD(16)
+ LLVM_DEFINE_OVERLOAD(17)
+ LLVM_DEFINE_OVERLOAD(18)
+ LLVM_DEFINE_OVERLOAD(19)
+ LLVM_DEFINE_OVERLOAD(20)
+ LLVM_DEFINE_OVERLOAD(21)
+ LLVM_DEFINE_OVERLOAD(22)
+ LLVM_DEFINE_OVERLOAD(23)
+ LLVM_DEFINE_OVERLOAD(24)
+ LLVM_DEFINE_OVERLOAD(25)
+ LLVM_DEFINE_OVERLOAD(26)
+ LLVM_DEFINE_OVERLOAD(27)
+ LLVM_DEFINE_OVERLOAD(28)
+ LLVM_DEFINE_OVERLOAD(29)
+ LLVM_DEFINE_OVERLOAD(30)
+ LLVM_DEFINE_OVERLOAD(31)
+ LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+template <typename ResultT, typename Param0T, typename ArgT,
+ ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)>
+struct VariadicFunction1 {
+ ResultT operator()(Param0T P0) const {
+ return Func(P0, ArrayRef<const ArgT *>());
+ }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+ ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+ const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+ return Func(P0, makeArrayRef(Args)); \
+ }
+ LLVM_DEFINE_OVERLOAD(1)
+ LLVM_DEFINE_OVERLOAD(2)
+ LLVM_DEFINE_OVERLOAD(3)
+ LLVM_DEFINE_OVERLOAD(4)
+ LLVM_DEFINE_OVERLOAD(5)
+ LLVM_DEFINE_OVERLOAD(6)
+ LLVM_DEFINE_OVERLOAD(7)
+ LLVM_DEFINE_OVERLOAD(8)
+ LLVM_DEFINE_OVERLOAD(9)
+ LLVM_DEFINE_OVERLOAD(10)
+ LLVM_DEFINE_OVERLOAD(11)
+ LLVM_DEFINE_OVERLOAD(12)
+ LLVM_DEFINE_OVERLOAD(13)
+ LLVM_DEFINE_OVERLOAD(14)
+ LLVM_DEFINE_OVERLOAD(15)
+ LLVM_DEFINE_OVERLOAD(16)
+ LLVM_DEFINE_OVERLOAD(17)
+ LLVM_DEFINE_OVERLOAD(18)
+ LLVM_DEFINE_OVERLOAD(19)
+ LLVM_DEFINE_OVERLOAD(20)
+ LLVM_DEFINE_OVERLOAD(21)
+ LLVM_DEFINE_OVERLOAD(22)
+ LLVM_DEFINE_OVERLOAD(23)
+ LLVM_DEFINE_OVERLOAD(24)
+ LLVM_DEFINE_OVERLOAD(25)
+ LLVM_DEFINE_OVERLOAD(26)
+ LLVM_DEFINE_OVERLOAD(27)
+ LLVM_DEFINE_OVERLOAD(28)
+ LLVM_DEFINE_OVERLOAD(29)
+ LLVM_DEFINE_OVERLOAD(30)
+ LLVM_DEFINE_OVERLOAD(31)
+ LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+template <typename ResultT, typename Param0T, typename Param1T, typename ArgT,
+ ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)>
+struct VariadicFunction2 {
+ ResultT operator()(Param0T P0, Param1T P1) const {
+ return Func(P0, P1, ArrayRef<const ArgT *>());
+ }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+ ResultT operator()(Param0T P0, Param1T P1, \
+ LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+ const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+ return Func(P0, P1, makeAraryRef(Args)); \
+ }
+ LLVM_DEFINE_OVERLOAD(1)
+ LLVM_DEFINE_OVERLOAD(2)
+ LLVM_DEFINE_OVERLOAD(3)
+ LLVM_DEFINE_OVERLOAD(4)
+ LLVM_DEFINE_OVERLOAD(5)
+ LLVM_DEFINE_OVERLOAD(6)
+ LLVM_DEFINE_OVERLOAD(7)
+ LLVM_DEFINE_OVERLOAD(8)
+ LLVM_DEFINE_OVERLOAD(9)
+ LLVM_DEFINE_OVERLOAD(10)
+ LLVM_DEFINE_OVERLOAD(11)
+ LLVM_DEFINE_OVERLOAD(12)
+ LLVM_DEFINE_OVERLOAD(13)
+ LLVM_DEFINE_OVERLOAD(14)
+ LLVM_DEFINE_OVERLOAD(15)
+ LLVM_DEFINE_OVERLOAD(16)
+ LLVM_DEFINE_OVERLOAD(17)
+ LLVM_DEFINE_OVERLOAD(18)
+ LLVM_DEFINE_OVERLOAD(19)
+ LLVM_DEFINE_OVERLOAD(20)
+ LLVM_DEFINE_OVERLOAD(21)
+ LLVM_DEFINE_OVERLOAD(22)
+ LLVM_DEFINE_OVERLOAD(23)
+ LLVM_DEFINE_OVERLOAD(24)
+ LLVM_DEFINE_OVERLOAD(25)
+ LLVM_DEFINE_OVERLOAD(26)
+ LLVM_DEFINE_OVERLOAD(27)
+ LLVM_DEFINE_OVERLOAD(28)
+ LLVM_DEFINE_OVERLOAD(29)
+ LLVM_DEFINE_OVERLOAD(30)
+ LLVM_DEFINE_OVERLOAD(31)
+ LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+template <typename ResultT, typename Param0T, typename Param1T,
+ typename Param2T, typename ArgT,
+ ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)>
+struct VariadicFunction3 {
+ ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const {
+ return Func(P0, P1, P2, ArrayRef<const ArgT *>());
+ }
+
+#define LLVM_DEFINE_OVERLOAD(N) \
+ ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \
+ LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \
+ const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \
+ return Func(P0, P1, P2, makeArrayRef(Args)); \
+ }
+ LLVM_DEFINE_OVERLOAD(1)
+ LLVM_DEFINE_OVERLOAD(2)
+ LLVM_DEFINE_OVERLOAD(3)
+ LLVM_DEFINE_OVERLOAD(4)
+ LLVM_DEFINE_OVERLOAD(5)
+ LLVM_DEFINE_OVERLOAD(6)
+ LLVM_DEFINE_OVERLOAD(7)
+ LLVM_DEFINE_OVERLOAD(8)
+ LLVM_DEFINE_OVERLOAD(9)
+ LLVM_DEFINE_OVERLOAD(10)
+ LLVM_DEFINE_OVERLOAD(11)
+ LLVM_DEFINE_OVERLOAD(12)
+ LLVM_DEFINE_OVERLOAD(13)
+ LLVM_DEFINE_OVERLOAD(14)
+ LLVM_DEFINE_OVERLOAD(15)
+ LLVM_DEFINE_OVERLOAD(16)
+ LLVM_DEFINE_OVERLOAD(17)
+ LLVM_DEFINE_OVERLOAD(18)
+ LLVM_DEFINE_OVERLOAD(19)
+ LLVM_DEFINE_OVERLOAD(20)
+ LLVM_DEFINE_OVERLOAD(21)
+ LLVM_DEFINE_OVERLOAD(22)
+ LLVM_DEFINE_OVERLOAD(23)
+ LLVM_DEFINE_OVERLOAD(24)
+ LLVM_DEFINE_OVERLOAD(25)
+ LLVM_DEFINE_OVERLOAD(26)
+ LLVM_DEFINE_OVERLOAD(27)
+ LLVM_DEFINE_OVERLOAD(28)
+ LLVM_DEFINE_OVERLOAD(29)
+ LLVM_DEFINE_OVERLOAD(30)
+ LLVM_DEFINE_OVERLOAD(31)
+ LLVM_DEFINE_OVERLOAD(32)
+#undef LLVM_DEFINE_OVERLOAD
+};
+
+// Cleanup the macro namespace.
+#undef LLVM_COMMA_JOIN1
+#undef LLVM_COMMA_JOIN2
+#undef LLVM_COMMA_JOIN3
+#undef LLVM_COMMA_JOIN4
+#undef LLVM_COMMA_JOIN5
+#undef LLVM_COMMA_JOIN6
+#undef LLVM_COMMA_JOIN7
+#undef LLVM_COMMA_JOIN8
+#undef LLVM_COMMA_JOIN9
+#undef LLVM_COMMA_JOIN10
+#undef LLVM_COMMA_JOIN11
+#undef LLVM_COMMA_JOIN12
+#undef LLVM_COMMA_JOIN13
+#undef LLVM_COMMA_JOIN14
+#undef LLVM_COMMA_JOIN15
+#undef LLVM_COMMA_JOIN16
+#undef LLVM_COMMA_JOIN17
+#undef LLVM_COMMA_JOIN18
+#undef LLVM_COMMA_JOIN19
+#undef LLVM_COMMA_JOIN20
+#undef LLVM_COMMA_JOIN21
+#undef LLVM_COMMA_JOIN22
+#undef LLVM_COMMA_JOIN23
+#undef LLVM_COMMA_JOIN24
+#undef LLVM_COMMA_JOIN25
+#undef LLVM_COMMA_JOIN26
+#undef LLVM_COMMA_JOIN27
+#undef LLVM_COMMA_JOIN28
+#undef LLVM_COMMA_JOIN29
+#undef LLVM_COMMA_JOIN30
+#undef LLVM_COMMA_JOIN31
+#undef LLVM_COMMA_JOIN32
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_VARIADIC_FUNCTION_H
diff --git a/contrib/llvm/include/llvm/ADT/edit_distance.h b/contrib/llvm/include/llvm/ADT/edit_distance.h
new file mode 100644
index 000000000000..f77ef13fef2b
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/edit_distance.h
@@ -0,0 +1,102 @@
+//===-- llvm/ADT/edit_distance.h - Array edit distance function --- 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 Levenshtein distance function that works for any two
+// sequences, with each element of each sequence being analogous to a character
+// in a string.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EDIT_DISTANCE_H
+#define LLVM_ADT_EDIT_DISTANCE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/OwningPtr.h"
+#include <algorithm>
+
+namespace llvm {
+
+/// \brief Determine the edit distance between two sequences.
+///
+/// \param FromArray the first sequence to compare.
+///
+/// \param ToArray the second sequence to compare.
+///
+/// \param AllowReplacements whether to allow element replacements (change one
+/// element into another) as a single operation, rather than as two operations
+/// (an insertion and a removal).
+///
+/// \param MaxEditDistance If non-zero, the maximum edit distance that this
+/// routine is allowed to compute. If the edit distance will exceed that
+/// maximum, returns \c MaxEditDistance+1.
+///
+/// \returns the minimum number of element insertions, removals, or (if
+/// \p AllowReplacements is \c true) replacements needed to transform one of
+/// the given sequences into the other. If zero, the sequences are identical.
+template<typename T>
+unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
+ bool AllowReplacements = true,
+ unsigned MaxEditDistance = 0) {
+ // The algorithm implemented below is the "classic"
+ // dynamic-programming algorithm for computing the Levenshtein
+ // distance, which is described here:
+ //
+ // http://en.wikipedia.org/wiki/Levenshtein_distance
+ //
+ // Although the algorithm is typically described using an m x n
+ // array, only two rows are used at a time, so this implemenation
+ // just keeps two separate vectors for those two rows.
+ typename ArrayRef<T>::size_type m = FromArray.size();
+ typename ArrayRef<T>::size_type n = ToArray.size();
+
+ const unsigned SmallBufferSize = 64;
+ unsigned SmallBuffer[SmallBufferSize];
+ llvm::OwningArrayPtr<unsigned> Allocated;
+ unsigned *Previous = SmallBuffer;
+ if (2*(n + 1) > SmallBufferSize) {
+ Previous = new unsigned [2*(n+1)];
+ Allocated.reset(Previous);
+ }
+ unsigned *Current = Previous + (n + 1);
+
+ for (unsigned i = 0; i <= n; ++i)
+ Previous[i] = i;
+
+ for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) {
+ Current[0] = y;
+ unsigned BestThisRow = Current[0];
+
+ for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) {
+ if (AllowReplacements) {
+ Current[x] = std::min(
+ Previous[x-1] + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
+ std::min(Current[x-1], Previous[x])+1);
+ }
+ else {
+ if (FromArray[y-1] == ToArray[x-1]) Current[x] = Previous[x-1];
+ else Current[x] = std::min(Current[x-1], Previous[x]) + 1;
+ }
+ BestThisRow = std::min(BestThisRow, Current[x]);
+ }
+
+ if (MaxEditDistance && BestThisRow > MaxEditDistance)
+ return MaxEditDistance + 1;
+
+ unsigned *tmp = Current;
+ Current = Previous;
+ Previous = tmp;
+ }
+
+ unsigned Result = Previous[n];
+ return Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ADT/ilist.h b/contrib/llvm/include/llvm/ADT/ilist.h
new file mode 100644
index 000000000000..ba9864a98a7e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ilist.h
@@ -0,0 +1,704 @@
+//==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- 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 classes to implement an intrusive doubly linked list class
+// (i.e. each node of the list must contain a next and previous field for the
+// list.
+//
+// The ilist_traits trait class is used to gain access to the next and previous
+// fields of the node type that the list is instantiated with. If it is not
+// specialized, the list defaults to using the getPrev(), getNext() method calls
+// to get the next and previous pointers.
+//
+// The ilist class itself, should be a plug in replacement for list, assuming
+// that the nodes contain next/prev pointers. This list replacement does not
+// provide a constant time size() method, so be careful to use empty() when you
+// really want to know if it's empty.
+//
+// The ilist class is implemented by allocating a 'tail' node when the list is
+// created (using ilist_traits<>::createSentinel()). This tail node is
+// absolutely required because the user must be able to compute end()-1. Because
+// of this, users of the direct next/prev links will see an extra link on the
+// end of the list, which should be ignored.
+//
+// Requirements for a user of this list:
+//
+// 1. The user must provide {g|s}et{Next|Prev} methods, or specialize
+// ilist_traits to provide an alternate way of getting and setting next and
+// prev links.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST_H
+#define LLVM_ADT_ILIST_H
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+
+namespace llvm {
+
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+/// ilist_nextprev_traits - A fragment for template traits for intrusive list
+/// that provides default next/prev implementations for common operations.
+///
+template<typename NodeTy>
+struct ilist_nextprev_traits {
+ static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
+ static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
+ static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
+ static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
+
+ static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
+ static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
+};
+
+template<typename NodeTy>
+struct ilist_traits;
+
+/// ilist_sentinel_traits - A fragment for template traits for intrusive list
+/// that provides default sentinel implementations for common operations.
+///
+/// ilist_sentinel_traits implements a lazy dynamic sentinel allocation
+/// strategy. The sentinel is stored in the prev field of ilist's Head.
+///
+template<typename NodeTy>
+struct ilist_sentinel_traits {
+ /// createSentinel - create the dynamic sentinel
+ static NodeTy *createSentinel() { return new NodeTy(); }
+
+ /// destroySentinel - deallocate the dynamic sentinel
+ static void destroySentinel(NodeTy *N) { delete N; }
+
+ /// provideInitialHead - when constructing an ilist, provide a starting
+ /// value for its Head
+ /// @return null node to indicate that it needs to be allocated later
+ static NodeTy *provideInitialHead() { return 0; }
+
+ /// ensureHead - make sure that Head is either already
+ /// initialized or assigned a fresh sentinel
+ /// @return the sentinel
+ static NodeTy *ensureHead(NodeTy *&Head) {
+ if (!Head) {
+ Head = ilist_traits<NodeTy>::createSentinel();
+ ilist_traits<NodeTy>::noteHead(Head, Head);
+ ilist_traits<NodeTy>::setNext(Head, 0);
+ return Head;
+ }
+ return ilist_traits<NodeTy>::getPrev(Head);
+ }
+
+ /// noteHead - stash the sentinel into its default location
+ static void noteHead(NodeTy *NewHead, NodeTy *Sentinel) {
+ ilist_traits<NodeTy>::setPrev(NewHead, Sentinel);
+ }
+};
+
+/// ilist_node_traits - A fragment for template traits for intrusive list
+/// that provides default node related operations.
+///
+template<typename NodeTy>
+struct ilist_node_traits {
+ static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
+ static void deleteNode(NodeTy *V) { delete V; }
+
+ void addNodeToList(NodeTy *) {}
+ void removeNodeFromList(NodeTy *) {}
+ void transferNodesFromList(ilist_node_traits & /*SrcTraits*/,
+ ilist_iterator<NodeTy> /*first*/,
+ ilist_iterator<NodeTy> /*last*/) {}
+};
+
+/// ilist_default_traits - Default template traits for intrusive list.
+/// By inheriting from this, you can easily use default implementations
+/// for all common operations.
+///
+template<typename NodeTy>
+struct ilist_default_traits : public ilist_nextprev_traits<NodeTy>,
+ public ilist_sentinel_traits<NodeTy>,
+ public ilist_node_traits<NodeTy> {
+};
+
+// Template traits for intrusive list. By specializing this template class, you
+// can change what next/prev fields are used to store the links...
+template<typename NodeTy>
+struct ilist_traits : public ilist_default_traits<NodeTy> {};
+
+// Const traits are the same as nonconst traits...
+template<typename Ty>
+struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
+
+//===----------------------------------------------------------------------===//
+// ilist_iterator<Node> - Iterator for intrusive list.
+//
+template<typename NodeTy>
+class ilist_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, NodeTy, ptrdiff_t> {
+
+public:
+ typedef ilist_traits<NodeTy> Traits;
+ typedef std::iterator<std::bidirectional_iterator_tag,
+ NodeTy, ptrdiff_t> super;
+
+ typedef typename super::value_type value_type;
+ typedef typename super::difference_type difference_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+private:
+ pointer NodePtr;
+
+ // ilist_iterator is not a random-access iterator, but it has an
+ // implicit conversion to pointer-type, which is. Declare (but
+ // don't define) these functions as private to help catch
+ // accidental misuse.
+ void operator[](difference_type) const;
+ void operator+(difference_type) const;
+ void operator-(difference_type) const;
+ void operator+=(difference_type) const;
+ void operator-=(difference_type) const;
+ template<class T> void operator<(T) const;
+ template<class T> void operator<=(T) const;
+ template<class T> void operator>(T) const;
+ template<class T> void operator>=(T) const;
+ template<class T> void operator-(T) const;
+public:
+
+ ilist_iterator(pointer NP) : NodePtr(NP) {}
+ ilist_iterator(reference NR) : NodePtr(&NR) {}
+ ilist_iterator() : NodePtr(0) {}
+
+ // This is templated so that we can allow constructing a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ ilist_iterator(const ilist_iterator<node_ty> &RHS)
+ : NodePtr(RHS.getNodePtrUnchecked()) {}
+
+ // This is templated so that we can allow assigning to a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
+ NodePtr = RHS.getNodePtrUnchecked();
+ return *this;
+ }
+
+ // Accessors...
+ operator pointer() const {
+ return NodePtr;
+ }
+
+ reference operator*() const {
+ return *NodePtr;
+ }
+ pointer operator->() const { return &operator*(); }
+
+ // Comparison operators
+ bool operator==(const ilist_iterator &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const ilist_iterator &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+
+ // Increment and decrement operators...
+ ilist_iterator &operator--() { // predecrement - Back up
+ NodePtr = Traits::getPrev(NodePtr);
+ assert(NodePtr && "--'d off the beginning of an ilist!");
+ return *this;
+ }
+ ilist_iterator &operator++() { // preincrement - Advance
+ NodePtr = Traits::getNext(NodePtr);
+ return *this;
+ }
+ ilist_iterator operator--(int) { // postdecrement operators...
+ ilist_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ ilist_iterator operator++(int) { // postincrement operators...
+ ilist_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Internal interface, do not use...
+ pointer getNodePtrUnchecked() const { return NodePtr; }
+};
+
+// do not implement. this is to catch errors when people try to use
+// them as random access iterators
+template<typename T>
+void operator-(int, ilist_iterator<T>);
+template<typename T>
+void operator-(ilist_iterator<T>,int);
+
+template<typename T>
+void operator+(int, ilist_iterator<T>);
+template<typename T>
+void operator+(ilist_iterator<T>,int);
+
+// operator!=/operator== - Allow mixed comparisons without dereferencing
+// the iterator, which could very likely be pointing to end().
+template<typename T>
+bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+
+
+// Allow ilist_iterators to convert into pointers to a node automatically when
+// used by the dyn_cast, cast, isa mechanisms...
+
+template<typename From> struct simplify_type;
+
+template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+/// iplist - The subset of list functionality that can safely be used on nodes
+/// of polymorphic types, i.e. a heterogeneous list with a common base class that
+/// holds the next/prev pointers. The only state of the list itself is a single
+/// pointer to the head of the list.
+///
+/// This list can be in one of three interesting states:
+/// 1. The list may be completely unconstructed. In this case, the head
+/// pointer is null. When in this form, any query for an iterator (e.g.
+/// begin() or end()) causes the list to transparently change to state #2.
+/// 2. The list may be empty, but contain a sentinel for the end iterator. This
+/// sentinel is created by the Traits::createSentinel method and is a link
+/// in the list. When the list is empty, the pointer in the iplist points
+/// to the sentinel. Once the sentinel is constructed, it
+/// is not destroyed until the list is.
+/// 3. The list may contain actual objects in it, which are stored as a doubly
+/// linked list of nodes. One invariant of the list is that the predecessor
+/// of the first node in the list always points to the last node in the list,
+/// and the successor pointer for the sentinel (which always stays at the
+/// end of the list) is always null.
+///
+template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
+class iplist : public Traits {
+ mutable NodeTy *Head;
+
+ // Use the prev node pointer of 'head' as the tail pointer. This is really a
+ // circularly linked list where we snip the 'next' link from the sentinel node
+ // back to the first node in the list (to preserve assertions about going off
+ // the end of the list).
+ NodeTy *getTail() { return this->ensureHead(Head); }
+ const NodeTy *getTail() const { return this->ensureHead(Head); }
+ void setTail(NodeTy *N) const { this->noteHead(Head, N); }
+
+ /// CreateLazySentinel - This method verifies whether the sentinel for the
+ /// list has been created and lazily makes it if not.
+ void CreateLazySentinel() const {
+ this->ensureHead(Head);
+ }
+
+ static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
+ static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
+
+ // 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
+
+public:
+ typedef NodeTy *pointer;
+ typedef const NodeTy *const_pointer;
+ typedef NodeTy &reference;
+ typedef const NodeTy &const_reference;
+ typedef NodeTy value_type;
+ typedef ilist_iterator<NodeTy> iterator;
+ typedef ilist_iterator<const NodeTy> const_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ iplist() : Head(this->provideInitialHead()) {}
+ ~iplist() {
+ if (!Head) return;
+ clear();
+ Traits::destroySentinel(getTail());
+ }
+
+ // Iterator creation methods.
+ iterator begin() {
+ CreateLazySentinel();
+ return iterator(Head);
+ }
+ const_iterator begin() const {
+ CreateLazySentinel();
+ return const_iterator(Head);
+ }
+ iterator end() {
+ CreateLazySentinel();
+ return iterator(getTail());
+ }
+ const_iterator end() const {
+ CreateLazySentinel();
+ return const_iterator(getTail());
+ }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+
+ // Miscellaneous inspection routines.
+ size_type max_size() const { return size_type(-1); }
+ bool empty() const { return Head == 0 || Head == getTail(); }
+
+ // Front and back accessor functions...
+ reference front() {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ const_reference front() const {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ reference back() {
+ assert(!empty() && "Called back() on empty list!");
+ return *this->getPrev(getTail());
+ }
+ const_reference back() const {
+ assert(!empty() && "Called back() on empty list!");
+ return *this->getPrev(getTail());
+ }
+
+ void swap(iplist &RHS) {
+ assert(0 && "Swap does not use list traits callback correctly yet!");
+ std::swap(Head, RHS.Head);
+ }
+
+ iterator insert(iterator where, NodeTy *New) {
+ NodeTy *CurNode = where.getNodePtrUnchecked();
+ NodeTy *PrevNode = this->getPrev(CurNode);
+ this->setNext(New, CurNode);
+ this->setPrev(New, PrevNode);
+
+ if (CurNode != Head) // Is PrevNode off the beginning of the list?
+ this->setNext(PrevNode, New);
+ else
+ Head = New;
+ this->setPrev(CurNode, New);
+
+ this->addNodeToList(New); // Notify traits that we added a node...
+ return New;
+ }
+
+ iterator insertAfter(iterator where, NodeTy *New) {
+ if (empty())
+ return insert(begin(), New);
+ else
+ return insert(++where, New);
+ }
+
+ NodeTy *remove(iterator &IT) {
+ assert(IT != end() && "Cannot remove end of list!");
+ NodeTy *Node = &*IT;
+ NodeTy *NextNode = this->getNext(Node);
+ NodeTy *PrevNode = this->getPrev(Node);
+
+ if (Node != Head) // Is PrevNode off the beginning of the list?
+ this->setNext(PrevNode, NextNode);
+ else
+ Head = NextNode;
+ this->setPrev(NextNode, PrevNode);
+ IT = NextNode;
+ this->removeNodeFromList(Node); // Notify traits that we removed a node...
+
+ // Set the next/prev pointers of the current node to null. This isn't
+ // strictly required, but this catches errors where a node is removed from
+ // an ilist (and potentially deleted) with iterators still pointing at it.
+ // When those iterators are incremented or decremented, they will assert on
+ // the null next/prev pointer instead of "usually working".
+ this->setNext(Node, 0);
+ this->setPrev(Node, 0);
+ return Node;
+ }
+
+ NodeTy *remove(const iterator &IT) {
+ iterator MutIt = IT;
+ return remove(MutIt);
+ }
+
+ // erase - remove a node from the controlled sequence... and delete it.
+ iterator erase(iterator where) {
+ this->deleteNode(remove(where));
+ return where;
+ }
+
+
+private:
+ // transfer - The heart of the splice function. Move linked list nodes from
+ // [first, last) into position.
+ //
+ void transfer(iterator position, iplist &L2, iterator first, iterator last) {
+ assert(first != last && "Should be checked by callers");
+
+ if (position != last) {
+ // Note: we have to be careful about the case when we move the first node
+ // in the list. This node is the list sentinel node and we can't move it.
+ NodeTy *ThisSentinel = getTail();
+ setTail(0);
+ NodeTy *L2Sentinel = L2.getTail();
+ L2.setTail(0);
+
+ // Remove [first, last) from its old position.
+ NodeTy *First = &*first, *Prev = this->getPrev(First);
+ NodeTy *Next = last.getNodePtrUnchecked(), *Last = this->getPrev(Next);
+ if (Prev)
+ this->setNext(Prev, Next);
+ else
+ L2.Head = Next;
+ this->setPrev(Next, Prev);
+
+ // Splice [first, last) into its new position.
+ NodeTy *PosNext = position.getNodePtrUnchecked();
+ NodeTy *PosPrev = this->getPrev(PosNext);
+
+ // Fix head of list...
+ if (PosPrev)
+ this->setNext(PosPrev, First);
+ else
+ Head = First;
+ this->setPrev(First, PosPrev);
+
+ // Fix end of list...
+ this->setNext(Last, PosNext);
+ this->setPrev(PosNext, Last);
+
+ this->transferNodesFromList(L2, First, PosNext);
+
+ // Now that everything is set, restore the pointers to the list sentinels.
+ L2.setTail(L2Sentinel);
+ setTail(ThisSentinel);
+ }
+ }
+
+public:
+
+ //===----------------------------------------------------------------------===
+ // Functionality derived from other functions defined above...
+ //
+
+ size_type size() const {
+ if (Head == 0) return 0; // Don't require construction of sentinel if empty.
+ return std::distance(begin(), end());
+ }
+
+ iterator erase(iterator first, iterator last) {
+ while (first != last)
+ first = erase(first);
+ return last;
+ }
+
+ void clear() { if (Head) erase(begin(), end()); }
+
+ // Front and back inserters...
+ void push_front(NodeTy *val) { insert(begin(), val); }
+ void push_back(NodeTy *val) { insert(end(), val); }
+ void pop_front() {
+ assert(!empty() && "pop_front() on empty list!");
+ erase(begin());
+ }
+ void pop_back() {
+ assert(!empty() && "pop_back() on empty list!");
+ iterator t = end(); erase(--t);
+ }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+
+ // Splice members - defined in terms of transfer...
+ void splice(iterator where, iplist &L2) {
+ if (!L2.empty())
+ transfer(where, L2, L2.begin(), L2.end());
+ }
+ void splice(iterator where, iplist &L2, iterator first) {
+ iterator last = first; ++last;
+ if (where == first || where == last) return; // No change
+ transfer(where, L2, first, last);
+ }
+ void splice(iterator where, iplist &L2, iterator first, iterator last) {
+ if (first != last) transfer(where, L2, first, last);
+ }
+
+
+
+ //===----------------------------------------------------------------------===
+ // High-Level Functionality that shouldn't really be here, but is part of list
+ //
+
+ // These two functions are actually called remove/remove_if in list<>, but
+ // they actually do the job of erase, rename them accordingly.
+ //
+ void erase(const NodeTy &val) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (*I == val) erase(I);
+ I = next;
+ }
+ }
+ template<class Pr1> void erase_if(Pr1 pred) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (pred(*I)) erase(I);
+ I = next;
+ }
+ }
+
+ template<class Pr2> void unique(Pr2 pred) {
+ if (empty()) return;
+ for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
+ if (pred(*I))
+ erase(Next);
+ else
+ I = Next;
+ Next = I;
+ }
+ }
+ void unique() { unique(op_equal); }
+
+ template<class Pr3> void merge(iplist &right, Pr3 pred) {
+ iterator first1 = begin(), last1 = end();
+ iterator first2 = right.begin(), last2 = right.end();
+ while (first1 != last1 && first2 != last2)
+ if (pred(*first2, *first1)) {
+ iterator next = first2;
+ transfer(first1, right, first2, ++next);
+ first2 = next;
+ } else {
+ ++first1;
+ }
+ if (first2 != last2) transfer(last1, right, first2, last2);
+ }
+ void merge(iplist &right) { return merge(right, op_less); }
+
+ template<class Pr3> void sort(Pr3 pred);
+ void sort() { sort(op_less); }
+};
+
+
+template<typename NodeTy>
+struct ilist : public iplist<NodeTy> {
+ typedef typename iplist<NodeTy>::size_type size_type;
+ typedef typename iplist<NodeTy>::iterator iterator;
+
+ ilist() {}
+ ilist(const ilist &right) {
+ insert(this->begin(), right.begin(), right.end());
+ }
+ explicit ilist(size_type count) {
+ insert(this->begin(), count, NodeTy());
+ }
+ ilist(size_type count, const NodeTy &val) {
+ insert(this->begin(), count, val);
+ }
+ template<class InIt> ilist(InIt first, InIt last) {
+ insert(this->begin(), first, last);
+ }
+
+ // bring hidden functions into scope
+ using iplist<NodeTy>::insert;
+ using iplist<NodeTy>::push_front;
+ using iplist<NodeTy>::push_back;
+
+ // Main implementation here - Insert for a node passed by value...
+ iterator insert(iterator where, const NodeTy &val) {
+ return insert(where, this->createNode(val));
+ }
+
+
+ // Front and back inserters...
+ void push_front(const NodeTy &val) { insert(this->begin(), val); }
+ void push_back(const NodeTy &val) { insert(this->end(), val); }
+
+ void insert(iterator where, size_type count, const NodeTy &val) {
+ for (; count != 0; --count) insert(where, val);
+ }
+
+ // Assign special forms...
+ void assign(size_type count, const NodeTy &val) {
+ iterator I = this->begin();
+ for (; I != this->end() && count != 0; ++I, --count)
+ *I = val;
+ if (count != 0)
+ insert(this->end(), val, val);
+ else
+ erase(I, this->end());
+ }
+ template<class InIt> void assign(InIt first1, InIt last1) {
+ iterator first2 = this->begin(), last2 = this->end();
+ for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+ *first1 = *first2;
+ if (first2 == last2)
+ erase(first1, last1);
+ else
+ insert(last1, first2, last2);
+ }
+
+
+ // Resize members...
+ void resize(size_type newsize, NodeTy val) {
+ iterator i = this->begin();
+ size_type len = 0;
+ for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
+
+ if (len == newsize)
+ erase(i, this->end());
+ else // i == end()
+ insert(this->end(), newsize - len, val);
+ }
+ void resize(size_type newsize) { resize(newsize, NodeTy()); }
+};
+
+} // End llvm namespace
+
+namespace std {
+ // Ensure that swap uses the fast list swap...
+ template<class Ty>
+ void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
+ Left.swap(Right);
+ }
+} // End 'std' extensions...
+
+#endif // LLVM_ADT_ILIST_H
diff --git a/contrib/llvm/include/llvm/ADT/ilist_node.h b/contrib/llvm/include/llvm/ADT/ilist_node.h
new file mode 100644
index 000000000000..f0080035cb88
--- /dev/null
+++ b/contrib/llvm/include/llvm/ADT/ilist_node.h
@@ -0,0 +1,106 @@
+//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- 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 ilist_node class template, which is a convenient
+// base class for creating classes that can be used with ilists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST_NODE_H
+#define LLVM_ADT_ILIST_NODE_H
+
+namespace llvm {
+
+template<typename NodeTy>
+struct ilist_traits;
+
+/// ilist_half_node - Base class that provides prev services for sentinels.
+///
+template<typename NodeTy>
+class ilist_half_node {
+ friend struct ilist_traits<NodeTy>;
+ NodeTy *Prev;
+protected:
+ NodeTy *getPrev() { return Prev; }
+ const NodeTy *getPrev() const { return Prev; }
+ void setPrev(NodeTy *P) { Prev = P; }
+ ilist_half_node() : Prev(0) {}
+};
+
+template<typename NodeTy>
+struct ilist_nextprev_traits;
+
+/// ilist_node - Base class that provides next/prev services for nodes
+/// that use ilist_nextprev_traits or ilist_default_traits.
+///
+template<typename NodeTy>
+class ilist_node : private ilist_half_node<NodeTy> {
+ friend struct ilist_nextprev_traits<NodeTy>;
+ friend struct ilist_traits<NodeTy>;
+ NodeTy *Next;
+ NodeTy *getNext() { return Next; }
+ const NodeTy *getNext() const { return Next; }
+ void setNext(NodeTy *N) { Next = N; }
+protected:
+ ilist_node() : Next(0) {}
+
+public:
+ /// @name Adjacent Node Accessors
+ /// @{
+
+ /// \brief Get the previous node, or 0 for the list head.
+ NodeTy *getPrevNode() {
+ NodeTy *Prev = this->getPrev();
+
+ // Check for sentinel.
+ if (!Prev->getNext())
+ return 0;
+
+ return Prev;
+ }
+
+ /// \brief Get the previous node, or 0 for the list head.
+ const NodeTy *getPrevNode() const {
+ const NodeTy *Prev = this->getPrev();
+
+ // Check for sentinel.
+ if (!Prev->getNext())
+ return 0;
+
+ return Prev;
+ }
+
+ /// \brief Get the next node, or 0 for the list tail.
+ NodeTy *getNextNode() {
+ NodeTy *Next = getNext();
+
+ // Check for sentinel.
+ if (!Next->getNext())
+ return 0;
+
+ return Next;
+ }
+
+ /// \brief Get the next node, or 0 for the list tail.
+ const NodeTy *getNextNode() const {
+ const NodeTy *Next = getNext();
+
+ // Check for sentinel.
+ if (!Next->getNext())
+ return 0;
+
+ return Next;
+ }
+
+ /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h
new file mode 100644
index 000000000000..b823f71a2217
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -0,0 +1,578 @@
+//===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the generic AliasAnalysis interface, which is used as the
+// common interface used by all clients of alias analysis information, and
+// implemented by all alias analysis implementations. Mod/Ref information is
+// also captured by this interface.
+//
+// Implementations of this interface must implement the various virtual methods,
+// which automatically provides functionality for the entire suite of client
+// APIs.
+//
+// This API identifies memory regions with the Location class. The pointer
+// component specifies the base memory address of the region. The Size specifies
+// the maximum size (in address units) of the memory region, or UnknownSize if
+// the size is not known. The TBAA tag identifies the "type" of the memory
+// reference; see the TypeBasedAliasAnalysis class for details.
+//
+// Some non-obvious details include:
+// - Pointers that point to two completely different objects in memory never
+// alias, regardless of the value of the Size component.
+// - NoAlias doesn't imply inequal pointers. The most obvious example of this
+// is two pointers to constant memory. Even if they are equal, constant
+// memory is never stored to, so there will never be any dependencies.
+// In this and other situations, the pointers may be both NoAlias and
+// MustAlias at the same time. The current API can only return one result,
+// though this is rarely a problem in practice.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
+#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
+
+#include "llvm/Support/CallSite.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+class LoadInst;
+class StoreInst;
+class VAArgInst;
+class TargetData;
+class Pass;
+class AnalysisUsage;
+class MemTransferInst;
+class MemIntrinsic;
+
+class AliasAnalysis {
+protected:
+ const TargetData *TD;
+
+private:
+ AliasAnalysis *AA; // Previous Alias Analysis to chain to.
+
+protected:
+ /// InitializeAliasAnalysis - Subclasses must call this method to initialize
+ /// the AliasAnalysis interface before any other methods are called. This is
+ /// typically called by the run* methods of these subclasses. This may be
+ /// called multiple times.
+ ///
+ void InitializeAliasAnalysis(Pass *P);
+
+ /// getAnalysisUsage - All alias analysis implementations should invoke this
+ /// directly (using AliasAnalysis::getAnalysisUsage(AU)).
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+ AliasAnalysis() : TD(0), AA(0) {}
+ virtual ~AliasAnalysis(); // We want to be subclassed
+
+ /// UnknownSize - This is a special value which can be used with the
+ /// size arguments in alias queries to indicate that the caller does not
+ /// 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.
+ ///
+ const TargetData *getTargetData() const { return TD; }
+
+ /// getTypeStoreSize - Return the TargetData store size for the given type,
+ /// if known, or a conservative value otherwise.
+ ///
+ uint64_t getTypeStoreSize(Type *Ty);
+
+ //===--------------------------------------------------------------------===//
+ /// Alias Queries...
+ ///
+
+ /// Location - A description of a memory location.
+ struct Location {
+ /// Ptr - The address of the start of the location.
+ const Value *Ptr;
+ /// Size - The maximum size of the location, in address-units, or
+ /// UnknownSize if the size is not known. Note that an unknown size does
+ /// not mean the pointer aliases the entire virtual address space, because
+ /// there are restrictions on stepping out of one object and into another.
+ /// See http://llvm.org/docs/LangRef.html#pointeraliasing
+ uint64_t Size;
+ /// TBAATag - The metadata node which describes the TBAA type of
+ /// the location, or null if there is no known unique tag.
+ const MDNode *TBAATag;
+
+ explicit Location(const Value *P = 0, uint64_t S = UnknownSize,
+ const MDNode *N = 0)
+ : Ptr(P), Size(S), TBAATag(N) {}
+
+ Location getWithNewPtr(const Value *NewPtr) const {
+ Location Copy(*this);
+ Copy.Ptr = NewPtr;
+ return Copy;
+ }
+
+ Location getWithNewSize(uint64_t NewSize) const {
+ Location Copy(*this);
+ Copy.Size = NewSize;
+ return Copy;
+ }
+
+ Location getWithoutTBAATag() const {
+ Location Copy(*this);
+ Copy.TBAATag = 0;
+ return Copy;
+ }
+ };
+
+ /// getLocation - Fill in Loc with information about the memory reference by
+ /// the given instruction.
+ Location getLocation(const LoadInst *LI);
+ Location getLocation(const StoreInst *SI);
+ Location getLocation(const VAArgInst *VI);
+ Location getLocation(const AtomicCmpXchgInst *CXI);
+ Location getLocation(const AtomicRMWInst *RMWI);
+ static Location getLocationForSource(const MemTransferInst *MTI);
+ static Location getLocationForDest(const MemIntrinsic *MI);
+
+ /// Alias analysis result - Either we know for sure that it does not alias, we
+ /// know for sure it must alias, or we don't know anything: The two pointers
+ /// _might_ alias. This enum is designed so you can do things like:
+ /// if (AA.alias(P1, P2)) { ... }
+ /// to check to see if two pointers might alias.
+ ///
+ /// See docs/AliasAnalysis.html for more information on the specific meanings
+ /// of these values.
+ ///
+ enum AliasResult {
+ NoAlias = 0, ///< No dependencies.
+ MayAlias, ///< Anything goes.
+ PartialAlias, ///< Pointers differ, but pointees overlap.
+ MustAlias ///< Pointers are equal.
+ };
+
+ /// alias - The main low level interface to the alias analysis implementation.
+ /// Returns an AliasResult indicating whether the two pointers are aliased to
+ /// each other. This is the interface that must be implemented by specific
+ /// alias analysis implementations.
+ virtual AliasResult alias(const Location &LocA, const Location &LocB);
+
+ /// alias - A convenience wrapper.
+ AliasResult alias(const Value *V1, uint64_t V1Size,
+ const Value *V2, uint64_t V2Size) {
+ return alias(Location(V1, V1Size), Location(V2, V2Size));
+ }
+
+ /// alias - A convenience wrapper.
+ AliasResult alias(const Value *V1, const Value *V2) {
+ return alias(V1, UnknownSize, V2, UnknownSize);
+ }
+
+ /// isNoAlias - A trivial helper function to check to see if the specified
+ /// pointers are no-alias.
+ bool isNoAlias(const Location &LocA, const Location &LocB) {
+ return alias(LocA, LocB) == NoAlias;
+ }
+
+ /// isNoAlias - A convenience wrapper.
+ bool isNoAlias(const Value *V1, uint64_t V1Size,
+ const Value *V2, uint64_t V2Size) {
+ return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
+ }
+
+ /// isMustAlias - A convenience wrapper.
+ bool isMustAlias(const Location &LocA, const Location &LocB) {
+ return alias(LocA, LocB) == MustAlias;
+ }
+
+ /// isMustAlias - A convenience wrapper.
+ bool isMustAlias(const Value *V1, const Value *V2) {
+ return alias(V1, 1, V2, 1) == MustAlias;
+ }
+
+ /// pointsToConstantMemory - If the specified memory location is
+ /// known to be constant, return true. If OrLocal is true and the
+ /// specified memory location is known to be "local" (derived from
+ /// an alloca), return true. Otherwise return false.
+ virtual bool pointsToConstantMemory(const Location &Loc,
+ bool OrLocal = false);
+
+ /// pointsToConstantMemory - A convenient wrapper.
+ bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
+ return pointsToConstantMemory(Location(P), OrLocal);
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// Simple mod/ref information...
+ ///
+
+ /// ModRefResult - Represent the result of a mod/ref query. Mod and Ref are
+ /// bits which may be or'd together.
+ ///
+ enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
+
+ /// These values define additional bits used to define the
+ /// ModRefBehavior values.
+ enum { Nowhere = 0, ArgumentPointees = 4, Anywhere = 8 | ArgumentPointees };
+
+ /// ModRefBehavior - Summary of how a function affects memory in the program.
+ /// Loads from constant globals are not considered memory accesses for this
+ /// interface. Also, functions may freely modify stack space local to their
+ /// invocation without having to report it through these interfaces.
+ enum ModRefBehavior {
+ /// DoesNotAccessMemory - This function does not perform any non-local loads
+ /// or stores to memory.
+ ///
+ /// This property corresponds to the GCC 'const' attribute.
+ /// This property corresponds to the LLVM IR 'readnone' attribute.
+ /// This property corresponds to the IntrNoMem LLVM intrinsic flag.
+ DoesNotAccessMemory = Nowhere | NoModRef,
+
+ /// OnlyReadsArgumentPointees - The only memory references in this function
+ /// (if it has any) are non-volatile loads from objects pointed to by its
+ /// pointer-typed arguments, with arbitrary offsets.
+ ///
+ /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
+ OnlyReadsArgumentPointees = ArgumentPointees | Ref,
+
+ /// OnlyAccessesArgumentPointees - The only memory references in this
+ /// function (if it has any) are non-volatile loads and stores from objects
+ /// pointed to by its pointer-typed arguments, with arbitrary offsets.
+ ///
+ /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
+ OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
+
+ /// OnlyReadsMemory - This function does not perform any non-local stores or
+ /// volatile loads, but may read from any memory location.
+ ///
+ /// This property corresponds to the GCC 'pure' attribute.
+ /// This property corresponds to the LLVM IR 'readonly' attribute.
+ /// This property corresponds to the IntrReadMem LLVM intrinsic flag.
+ OnlyReadsMemory = Anywhere | Ref,
+
+ /// UnknownModRefBehavior - This indicates that the function could not be
+ /// classified into one of the behaviors above.
+ UnknownModRefBehavior = Anywhere | ModRef
+ };
+
+ /// getModRefBehavior - Return the behavior when calling the given call site.
+ virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
+
+ /// getModRefBehavior - Return the behavior when calling the given function.
+ /// For use when the call site is not known.
+ virtual ModRefBehavior getModRefBehavior(const Function *F);
+
+ /// doesNotAccessMemory - If the specified call is known to never read or
+ /// write memory, return true. If the call only reads from known-constant
+ /// memory, it is also legal to return true. Calls that unwind the stack
+ /// are legal for this predicate.
+ ///
+ /// Many optimizations (such as CSE and LICM) can be performed on such calls
+ /// without worrying about aliasing properties, and many calls have this
+ /// property (e.g. calls to 'sin' and 'cos').
+ ///
+ /// This property corresponds to the GCC 'const' attribute.
+ ///
+ bool doesNotAccessMemory(ImmutableCallSite CS) {
+ return getModRefBehavior(CS) == DoesNotAccessMemory;
+ }
+
+ /// doesNotAccessMemory - If the specified function is known to never read or
+ /// write memory, return true. For use when the call site is not known.
+ ///
+ bool doesNotAccessMemory(const Function *F) {
+ return getModRefBehavior(F) == DoesNotAccessMemory;
+ }
+
+ /// onlyReadsMemory - If the specified call is known to only read from
+ /// non-volatile memory (or not access memory at all), return true. Calls
+ /// that unwind the stack are legal for this predicate.
+ ///
+ /// This property allows many common optimizations to be performed in the
+ /// absence of interfering store instructions, such as CSE of strlen calls.
+ ///
+ /// This property corresponds to the GCC 'pure' attribute.
+ ///
+ bool onlyReadsMemory(ImmutableCallSite CS) {
+ return onlyReadsMemory(getModRefBehavior(CS));
+ }
+
+ /// onlyReadsMemory - If the specified function is known to only read from
+ /// non-volatile memory (or not access memory at all), return true. For use
+ /// when the call site is not known.
+ ///
+ bool onlyReadsMemory(const Function *F) {
+ return onlyReadsMemory(getModRefBehavior(F));
+ }
+
+ /// onlyReadsMemory - Return true if functions with the specified behavior are
+ /// known to only read from non-volatile memory (or not access memory at all).
+ ///
+ static bool onlyReadsMemory(ModRefBehavior MRB) {
+ return !(MRB & Mod);
+ }
+
+ /// onlyAccessesArgPointees - Return true if functions with the specified
+ /// behavior are known to read and write at most from objects pointed to by
+ /// their pointer-typed arguments (with arbitrary offsets).
+ ///
+ static bool onlyAccessesArgPointees(ModRefBehavior MRB) {
+ return !(MRB & Anywhere & ~ArgumentPointees);
+ }
+
+ /// doesAccessArgPointees - Return true if functions with the specified
+ /// behavior are known to potentially read or write from objects pointed
+ /// to be their pointer-typed arguments (with arbitrary offsets).
+ ///
+ static bool doesAccessArgPointees(ModRefBehavior MRB) {
+ return (MRB & ModRef) && (MRB & ArgumentPointees);
+ }
+
+ /// getModRefInfo - Return information about whether or not an instruction may
+ /// read or write the specified memory location. An instruction
+ /// that doesn't read or write memory may be trivially LICM'd for example.
+ ModRefResult getModRefInfo(const Instruction *I,
+ const Location &Loc) {
+ switch (I->getOpcode()) {
+ case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
+ case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
+ case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc);
+ case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc);
+ case Instruction::AtomicCmpXchg:
+ return getModRefInfo((const AtomicCmpXchgInst*)I, Loc);
+ case Instruction::AtomicRMW:
+ return getModRefInfo((const AtomicRMWInst*)I, Loc);
+ case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
+ case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
+ default: return NoModRef;
+ }
+ }
+
+ /// getModRefInfo - A convenience wrapper.
+ ModRefResult getModRefInfo(const Instruction *I,
+ const Value *P, uint64_t Size) {
+ return getModRefInfo(I, Location(P, Size));
+ }
+
+ /// getModRefInfo (for call sites) - Return whether information about whether
+ /// a particular call site modifies or reads the specified memory location.
+ virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
+ const Location &Loc);
+
+ /// getModRefInfo (for call sites) - A convenience wrapper.
+ ModRefResult getModRefInfo(ImmutableCallSite CS,
+ const Value *P, uint64_t Size) {
+ return getModRefInfo(CS, Location(P, Size));
+ }
+
+ /// getModRefInfo (for calls) - Return whether 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);
+ }
+
+ /// getModRefInfo (for calls) - A convenience wrapper.
+ ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) {
+ return getModRefInfo(C, Location(P, Size));
+ }
+
+ /// getModRefInfo (for invokes) - Return whether information about whether
+ /// a particular invoke modifies or reads the specified memory location.
+ ModRefResult getModRefInfo(const InvokeInst *I,
+ const Location &Loc) {
+ return getModRefInfo(ImmutableCallSite(I), Loc);
+ }
+
+ /// getModRefInfo (for invokes) - A convenience wrapper.
+ ModRefResult getModRefInfo(const InvokeInst *I,
+ const Value *P, uint64_t Size) {
+ return getModRefInfo(I, Location(P, Size));
+ }
+
+ /// getModRefInfo (for loads) - Return whether information about whether
+ /// a particular load modifies or reads the specified memory location.
+ ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
+
+ /// getModRefInfo (for loads) - A convenience wrapper.
+ ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) {
+ return getModRefInfo(L, Location(P, Size));
+ }
+
+ /// getModRefInfo (for stores) - Return whether information about whether
+ /// a particular store modifies or reads the specified memory location.
+ ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
+
+ /// getModRefInfo (for stores) - A convenience wrapper.
+ ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
+ return getModRefInfo(S, Location(P, Size));
+ }
+
+ /// getModRefInfo (for fences) - Return whether 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
+ // Loc is a alloca that doesn't escape.)
+ return ModRef;
+ }
+
+ /// getModRefInfo (for fences) - A convenience wrapper.
+ ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){
+ return getModRefInfo(S, Location(P, Size));
+ }
+
+ /// getModRefInfo (for cmpxchges) - Return whether information about whether
+ /// a particular cmpxchg modifies or reads the specified memory location.
+ ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
+
+ /// getModRefInfo (for cmpxchges) - A convenience wrapper.
+ ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX,
+ const Value *P, unsigned Size) {
+ return getModRefInfo(CX, Location(P, Size));
+ }
+
+ /// getModRefInfo (for atomicrmws) - Return whether information about whether
+ /// a particular atomicrmw modifies or reads the specified memory location.
+ ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
+
+ /// getModRefInfo (for atomicrmws) - A convenience wrapper.
+ ModRefResult getModRefInfo(const AtomicRMWInst *RMW,
+ const Value *P, unsigned Size) {
+ return getModRefInfo(RMW, Location(P, Size));
+ }
+
+ /// getModRefInfo (for va_args) - Return whether information about whether
+ /// a particular va_arg modifies or reads the specified memory location.
+ ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
+
+ /// getModRefInfo (for va_args) - A convenience wrapper.
+ ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
+ return getModRefInfo(I, Location(P, Size));
+ }
+
+ /// getModRefInfo - Return information about whether two call sites may refer
+ /// to the same set of memory locations. See
+ /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
+ /// for details.
+ virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2);
+
+ //===--------------------------------------------------------------------===//
+ /// Higher level methods for querying mod/ref information.
+ ///
+
+ /// canBasicBlockModify - Return true if it is possible for execution of the
+ /// specified basic block to modify the value pointed to by Ptr.
+ bool canBasicBlockModify(const BasicBlock &BB, const Location &Loc);
+
+ /// canBasicBlockModify - A convenience wrapper.
+ bool canBasicBlockModify(const BasicBlock &BB, const Value *P, uint64_t Size){
+ return canBasicBlockModify(BB, Location(P, Size));
+ }
+
+ /// canInstructionRangeModify - Return true if it is possible for the
+ /// execution of the specified instructions to modify the value pointed to by
+ /// Ptr. The instructions to consider are all of the instructions in the
+ /// range of [I1,I2] INCLUSIVE. I1 and I2 must be in the same basic block.
+ bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
+ const Location &Loc);
+
+ /// canInstructionRangeModify - A convenience wrapper.
+ bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
+ const Value *Ptr, uint64_t Size) {
+ return canInstructionRangeModify(I1, I2, Location(Ptr, Size));
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// Methods that clients should call when they transform the program to allow
+ /// alias analyses to update their internal data structures. Note that these
+ /// methods may be called on any instruction, regardless of whether or not
+ /// they have pointer-analysis implications.
+ ///
+
+ /// deleteValue - This method should be called whenever an LLVM Value is
+ /// deleted from the program, for example when an instruction is found to be
+ /// redundant and is eliminated.
+ ///
+ virtual void deleteValue(Value *V);
+
+ /// copyValue - This method should be used whenever a preexisting value in the
+ /// program is copied or cloned, introducing a new value. Note that analysis
+ /// implementations should tolerate clients that use this method to introduce
+ /// the same value multiple times: if the analysis already knows about a
+ /// value, it should ignore the request.
+ ///
+ virtual void copyValue(Value *From, Value *To);
+
+ /// addEscapingUse - This method should be used whenever an escaping use is
+ /// added to a pointer value. Analysis implementations may either return
+ /// conservative responses for that value in the future, or may recompute
+ /// some or all internal state to continue providing precise responses.
+ ///
+ /// Escaping uses are considered by anything _except_ the following:
+ /// - GEPs or bitcasts of the pointer
+ /// - Loads through the pointer
+ /// - Stores through (but not of) the pointer
+ virtual void addEscapingUse(Use &U);
+
+ /// replaceWithNewValue - This method is the obvious combination of the two
+ /// above, and it provided as a helper to simplify client code.
+ ///
+ void replaceWithNewValue(Value *Old, Value *New) {
+ copyValue(Old, New);
+ deleteValue(Old);
+ }
+};
+
+// Specialize DenseMapInfo for Location.
+template<>
+struct DenseMapInfo<AliasAnalysis::Location> {
+ static inline AliasAnalysis::Location getEmptyKey() {
+ return
+ AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(),
+ 0, 0);
+ }
+ static inline AliasAnalysis::Location getTombstoneKey() {
+ return
+ AliasAnalysis::Location(DenseMapInfo<const Value *>::getTombstoneKey(),
+ 0, 0);
+ }
+ static unsigned getHashValue(const AliasAnalysis::Location &Val) {
+ return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
+ DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
+ DenseMapInfo<const MDNode *>::getHashValue(Val.TBAATag);
+ }
+ static bool isEqual(const AliasAnalysis::Location &LHS,
+ const AliasAnalysis::Location &RHS) {
+ return LHS.Ptr == RHS.Ptr &&
+ LHS.Size == RHS.Size &&
+ LHS.TBAATag == RHS.TBAATag;
+ }
+};
+
+/// isNoAliasCall - Return true if this pointer is returned by a noalias
+/// function.
+bool isNoAliasCall(const Value *V);
+
+/// isIdentifiedObject - Return true if this pointer refers to a distinct and
+/// identifiable object. This returns true for:
+/// Global Variables and Functions (but not Global Aliases)
+/// Allocas and Mallocs
+/// ByVal and NoAlias Arguments
+/// NoAlias returns
+///
+bool isIdentifiedObject(const Value *V);
+
+/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
+/// its definition. This returns true for allocas, non-extern-weak globals and
+/// byval arguments.
+bool isKnownNonNull(const Value *V);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h b/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h
new file mode 100644
index 000000000000..95626d624a13
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/AliasSetTracker.h
@@ -0,0 +1,439 @@
+//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- 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 two classes: AliasSetTracker and AliasSet. These interface
+// are used to classify a collection of pointer references into a maximal number
+// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
+// object refers to memory disjoint from the other sets.
+//
+//===----------------------------------------------------------------------===//
+
+#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 <vector>
+
+namespace llvm {
+
+class AliasAnalysis;
+class LoadInst;
+class StoreInst;
+class VAArgInst;
+class AliasSetTracker;
+class AliasSet;
+
+class AliasSet : public ilist_node<AliasSet> {
+ friend class AliasSetTracker;
+
+ class PointerRec {
+ Value *Val; // The pointer this record corresponds to.
+ PointerRec **PrevInList, *NextInList;
+ AliasSet *AS;
+ uint64_t Size;
+ const MDNode *TBAAInfo;
+ public:
+ PointerRec(Value *V)
+ : Val(V), PrevInList(0), NextInList(0), AS(0), Size(0),
+ TBAAInfo(DenseMapInfo<const MDNode *>::getEmptyKey()) {}
+
+ Value *getValue() const { return Val; }
+
+ PointerRec *getNext() const { return NextInList; }
+ bool hasAliasSet() const { return AS != 0; }
+
+ PointerRec** setPrevInList(PointerRec **PIL) {
+ PrevInList = PIL;
+ return &NextInList;
+ }
+
+ void updateSizeAndTBAAInfo(uint64_t NewSize, const MDNode *NewTBAAInfo) {
+ if (NewSize > Size) Size = NewSize;
+
+ if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey())
+ // We don't have a TBAAInfo yet. Set it to NewTBAAInfo.
+ TBAAInfo = NewTBAAInfo;
+ else if (TBAAInfo != NewTBAAInfo)
+ // NewTBAAInfo conflicts with TBAAInfo.
+ TBAAInfo = DenseMapInfo<const MDNode *>::getTombstoneKey();
+ }
+
+ uint64_t getSize() const { return Size; }
+
+ /// getTBAAInfo - Return the TBAAInfo, or null if there is no
+ /// information or conflicting information.
+ const MDNode *getTBAAInfo() const {
+ // If we have missing or conflicting TBAAInfo, return null.
+ if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey() ||
+ TBAAInfo == DenseMapInfo<const MDNode *>::getTombstoneKey())
+ return 0;
+ return TBAAInfo;
+ }
+
+ AliasSet *getAliasSet(AliasSetTracker &AST) {
+ assert(AS && "No AliasSet yet!");
+ if (AS->Forward) {
+ AliasSet *OldAS = AS;
+ AS = OldAS->getForwardedTarget(AST);
+ AS->addRef();
+ OldAS->dropRef(AST);
+ }
+ return AS;
+ }
+
+ void setAliasSet(AliasSet *as) {
+ assert(AS == 0 && "Already have an alias set!");
+ AS = as;
+ }
+
+ void eraseFromList() {
+ if (NextInList) NextInList->PrevInList = PrevInList;
+ *PrevInList = NextInList;
+ if (AS->PtrListEnd == &NextInList) {
+ AS->PtrListEnd = PrevInList;
+ assert(*AS->PtrListEnd == 0 && "List not terminated right!");
+ }
+ delete this;
+ }
+ };
+
+ 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;
+
+ // RefCount - Number of nodes pointing to this AliasSet plus the number of
+ // AliasSets forwarding to it.
+ unsigned RefCount : 28;
+
+ /// AccessType - Keep track of whether this alias set merely refers to the
+ /// locations of memory, whether it modifies the memory, or whether it does
+ /// both. The lattice goes from "NoModRef" to either Refs or Mods, then to
+ /// ModRef as necessary.
+ ///
+ enum AccessType {
+ NoModRef = 0, Refs = 1, // Ref = bit 1
+ Mods = 2, ModRef = 3 // Mod = bit 2
+ };
+ unsigned AccessTy : 2;
+
+ /// AliasType - Keep track the relationships between the pointers in the set.
+ /// Lattice goes from MustAlias to MayAlias.
+ ///
+ enum AliasType {
+ MustAlias = 0, MayAlias = 1
+ };
+ unsigned AliasTy : 1;
+
+ // Volatile - True if this alias set contains volatile loads or stores.
+ bool Volatile : 1;
+
+ void addRef() { ++RefCount; }
+ void dropRef(AliasSetTracker &AST) {
+ assert(RefCount >= 1 && "Invalid reference count detected!");
+ if (--RefCount == 0)
+ removeFromTracker(AST);
+ }
+
+ Instruction *getUnknownInst(unsigned i) const {
+ assert(i < UnknownInsts.size());
+ return UnknownInsts[i];
+ }
+
+public:
+ /// Accessors...
+ bool isRef() const { return AccessTy & Refs; }
+ bool isMod() const { return AccessTy & Mods; }
+ bool isMustAlias() const { return AliasTy == MustAlias; }
+ bool isMayAlias() const { return AliasTy == MayAlias; }
+
+ // isVolatile - Return true if this alias set contains volatile loads or
+ // stores.
+ bool isVolatile() const { return Volatile; }
+
+ /// isForwardingAliasSet - Return true if this alias set should be ignored as
+ /// part of the AliasSetTracker object.
+ bool isForwardingAliasSet() const { return Forward; }
+
+ /// mergeSetIn - Merge the specified alias set into this alias set...
+ ///
+ void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
+
+ // Alias Set iteration - Allow access to all of the pointer which are part of
+ // this alias set...
+ class iterator;
+ iterator begin() const { return iterator(PtrList); }
+ iterator end() const { return iterator(); }
+ bool empty() const { return PtrList == 0; }
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+ /// Define an iterator for alias sets... this is just a forward iterator.
+ class iterator : public std::iterator<std::forward_iterator_tag,
+ PointerRec, ptrdiff_t> {
+ PointerRec *CurNode;
+ public:
+ explicit iterator(PointerRec *CN = 0) : CurNode(CN) {}
+
+ bool operator==(const iterator& x) const {
+ return CurNode == x.CurNode;
+ }
+ bool operator!=(const iterator& x) const { return !operator==(x); }
+
+ const iterator &operator=(const iterator &I) {
+ CurNode = I.CurNode;
+ return *this;
+ }
+
+ value_type &operator*() const {
+ assert(CurNode && "Dereferencing AliasSet.end()!");
+ return *CurNode;
+ }
+ value_type *operator->() const { return &operator*(); }
+
+ Value *getPointer() const { return CurNode->getValue(); }
+ uint64_t getSize() const { return CurNode->getSize(); }
+ const MDNode *getTBAAInfo() const { return CurNode->getTBAAInfo(); }
+
+ iterator& operator++() { // Preincrement
+ assert(CurNode && "Advancing past AliasSet.end()!");
+ CurNode = CurNode->getNext();
+ return *this;
+ }
+ iterator operator++(int) { // Postincrement
+ iterator tmp = *this; ++*this; return tmp;
+ }
+ };
+
+private:
+ // Can only be created by AliasSetTracker. Also, ilist creates one
+ // to serve as a sentinel.
+ friend struct ilist_sentinel_traits<AliasSet>;
+ AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
+ AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
+ }
+
+ AliasSet(const AliasSet &AS); // do not implement
+ void operator=(const AliasSet &AS); // do not implement
+
+ PointerRec *getSomePointer() const {
+ return PtrList;
+ }
+
+ /// getForwardedTarget - Return the real alias set this represents. If this
+ /// has been merged with another set and is forwarding, return the ultimate
+ /// destination set. This also implements the union-find collapsing as well.
+ AliasSet *getForwardedTarget(AliasSetTracker &AST) {
+ if (!Forward) return this;
+
+ AliasSet *Dest = Forward->getForwardedTarget(AST);
+ if (Dest != Forward) {
+ Dest->addRef();
+ Forward->dropRef(AST);
+ Forward = Dest;
+ }
+ return Dest;
+ }
+
+ void removeFromTracker(AliasSetTracker &AST);
+
+ void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
+ const MDNode *TBAAInfo,
+ bool KnownMustAlias = false);
+ void addUnknownInst(Instruction *I, AliasAnalysis &AA);
+ void removeUnknownInst(Instruction *I) {
+ for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
+ if (UnknownInsts[i] == I) {
+ UnknownInsts[i] = UnknownInsts.back();
+ UnknownInsts.pop_back();
+ --i; --e; // Revisit the moved entry.
+ }
+ }
+ void setVolatile() { Volatile = true; }
+
+public:
+ /// aliasesPointer - Return true if the specified pointer "may" (or must)
+ /// alias one of the members in the set.
+ ///
+ bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
+ AliasAnalysis &AA) const;
+ bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
+ AS.print(OS);
+ return OS;
+}
+
+
+class AliasSetTracker {
+ /// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be
+ /// notified whenever a Value is deleted.
+ class ASTCallbackVH : public CallbackVH {
+ AliasSetTracker *AST;
+ virtual void deleted();
+ virtual void allUsesReplacedWith(Value *);
+ public:
+ ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
+ ASTCallbackVH &operator=(Value *V);
+ };
+ /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
+ /// compare and hash the value handle.
+ struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
+
+ AliasAnalysis &AA;
+ ilist<AliasSet> AliasSets;
+
+ typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*,
+ ASTCallbackVHDenseMapInfo>
+ PointerMapType;
+
+ // Map from pointers to their node
+ PointerMapType PointerMap;
+
+public:
+ /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
+ /// the specified alias analysis object to disambiguate load and store
+ /// addresses.
+ explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
+ ~AliasSetTracker() { clear(); }
+
+ /// add methods - These methods are used to add different types of
+ /// instructions to the alias sets. Adding a new instruction can result in
+ /// one of three actions happening:
+ ///
+ /// 1. If the instruction doesn't alias any other sets, create a new set.
+ /// 2. If the instruction aliases exactly one set, add it to the set
+ /// 3. If the instruction aliases multiple sets, merge the sets, and add
+ /// the instruction to the result.
+ ///
+ /// These methods return true if inserting the instruction resulted in the
+ /// addition of a new alias set (i.e., the pointer did not alias anything).
+ ///
+ bool add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo); // Add a location
+ bool add(LoadInst *LI);
+ bool add(StoreInst *SI);
+ bool add(VAArgInst *VAAI);
+ bool add(Instruction *I); // Dispatch to one of the other add methods...
+ void add(BasicBlock &BB); // Add all instructions in basic block
+ void add(const AliasSetTracker &AST); // Add alias relations from another AST
+ bool addUnknown(Instruction *I);
+
+ /// remove methods - These methods are used to remove all entries that might
+ /// be aliased by the specified instruction. These methods return true if any
+ /// alias sets were eliminated.
+ // Remove a location
+ bool remove(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo);
+ bool remove(LoadInst *LI);
+ bool remove(StoreInst *SI);
+ bool remove(VAArgInst *VAAI);
+ bool remove(Instruction *I);
+ void remove(AliasSet &AS);
+ bool removeUnknown(Instruction *I);
+
+ void clear();
+
+ /// getAliasSets - Return the alias sets that are active.
+ ///
+ const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
+
+ /// getAliasSetForPointer - Return the alias set that the specified pointer
+ /// lives in. If the New argument is non-null, this method sets the value to
+ /// true if a new alias set is created to contain the pointer (because the
+ /// pointer didn't alias anything).
+ AliasSet &getAliasSetForPointer(Value *P, uint64_t Size,
+ const MDNode *TBAAInfo,
+ bool *New = 0);
+
+ /// getAliasSetForPointerIfExists - Return the alias set containing the
+ /// location specified if one exists, otherwise return null.
+ AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size,
+ const MDNode *TBAAInfo) {
+ return findAliasSetForPointer(P, Size, TBAAInfo);
+ }
+
+ /// containsPointer - Return true if the specified location is represented by
+ /// this alias set, false otherwise. This does not modify the AST object or
+ /// alias sets.
+ bool containsPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo) const;
+
+ /// getAliasAnalysis - Return the underlying alias analysis object used by
+ /// this tracker.
+ AliasAnalysis &getAliasAnalysis() const { return AA; }
+
+ /// deleteValue method - This method is used to remove a pointer value from
+ /// the AliasSetTracker entirely. It should be used when an instruction is
+ /// deleted from the program to update the AST. If you don't use this, you
+ /// would have dangling pointers to deleted instructions.
+ ///
+ void deleteValue(Value *PtrVal);
+
+ /// copyValue - This method should be used whenever a preexisting value in the
+ /// program is copied or cloned, introducing a new value. Note that it is ok
+ /// for clients that use this method to introduce the same value multiple
+ /// times: if the tracker already knows about a value, it will ignore the
+ /// request.
+ ///
+ void copyValue(Value *From, Value *To);
+
+
+ typedef ilist<AliasSet>::iterator iterator;
+ typedef ilist<AliasSet>::const_iterator const_iterator;
+
+ const_iterator begin() const { return AliasSets.begin(); }
+ const_iterator end() const { return AliasSets.end(); }
+
+ iterator begin() { return AliasSets.begin(); }
+ iterator end() { return AliasSets.end(); }
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+private:
+ friend class AliasSet;
+ void removeAliasSet(AliasSet *AS);
+
+ // getEntryFor - Just like operator[] on the map, except that it creates an
+ // entry for the pointer if it doesn't already exist.
+ AliasSet::PointerRec &getEntryFor(Value *V) {
+ AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
+ if (Entry == 0)
+ Entry = new AliasSet::PointerRec(V);
+ return *Entry;
+ }
+
+ AliasSet &addPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo,
+ AliasSet::AccessType E,
+ bool &NewSet) {
+ NewSet = false;
+ AliasSet &AS = getAliasSetForPointer(P, Size, TBAAInfo, &NewSet);
+ AS.AccessTy |= E;
+ return AS;
+ }
+ AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
+ const MDNode *TBAAInfo);
+
+ AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
+ AST.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h b/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h
new file mode 100644
index 000000000000..6f2ccfb19901
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -0,0 +1,342 @@
+//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared implementation of BlockFrequency for IR and Machine Instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/BlockFrequency.h"
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+#include <string>
+
+namespace llvm {
+
+
+class BlockFrequencyInfo;
+class MachineBlockFrequencyInfo;
+
+/// BlockFrequencyImpl implements block frequency algorithm for IR and
+/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
+/// for the entry block and then propagates frequencies using branch weights
+/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
+/// algorithm can find "backedges" by itself.
+template<class BlockT, class FunctionT, class BlockProbInfoT>
+class BlockFrequencyImpl {
+
+ DenseMap<const BlockT *, BlockFrequency> Freqs;
+
+ BlockProbInfoT *BPI;
+
+ FunctionT *Fn;
+
+ typedef GraphTraits< Inverse<BlockT *> > GT;
+
+ const uint32_t EntryFreq;
+
+ std::string getBlockName(BasicBlock *BB) const {
+ return BB->getName().str();
+ }
+
+ std::string getBlockName(MachineBasicBlock *MBB) const {
+ std::string str;
+ raw_string_ostream ss(str);
+ ss << "BB#" << MBB->getNumber();
+
+ if (const BasicBlock *BB = MBB->getBasicBlock())
+ ss << " derived from LLVM BB " << BB->getName();
+
+ return ss.str();
+ }
+
+ void setBlockFreq(BlockT *BB, BlockFrequency Freq) {
+ Freqs[BB] = Freq;
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
+ }
+
+ /// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
+ /// edge probability.
+ BlockFrequency getEdgeFreq(BlockT *Src, BlockT *Dst) const {
+ BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
+ return getBlockFreq(Src) * Prob;
+ }
+
+ /// incBlockFreq - Increase BB block frequency by FREQ.
+ ///
+ void incBlockFreq(BlockT *BB, BlockFrequency Freq) {
+ Freqs[BB] += Freq;
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
+ << " --> " << Freqs[BB] << "\n");
+ }
+
+ /// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
+ ///
+ void divBlockFreq(BlockT *BB, BranchProbability Prob) {
+ uint64_t N = Prob.getNumerator();
+ assert(N && "Illegal division by zero!");
+ uint64_t D = Prob.getDenominator();
+ uint64_t Freq = (Freqs[BB].getFrequency() * D) / N;
+
+ // Should we assert it?
+ if (Freq > UINT32_MAX)
+ Freq = UINT32_MAX;
+
+ Freqs[BB] = BlockFrequency(Freq);
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
+ << ") --> " << Freqs[BB] << "\n");
+ }
+
+ // All blocks in postorder.
+ std::vector<BlockT *> POT;
+
+ // Map Block -> Position in reverse-postorder list.
+ DenseMap<BlockT *, unsigned> RPO;
+
+ // Cycle Probability for each bloch.
+ DenseMap<BlockT *, uint32_t> CycleProb;
+
+ // (reverse-)postorder traversal iterators.
+ typedef typename std::vector<BlockT *>::iterator pot_iterator;
+ typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator;
+
+ pot_iterator pot_begin() { return POT.begin(); }
+ pot_iterator pot_end() { return POT.end(); }
+
+ rpot_iterator rpot_begin() { return POT.rbegin(); }
+ rpot_iterator rpot_end() { return POT.rend(); }
+
+ rpot_iterator rpot_at(BlockT *BB) {
+ rpot_iterator I = rpot_begin();
+ unsigned idx = RPO[BB];
+ assert(idx);
+ std::advance(I, idx - 1);
+
+ assert(*I == BB);
+ return I;
+ }
+
+
+ /// isReachable - Returns if BB block is reachable from the entry.
+ ///
+ bool isReachable(BlockT *BB) {
+ return RPO.count(BB);
+ }
+
+ /// isBackedge - Return if edge Src -> Dst is a backedge.
+ ///
+ bool isBackedge(BlockT *Src, BlockT *Dst) {
+ assert(isReachable(Src));
+ assert(isReachable(Dst));
+
+ unsigned a = RPO[Src];
+ unsigned b = RPO[Dst];
+
+ return a >= b;
+ }
+
+ /// getSingleBlockPred - return single BB block predecessor or NULL if
+ /// BB has none or more predecessors.
+ BlockT *getSingleBlockPred(BlockT *BB) {
+ typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
+
+ if (PI == PE)
+ return 0;
+
+ BlockT *Pred = *PI;
+
+ ++PI;
+ if (PI != PE)
+ return 0;
+
+ return Pred;
+ }
+
+ void doBlock(BlockT *BB, BlockT *LoopHead,
+ SmallPtrSet<BlockT *, 8> &BlocksInLoop) {
+
+ DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n");
+ setBlockFreq(BB, 0);
+
+ if (BB == LoopHead) {
+ setBlockFreq(BB, EntryFreq);
+ return;
+ }
+
+ if(BlockT *Pred = getSingleBlockPred(BB)) {
+ if (BlocksInLoop.count(Pred))
+ setBlockFreq(BB, getEdgeFreq(Pred, BB));
+ // TODO: else? irreducible, ignore it for now.
+ return;
+ }
+
+ bool isInLoop = false;
+ bool isLoopHead = false;
+
+ for (typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
+ PI != PE; ++PI) {
+ BlockT *Pred = *PI;
+
+ if (isReachable(Pred) && isBackedge(Pred, BB)) {
+ isLoopHead = true;
+ } else if (BlocksInLoop.count(Pred)) {
+ incBlockFreq(BB, getEdgeFreq(Pred, BB));
+ isInLoop = true;
+ }
+ // TODO: else? irreducible.
+ }
+
+ if (!isInLoop)
+ return;
+
+ if (!isLoopHead)
+ return;
+
+ assert(EntryFreq >= CycleProb[BB]);
+ uint32_t CProb = CycleProb[BB];
+ uint32_t Numerator = EntryFreq - CProb ? EntryFreq - CProb : 1;
+ divBlockFreq(BB, BranchProbability(Numerator, EntryFreq));
+ }
+
+ /// doLoop - Propagate block frequency down throught the loop.
+ void doLoop(BlockT *Head, BlockT *Tail) {
+ DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
+ << getBlockName(Tail) << ")\n");
+
+ SmallPtrSet<BlockT *, 8> BlocksInLoop;
+
+ for (rpot_iterator I = rpot_at(Head), E = rpot_at(Tail); ; ++I) {
+ BlockT *BB = *I;
+ doBlock(BB, Head, BlocksInLoop);
+
+ BlocksInLoop.insert(BB);
+ if (I == E)
+ break;
+ }
+
+ // Compute loop's cyclic probability using backedges probabilities.
+ for (typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
+ PI != PE; ++PI) {
+ BlockT *Pred = *PI;
+ assert(Pred);
+ if (isReachable(Pred) && isBackedge(Pred, Head)) {
+ uint64_t N = getEdgeFreq(Pred, Head).getFrequency();
+ uint64_t D = getBlockFreq(Head).getFrequency();
+ assert(N <= EntryFreq && "Backedge frequency must be <= EntryFreq!");
+ uint64_t Res = (N * EntryFreq) / D;
+
+ assert(Res <= UINT32_MAX);
+ CycleProb[Head] += (uint32_t) Res;
+ DEBUG(dbgs() << " CycleProb[" << getBlockName(Head) << "] += " << Res
+ << " --> " << CycleProb[Head] << "\n");
+ }
+ }
+ }
+
+ friend class BlockFrequencyInfo;
+ friend class MachineBlockFrequencyInfo;
+
+ BlockFrequencyImpl() : EntryFreq(BlockFrequency::getEntryFrequency()) { }
+
+ void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
+ Fn = fn;
+ BPI = bpi;
+
+ // Clear everything.
+ RPO.clear();
+ POT.clear();
+ CycleProb.clear();
+ Freqs.clear();
+
+ BlockT *EntryBlock = fn->begin();
+
+ copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
+
+ unsigned RPOidx = 0;
+ for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
+ BlockT *BB = *I;
+ RPO[BB] = ++RPOidx;
+ DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n");
+ }
+
+ // Travel over all blocks in postorder.
+ for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) {
+ BlockT *BB = *I;
+ BlockT *LastTail = 0;
+ DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n");
+
+ for (typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
+ PI != PE; ++PI) {
+
+ BlockT *Pred = *PI;
+ if (isReachable(Pred) && isBackedge(Pred, BB)
+ && (!LastTail || RPO[Pred] > RPO[LastTail]))
+ LastTail = Pred;
+ }
+
+ if (LastTail)
+ doLoop(BB, LastTail);
+ }
+
+ // At the end assume the whole function as a loop, and travel over it once
+ // again.
+ doLoop(*(rpot_begin()), *(pot_begin()));
+ }
+
+public:
+ /// getBlockFreq - Return block frequency. Return 0 if we don't have it.
+ BlockFrequency getBlockFreq(const BlockT *BB) const {
+ typename DenseMap<const BlockT *, BlockFrequency>::const_iterator
+ I = Freqs.find(BB);
+ if (I != Freqs.end())
+ return I->second;
+ return 0;
+ }
+
+ void print(raw_ostream &OS) const {
+ OS << "\n\n---- Block Freqs ----\n";
+ for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) {
+ BlockT *BB = I++;
+ OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n";
+
+ for (typename GraphTraits<BlockT *>::ChildIteratorType
+ SI = GraphTraits<BlockT *>::child_begin(BB),
+ SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) {
+ BlockT *Succ = *SI;
+ OS << " " << getBlockName(BB) << " -> " << getBlockName(Succ)
+ << " = " << getEdgeFreq(BB, Succ) << "\n";
+ }
+ }
+ }
+
+ void dump() const {
+ print(dbgs());
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
new file mode 100644
index 000000000000..fcab90677a48
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -0,0 +1,55 @@
+//========-------- BlockFrequencyInfo.h - Block Frequency Analysis -------========//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Loops should be simplified before this analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
+#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/BlockFrequency.h"
+#include <climits>
+
+namespace llvm {
+
+class BranchProbabilityInfo;
+template<class BlockT, class FunctionT, class BranchProbInfoT>
+class BlockFrequencyImpl;
+
+/// BlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
+/// IR basic block frequencies.
+class BlockFrequencyInfo : public FunctionPass {
+
+ BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
+
+public:
+ static char ID;
+
+ BlockFrequencyInfo();
+
+ ~BlockFrequencyInfo();
+
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ bool runOnFunction(Function &F);
+ void print(raw_ostream &O, const Module *M) const;
+
+ /// getblockFreq - Return block frequency. Return 0 if we don't have the
+ /// information. Please note that initial frequency is equal to 1024. It means
+ /// that we should not rely on the value itself, but only on the comparison to
+ /// the other block frequencies. We do this to avoid using of floating points.
+ ///
+ BlockFrequency getBlockFreq(const BasicBlock *BB) const;
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
new file mode 100644
index 000000000000..2ced7967ed5b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -0,0 +1,129 @@
+//===--- BranchProbabilityInfo.h - Branch Probability Analysis --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to evaluate branch probabilties.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/BranchProbability.h"
+
+namespace llvm {
+class LoopInfo;
+class raw_ostream;
+
+/// \brief Analysis pass providing branch probability information.
+///
+/// This is a function analysis pass which provides information on the relative
+/// probabilities of each "edge" in the function's CFG where such an edge is
+/// defined by a pair of basic blocks. The probability for a given block and
+/// a successor block are always relative to the probabilities of the other
+/// successor blocks. Another way of looking at it is that the probabilities
+/// for a given block B and each of its successors should sum to exactly
+/// one (100%).
+class BranchProbabilityInfo : public FunctionPass {
+public:
+ static char ID;
+
+ BranchProbabilityInfo() : FunctionPass(ID) {
+ initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ bool runOnFunction(Function &F);
+ void print(raw_ostream &OS, const Module *M = 0) const;
+
+ /// \brief Get an edge's probability, relative to other out-edges of the Src.
+ ///
+ /// This routine provides access to the fractional probability between zero
+ /// (0%) and one (100%) of this edge executing, relative to other edges
+ /// leaving the 'Src' block. The returned probability is never zero, and can
+ /// only be one if the source block has only one successor.
+ BranchProbability getEdgeProbability(const BasicBlock *Src,
+ const BasicBlock *Dst) const;
+
+ /// \brief Test if an edge is hot relative to other out-edges of the Src.
+ ///
+ /// Check whether this edge out of the source block is 'hot'. We define hot
+ /// as having a relative probability >= 80%.
+ bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const;
+
+ /// \brief Retrieve the hot successor of a block if one exists.
+ ///
+ /// Given a basic block, look through its successors and if one exists for
+ /// which \see isEdgeHot would return true, return that successor block.
+ BasicBlock *getHotSucc(BasicBlock *BB) const;
+
+ /// \brief Print an edge's probability.
+ ///
+ /// Retrieves an edge's probability similarly to \see getEdgeProbability, but
+ /// then prints that probability to the provided stream. That stream is then
+ /// returned.
+ raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
+ const BasicBlock *Dst) const;
+
+ /// \brief Get the raw edge weight calculated for the block pair.
+ ///
+ /// This returns the raw edge weight. It is guaranteed to fall between 1 and
+ /// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation.
+ /// This interface should be very carefully, and primarily by routines that
+ /// are updating the analysis by later calling setEdgeWeight.
+ uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
+
+ /// \brief Set the raw edge weight for the block pair.
+ ///
+ /// This allows a pass to explicitly set the edge weight for a block. It can
+ /// be used when updating the CFG to update and preserve the branch
+ /// probability information. Read the implementation of how these edge
+ /// weights are calculated carefully before using!
+ void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst,
+ uint32_t Weight);
+
+private:
+ typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
+
+ // Default weight value. Used when we don't have information about the edge.
+ // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
+ // the successors have a weight yet. But it doesn't make sense when providing
+ // weight to an edge that may have siblings with non-zero weights. This can
+ // be handled various ways, but it's probably fine for an edge with unknown
+ // weight to just "inherit" the non-zero weight of an adjacent successor.
+ static const uint32_t DEFAULT_WEIGHT = 16;
+
+ DenseMap<Edge, uint32_t> Weights;
+
+ /// \brief Handle to the LoopInfo analysis.
+ LoopInfo *LI;
+
+ /// \brief Track the last function we run over for printing.
+ Function *LastF;
+
+ /// \brief Track the set of blocks directly succeeded by a returning block.
+ SmallPtrSet<BasicBlock *, 16> PostDominatedByUnreachable;
+
+ /// \brief Get sum of the block successors' weights.
+ uint32_t getSumForBlock(const BasicBlock *BB) const;
+
+ bool calcUnreachableHeuristics(BasicBlock *BB);
+ bool calcMetadataWeights(BasicBlock *BB);
+ bool calcPointerHeuristics(BasicBlock *BB);
+ bool calcLoopBranchHeuristics(BasicBlock *BB);
+ bool calcZeroHeuristics(BasicBlock *BB);
+ bool calcFloatingPointHeuristics(BasicBlock *BB);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/CFGPrinter.h b/contrib/llvm/include/llvm/Analysis/CFGPrinter.h
new file mode 100644
index 000000000000..4704a929acf6
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/CFGPrinter.h
@@ -0,0 +1,114 @@
+//===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines external functions that can be called to explicitly
+// instantiate the CFG printer.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/CFG.h"
+#include "llvm/Support/GraphWriter.h"
+
+namespace llvm {
+template<>
+struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
+
+ DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+
+ static std::string getGraphName(const Function *F) {
+ return "CFG for '" + F->getName().str() + "' function";
+ }
+
+ static std::string getSimpleNodeLabel(const BasicBlock *Node,
+ const Function *) {
+ if (!Node->getName().empty())
+ return Node->getName().str();
+
+ std::string Str;
+ raw_string_ostream OS(Str);
+
+ WriteAsOperand(OS, Node, false);
+ return OS.str();
+ }
+
+ static std::string getCompleteNodeLabel(const BasicBlock *Node,
+ const Function *) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+
+ if (Node->getName().empty()) {
+ WriteAsOperand(OS, Node, false);
+ OS << ":";
+ }
+
+ OS << *Node;
+ std::string OutStr = OS.str();
+ if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
+
+ // Process string output to make it nicer...
+ for (unsigned i = 0; i != OutStr.length(); ++i)
+ if (OutStr[i] == '\n') { // Left justify
+ OutStr[i] = '\\';
+ OutStr.insert(OutStr.begin()+i+1, 'l');
+ } else if (OutStr[i] == ';') { // Delete comments!
+ unsigned Idx = OutStr.find('\n', i+1); // Find end of line
+ OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
+ --i;
+ }
+
+ return OutStr;
+ }
+
+ std::string getNodeLabel(const BasicBlock *Node,
+ const Function *Graph) {
+ if (isSimple())
+ return getSimpleNodeLabel(Node, Graph);
+ else
+ return getCompleteNodeLabel(Node, Graph);
+ }
+
+ static std::string getEdgeSourceLabel(const BasicBlock *Node,
+ succ_const_iterator I) {
+ // Label source of conditional branches with "T" or "F"
+ if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
+ if (BI->isConditional())
+ return (I == succ_begin(Node)) ? "T" : "F";
+
+ // Label source of switch edges with the associated value.
+ if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
+ unsigned SuccNo = I.getSuccessorIndex();
+
+ if (SuccNo == 0) return "def";
+
+ std::string Str;
+ raw_string_ostream OS(Str);
+ SwitchInst::ConstCaseIt Case =
+ SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
+ OS << Case.getCaseValue()->getValue();
+ return OS.str();
+ }
+ return "";
+ }
+};
+} // End llvm namespace
+
+namespace llvm {
+ class FunctionPass;
+ FunctionPass *createCFGPrinterPass ();
+ FunctionPass *createCFGOnlyPrinterPass ();
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/CallGraph.h b/contrib/llvm/include/llvm/Analysis/CallGraph.h
new file mode 100644
index 000000000000..fb77da7b69ea
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/CallGraph.h
@@ -0,0 +1,378 @@
+//===- CallGraph.h - Build a Module's call graph ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This interface is used to build and manipulate a call graph, which is a very
+// useful tool for interprocedural optimization.
+//
+// Every function in a module is represented as a node in the call graph. The
+// callgraph node keeps track of which functions the are called by the function
+// corresponding to the node.
+//
+// A call graph may contain nodes where the function that they correspond to is
+// null. These 'external' nodes are used to represent control flow that is not
+// represented (or analyzable) in the module. In particular, this analysis
+// builds one external node such that:
+// 1. All functions in the module without internal linkage will have edges
+// from this external node, indicating that they could be called by
+// functions outside of the module.
+// 2. All functions whose address is used for something more than a direct
+// call, for example being stored into a memory location will also have an
+// edge from this external node. Since they may be called by an unknown
+// caller later, they must be tracked as such.
+//
+// There is a second external node added for calls that leave this module.
+// Functions have a call edge to the external node iff:
+// 1. The function is external, reflecting the fact that they could call
+// anything without internal linkage or that has its address taken.
+// 2. The function contains an indirect function call.
+//
+// As an extension in the future, there may be multiple nodes with a null
+// function. These will be used when we can prove (through pointer analysis)
+// that an indirect call site can call only a specific set of functions.
+//
+// Because of these properties, the CallGraph captures a conservative superset
+// of all of the caller-callee relationships, which is useful for
+// transformations.
+//
+// The CallGraph class also attempts to figure out what the root of the
+// CallGraph is, which it currently does by looking for a function named 'main'.
+// If no function named 'main' is found, the external node is used as the entry
+// node, reflecting the fact that any function without internal linkage could
+// be called into (which is common for libraries).
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/CallSite.h"
+#include "llvm/Support/ValueHandle.h"
+#include "llvm/Support/IncludeFile.h"
+#include <map>
+
+namespace llvm {
+
+class Function;
+class Module;
+class CallGraphNode;
+
+//===----------------------------------------------------------------------===//
+// CallGraph class definition
+//
+class CallGraph {
+protected:
+ Module *Mod; // The module this call graph represents
+
+ typedef std::map<const Function *, CallGraphNode *> FunctionMapTy;
+ FunctionMapTy FunctionMap; // Map from a function to its node
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+ //===---------------------------------------------------------------------
+ // Accessors.
+ //
+ typedef FunctionMapTy::iterator iterator;
+ typedef FunctionMapTy::const_iterator const_iterator;
+
+ /// getModule - Return the module the call graph corresponds to.
+ ///
+ Module &getModule() const { return *Mod; }
+
+ inline iterator begin() { return FunctionMap.begin(); }
+ inline iterator end() { return FunctionMap.end(); }
+ inline const_iterator begin() const { return FunctionMap.begin(); }
+ inline const_iterator end() const { return FunctionMap.end(); }
+
+ // Subscripting operators, return the call graph node for the provided
+ // function
+ inline const CallGraphNode *operator[](const Function *F) const {
+ const_iterator I = FunctionMap.find(F);
+ assert(I != FunctionMap.end() && "Function not in callgraph!");
+ return I->second;
+ }
+ inline CallGraphNode *operator[](const Function *F) {
+ const_iterator I = FunctionMap.find(F);
+ assert(I != FunctionMap.end() && "Function not in callgraph!");
+ return I->second;
+ }
+
+ /// Returns the CallGraphNode which is used to represent undetermined calls
+ /// into the callgraph. Override this if you want behavioral inheritance.
+ virtual CallGraphNode* getExternalCallingNode() const { return 0; }
+ virtual CallGraphNode* getCallsExternalNode() const { return 0; }
+
+ /// Return the root/main method in the module, or some other root node, such
+ /// as the externalcallingnode. Overload these if you behavioral
+ /// inheritance.
+ virtual CallGraphNode* getRoot() { return 0; }
+ virtual const CallGraphNode* getRoot() const { return 0; }
+
+ //===---------------------------------------------------------------------
+ // Functions to keep a call graph up to date with a function that has been
+ // modified.
+ //
+
+ /// removeFunctionFromModule - Unlink the function from this module, returning
+ /// it. Because this removes the function from the module, the call graph
+ /// node is destroyed. This is only valid if the function does not call any
+ /// other functions (ie, there are no edges in it's CGN). The easiest way to
+ /// do this is to dropAllReferences before calling this.
+ ///
+ Function *removeFunctionFromModule(CallGraphNode *CGN);
+ Function *removeFunctionFromModule(Function *F) {
+ return removeFunctionFromModule((*this)[F]);
+ }
+
+ /// getOrInsertFunction - This method is identical to calling operator[], but
+ /// it will insert a new CallGraphNode for the specified function if one does
+ /// not already exist.
+ CallGraphNode *getOrInsertFunction(const Function *F);
+
+ /// spliceFunction - Replace the function represented by this node by another.
+ /// This does not rescan the body of the function, so it is suitable when
+ /// splicing the body of one function to another while also updating all
+ /// callers from the old function to the new.
+ ///
+ void spliceFunction(const Function *From, const Function *To);
+
+ //===---------------------------------------------------------------------
+ // Pass infrastructure interface glue code.
+ //
+protected:
+ CallGraph() {}
+
+public:
+ virtual ~CallGraph() { destroy(); }
+
+ /// initialize - Call this method before calling other methods,
+ /// re/initializes the state of the CallGraph.
+ ///
+ void initialize(Module &M);
+
+ void print(raw_ostream &o, Module *) const;
+ void dump() const;
+protected:
+ // destroy - Release memory for the call graph
+ virtual void destroy();
+};
+
+//===----------------------------------------------------------------------===//
+// CallGraphNode class definition.
+//
+class CallGraphNode {
+ friend class CallGraph;
+
+ AssertingVH<Function> F;
+
+ // CallRecord - This is a pair of the calling instruction (a call or invoke)
+ // and the callgraph node being called.
+public:
+ typedef std::pair<WeakVH, CallGraphNode*> CallRecord;
+private:
+ std::vector<CallRecord> CalledFunctions;
+
+ /// NumReferences - This is the number of times that this CallGraphNode occurs
+ /// in the CalledFunctions array of this or other CallGraphNodes.
+ unsigned NumReferences;
+
+ CallGraphNode(const CallGraphNode &); // DO NOT IMPLEMENT
+ void operator=(const CallGraphNode &); // DO NOT IMPLEMENT
+
+ void DropRef() { --NumReferences; }
+ void AddRef() { ++NumReferences; }
+public:
+ typedef std::vector<CallRecord> CalledFunctionsVector;
+
+
+ // CallGraphNode ctor - Create a node for the specified function.
+ inline CallGraphNode(Function *f) : F(f), NumReferences(0) {}
+ ~CallGraphNode() {
+ assert(NumReferences == 0 && "Node deleted while references remain");
+ }
+
+ //===---------------------------------------------------------------------
+ // Accessor methods.
+ //
+
+ typedef std::vector<CallRecord>::iterator iterator;
+ typedef std::vector<CallRecord>::const_iterator const_iterator;
+
+ // getFunction - Return the function that this call graph node represents.
+ Function *getFunction() const { return F; }
+
+ inline iterator begin() { return CalledFunctions.begin(); }
+ inline iterator end() { return CalledFunctions.end(); }
+ inline const_iterator begin() const { return CalledFunctions.begin(); }
+ inline const_iterator end() const { return CalledFunctions.end(); }
+ inline bool empty() const { return CalledFunctions.empty(); }
+ inline unsigned size() const { return (unsigned)CalledFunctions.size(); }
+
+ /// getNumReferences - Return the number of other CallGraphNodes in this
+ /// CallGraph that reference this node in their callee list.
+ unsigned getNumReferences() const { return NumReferences; }
+
+ // Subscripting operator - Return the i'th called function.
+ //
+ CallGraphNode *operator[](unsigned i) const {
+ assert(i < CalledFunctions.size() && "Invalid index");
+ return CalledFunctions[i].second;
+ }
+
+ /// dump - Print out this call graph node.
+ ///
+ void dump() const;
+ void print(raw_ostream &OS) const;
+
+ //===---------------------------------------------------------------------
+ // Methods to keep a call graph up to date with a function that has been
+ // modified
+ //
+
+ /// removeAllCalledFunctions - As the name implies, this removes all edges
+ /// from this CallGraphNode to any functions it calls.
+ void removeAllCalledFunctions() {
+ while (!CalledFunctions.empty()) {
+ CalledFunctions.back().second->DropRef();
+ CalledFunctions.pop_back();
+ }
+ }
+
+ /// stealCalledFunctionsFrom - Move all the callee information from N to this
+ /// node.
+ void stealCalledFunctionsFrom(CallGraphNode *N) {
+ assert(CalledFunctions.empty() &&
+ "Cannot steal callsite information if I already have some");
+ std::swap(CalledFunctions, N->CalledFunctions);
+ }
+
+
+ /// addCalledFunction - Add a function to the list of functions called by this
+ /// one.
+ void addCalledFunction(CallSite CS, CallGraphNode *M) {
+ assert(!CS.getInstruction() ||
+ !CS.getCalledFunction() ||
+ !CS.getCalledFunction()->isIntrinsic());
+ CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
+ M->AddRef();
+ }
+
+ void removeCallEdge(iterator I) {
+ I->second->DropRef();
+ *I = CalledFunctions.back();
+ CalledFunctions.pop_back();
+ }
+
+
+ /// removeCallEdgeFor - This method removes the edge in the node for the
+ /// specified call site. Note that this method takes linear time, so it
+ /// should be used sparingly.
+ void removeCallEdgeFor(CallSite CS);
+
+ /// removeAnyCallEdgeTo - This method removes all call edges from this node
+ /// to the specified callee function. This takes more time to execute than
+ /// removeCallEdgeTo, so it should not be used unless necessary.
+ void removeAnyCallEdgeTo(CallGraphNode *Callee);
+
+ /// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite
+ /// from this node to the specified callee function.
+ void removeOneAbstractEdgeTo(CallGraphNode *Callee);
+
+ /// replaceCallEdge - This method replaces the edge in the node for the
+ /// specified call site with a new one. Note that this method takes linear
+ /// time, so it should be used sparingly.
+ void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
+
+ /// allReferencesDropped - This is a special function that should only be
+ /// used by the CallGraph class.
+ void allReferencesDropped() {
+ NumReferences = 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// GraphTraits specializations for call graphs so that they can be treated as
+// graphs by the generic graph algorithms.
+//
+
+// Provide graph traits for tranversing call graphs using standard graph
+// traversals.
+template <> struct GraphTraits<CallGraphNode*> {
+ typedef CallGraphNode NodeType;
+
+ typedef CallGraphNode::CallRecord CGNPairTy;
+ typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode*> CGNDerefFun;
+
+ static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }
+
+ typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+ }
+ static inline ChildIteratorType child_end (NodeType *N) {
+ return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+ }
+
+ static CallGraphNode *CGNDeref(CGNPairTy P) {
+ return P.second;
+ }
+
+};
+
+template <> struct GraphTraits<const CallGraphNode*> {
+ typedef const CallGraphNode NodeType;
+ typedef NodeType::const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const CallGraphNode *CGN) { return CGN; }
+ static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
+ static inline ChildIteratorType child_end (NodeType *N) { return N->end(); }
+};
+
+template<> struct GraphTraits<CallGraph*> : public GraphTraits<CallGraphNode*> {
+ static NodeType *getEntryNode(CallGraph *CGN) {
+ return CGN->getExternalCallingNode(); // Start at the external node!
+ }
+ typedef std::pair<const Function*, CallGraphNode*> PairTy;
+ typedef std::pointer_to_unary_function<PairTy, CallGraphNode&> DerefFun;
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef mapped_iterator<CallGraph::iterator, DerefFun> nodes_iterator;
+ static nodes_iterator nodes_begin(CallGraph *CG) {
+ return map_iterator(CG->begin(), DerefFun(CGdereference));
+ }
+ static nodes_iterator nodes_end (CallGraph *CG) {
+ return map_iterator(CG->end(), DerefFun(CGdereference));
+ }
+
+ static CallGraphNode &CGdereference(PairTy P) {
+ return *P.second;
+ }
+};
+
+template<> struct GraphTraits<const CallGraph*> :
+ public GraphTraits<const CallGraphNode*> {
+ static NodeType *getEntryNode(const CallGraph *CGN) {
+ return CGN->getExternalCallingNode();
+ }
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef CallGraph::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const CallGraph *CG) { return CG->begin(); }
+ static nodes_iterator nodes_end (const CallGraph *CG) { return CG->end(); }
+};
+
+} // End llvm namespace
+
+// Make sure that any clients of this file link in CallGraph.cpp
+FORCE_DEFINING_FILE_TO_BE_LINKED(CallGraph)
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/CaptureTracking.h b/contrib/llvm/include/llvm/Analysis/CaptureTracking.h
new file mode 100644
index 000000000000..9b5e8425ad29
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/CaptureTracking.h
@@ -0,0 +1,63 @@
+//===----- llvm/Analysis/CaptureTracking.h - Pointer capture ----*- 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 routines that help determine which pointers are captured.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/CallSite.h"
+
+namespace llvm {
+ /// PointerMayBeCaptured - Return true if this pointer value may be captured
+ /// by the enclosing function (which is required to exist). This routine can
+ /// be expensive, so consider caching the results. The boolean ReturnCaptures
+ /// specifies whether returning the value (or part of it) from the function
+ /// counts as capturing it or not. The boolean StoreCaptures specified
+ /// whether storing the value (or part of it) into memory anywhere
+ /// automatically counts as capturing it or not.
+ bool PointerMayBeCaptured(const Value *V,
+ bool ReturnCaptures,
+ bool StoreCaptures);
+
+ /// This callback is used in conjunction with PointerMayBeCaptured. In
+ /// addition to the interface here, you'll need to provide your own getters
+ /// to see whether anything was captured.
+ struct CaptureTracker {
+ virtual ~CaptureTracker();
+
+ /// tooManyUses - The depth of traversal has breached a limit. There may be
+ /// capturing instructions that will not be passed into captured().
+ virtual void tooManyUses() = 0;
+
+ /// shouldExplore - This is the use of a value derived from the pointer.
+ /// To prune the search (ie., assume that none of its users could possibly
+ /// capture) return false. To search it, return true.
+ ///
+ /// U->getUser() is always an Instruction.
+ virtual bool shouldExplore(Use *U) = 0;
+
+ /// captured - Information about the pointer was captured by the user of
+ /// use U. Return true to stop the traversal or false to continue looking
+ /// for more capturing instructions.
+ virtual bool captured(Use *U) = 0;
+ };
+
+ /// PointerMayBeCaptured - Visit the value and the values derived from it and
+ /// find values which appear to be capturing the pointer value. This feeds
+ /// results into and is controlled by the CaptureTracker object.
+ void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker);
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/CodeMetrics.h b/contrib/llvm/include/llvm/Analysis/CodeMetrics.h
new file mode 100644
index 000000000000..711607834921
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/CodeMetrics.h
@@ -0,0 +1,93 @@
+//===- CodeMetrics.h - Code cost measurements -------------------*- 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 various weight measurements for code, helping
+// the Inliner and other passes decide whether to duplicate its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CODEMETRICS_H
+#define LLVM_ANALYSIS_CODEMETRICS_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+ class BasicBlock;
+ class Function;
+ class Instruction;
+ class TargetData;
+ class Value;
+
+ /// \brief Check whether an instruction is likely to be "free" when lowered.
+ bool isInstructionFree(const Instruction *I, const TargetData *TD = 0);
+
+ /// \brief Check whether a call will lower to something small.
+ ///
+ /// This tests checks whether calls to this function will lower to something
+ /// significantly cheaper than a traditional call, often a single
+ /// instruction.
+ bool callIsSmall(const Function *F);
+
+ /// \brief Utility to calculate the size and a few similar metrics for a set
+ /// of basic blocks.
+ struct CodeMetrics {
+ /// \brief True if this function contains a call to setjmp or other functions
+ /// with attribute "returns twice" without having the attribute itself.
+ bool exposesReturnsTwice;
+
+ /// \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 calls alloca (in the C sense).
+ bool usesDynamicAlloca;
+
+ /// \brief Number of instructions in the analyzed blocks.
+ unsigned NumInsts;
+
+ /// \brief Number of analyzed blocks.
+ unsigned NumBlocks;
+
+ /// \brief Keeps track of basic block code size estimates.
+ DenseMap<const BasicBlock *, unsigned> NumBBInsts;
+
+ /// \brief Keep track of the number of calls to 'big' functions.
+ unsigned NumCalls;
+
+ /// \brief The number of calls to internal functions with a single caller.
+ ///
+ /// These are likely targets for future inlining, likely exposed by
+ /// interleaved devirtualization.
+ unsigned NumInlineCandidates;
+
+ /// \brief How many instructions produce vector values.
+ ///
+ /// The inliner is more aggressive with inlining vector kernels.
+ unsigned NumVectorInsts;
+
+ /// \brief How many 'ret' instructions the blocks contain.
+ unsigned NumRets;
+
+ CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
+ containsIndirectBr(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);
+
+ /// \brief Add information about a function to the current state.
+ void analyzeFunction(Function *F, const TargetData *TD = 0);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ConstantFolding.h b/contrib/llvm/include/llvm/Analysis/ConstantFolding.h
new file mode 100644
index 000000000000..2fdef5f0836e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ConstantFolding.h
@@ -0,0 +1,102 @@
+//===-- ConstantFolding.h - Fold instructions into constants --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares routines for folding instructions into constants when all
+// operands are constants, for example "sub i32 1, 0" -> "1".
+//
+// 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
+// dependency issues.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CONSTANTFOLDING_H
+#define LLVM_ANALYSIS_CONSTANTFOLDING_H
+
+namespace llvm {
+ class Constant;
+ class ConstantExpr;
+ class Instruction;
+ class TargetData;
+ class TargetLibraryInfo;
+ class Function;
+ class Type;
+ template<typename T>
+ class ArrayRef;
+
+/// ConstantFoldInstruction - Try to constant fold the specified instruction.
+/// If successful, the constant result is returned, if not, null is returned.
+/// 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,
+ const TargetLibraryInfo *TLI = 0);
+
+/// ConstantFoldConstantExpression - Attempt to fold the constant expression
+/// using the specified TargetData. If successful, the constant result is
+/// result is returned, if not, null is returned.
+Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
+ const TargetData *TD = 0,
+ const TargetLibraryInfo *TLI = 0);
+
+/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
+/// specified operands. If successful, the constant result is returned, if not,
+/// null is returned. Note that this function can fail when attempting to
+/// fold instructions like loads and stores, which have no constant expression
+/// form.
+///
+Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
+ ArrayRef<Constant *> Ops,
+ const TargetData *TD = 0,
+ const TargetLibraryInfo *TLI = 0);
+
+/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
+/// instruction (icmp/fcmp) with the specified operands. If it fails, it
+/// returns a constant expression of the specified operands.
+///
+Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
+ Constant *LHS, Constant *RHS,
+ const TargetData *TD = 0,
+ const TargetLibraryInfo *TLI = 0);
+
+/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
+/// instruction with the specified operands and indices. The constant result is
+/// returned if successful; if not, null is returned.
+Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
+ ArrayRef<unsigned> Idxs);
+
+/// 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);
+
+/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
+/// getelementptr constantexpr, return the constant value being addressed by the
+/// constant expression, or null if something is funny and we can't decide.
+Constant *ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE);
+
+/// ConstantFoldLoadThroughGEPIndices - Given a constant and getelementptr
+/// indices (with an *implied* zero pointer index that is not in the list),
+/// return the constant value being addressed by a virtual load, or null if
+/// something is funny and we can't decide.
+Constant *ConstantFoldLoadThroughGEPIndices(Constant *C,
+ ArrayRef<Constant*> Indices);
+
+/// canConstantFoldCallTo - Return true if its even possible to fold a call to
+/// the specified function.
+bool canConstantFoldCallTo(const Function *F);
+
+/// ConstantFoldCall - Attempt to constant fold a call to the specified function
+/// with the specified arguments, returning null if unsuccessful.
+Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
+ const TargetLibraryInfo *TLI = 0);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ConstantsScanner.h b/contrib/llvm/include/llvm/Analysis/ConstantsScanner.h
new file mode 100644
index 000000000000..cdaf68d75a63
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ConstantsScanner.h
@@ -0,0 +1,93 @@
+//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements an iterator to walk through the constants referenced by
+// a method. This is used by the Bitcode & Assembly writers to build constant
+// pools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
+#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
+
+#include "llvm/Support/InstIterator.h"
+
+namespace llvm {
+
+class Constant;
+
+class constant_iterator : public std::iterator<std::forward_iterator_tag,
+ const Constant, ptrdiff_t> {
+ const_inst_iterator InstI; // Method instruction iterator
+ unsigned OpIdx; // Operand index
+
+ typedef constant_iterator _Self;
+
+ inline bool isAtConstant() const {
+ assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
+ "isAtConstant called with invalid arguments!");
+ return isa<Constant>(InstI->getOperand(OpIdx));
+ }
+
+public:
+ inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
+ // Advance to first constant... if we are not already at constant or end
+ if (InstI != inst_end(F) && // InstI is valid?
+ (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
+ operator++();
+ }
+
+ inline constant_iterator(const Function *F, bool) // end ctor
+ : InstI(inst_end(F)), OpIdx(0) {
+ }
+
+ inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
+ InstI == x.InstI; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ assert(isAtConstant() && "Dereferenced an iterator at the end!");
+ return cast<Constant>(InstI->getOperand(OpIdx));
+ }
+ inline pointer operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement implementation
+ ++OpIdx;
+ do {
+ unsigned NumOperands = InstI->getNumOperands();
+ while (OpIdx < NumOperands && !isAtConstant()) {
+ ++OpIdx;
+ }
+
+ if (OpIdx < NumOperands) return *this; // Found a constant!
+ ++InstI;
+ OpIdx = 0;
+ } while (!InstI.atEnd());
+
+ return *this; // At the end of the method
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ inline bool atEnd() const { return InstI.atEnd(); }
+};
+
+inline constant_iterator constant_begin(const Function *F) {
+ return constant_iterator(F);
+}
+
+inline constant_iterator constant_end(const Function *F) {
+ return constant_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/DIBuilder.h b/contrib/llvm/include/llvm/Analysis/DIBuilder.h
new file mode 100644
index 000000000000..2d109cdbf08f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/DIBuilder.h
@@ -0,0 +1,560 @@
+//===--- llvm/Analysis/DIBuilder.h - Debug Information Builder --*- 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 DIBuilder that is useful for creating debugging
+// information entries in LLVM IR form.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+ class BasicBlock;
+ class Instruction;
+ class Function;
+ class Module;
+ class Value;
+ class LLVMContext;
+ class MDNode;
+ class StringRef;
+ class DIDescriptor;
+ class DIFile;
+ class DIEnumerator;
+ class DIType;
+ class DIArray;
+ class DIGlobalVariable;
+ class DINameSpace;
+ class DIVariable;
+ class DISubrange;
+ class DILexicalBlockFile;
+ class DILexicalBlock;
+ class DISubprogram;
+ class DITemplateTypeParameter;
+ class DITemplateValueParameter;
+ class DIObjCProperty;
+
+ class DIBuilder {
+ private:
+ Module &M;
+ LLVMContext & VMContext;
+ MDNode *TheCU;
+
+ MDNode *TempEnumTypes;
+ MDNode *TempRetainTypes;
+ MDNode *TempSubprograms;
+ MDNode *TempGVs;
+
+ Function *DeclareFn; // llvm.dbg.declare
+ Function *ValueFn; // llvm.dbg.value
+
+ SmallVector<Value *, 4> AllEnumTypes;
+ SmallVector<Value *, 4> AllRetainTypes;
+ SmallVector<Value *, 4> AllSubprograms;
+ SmallVector<Value *, 4> AllGVs;
+
+ DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT
+ void operator=(const DIBuilder &); // DO NOT IMPLEMENT
+
+ public:
+ explicit DIBuilder(Module &M);
+ const MDNode *getCU() { return TheCU; }
+ enum ComplexAddrKind { OpPlus=1, OpDeref };
+
+ /// finalize - Construct any deferred debug info descriptors.
+ void finalize();
+
+ /// createCompileUnit - A CompileUnit provides an anchor for all debugging
+ /// information generated during this instance of compilation.
+ /// @param Lang Source programming language, eg. dwarf::DW_LANG_C99
+ /// @param File File name
+ /// @param Dir Directory
+ /// @param Producer String identify producer of debugging information.
+ /// Usuall this is a compiler version string.
+ /// @param isOptimized A boolean flag which indicates whether optimization
+ /// is ON or not.
+ /// @param Flags This string lists command line options. This string is
+ /// directly embedded in debug info output which may be used
+ /// by a tool analyzing generated debugging information.
+ /// @param RV This indicates runtime version for languages like
+ /// Objective-C.
+ void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
+ StringRef Producer,
+ bool isOptimized, StringRef Flags, unsigned RV);
+
+ /// createFile - Create a file descriptor to hold debugging information
+ /// for a file.
+ DIFile createFile(StringRef Filename, StringRef Directory);
+
+ /// createEnumerator - Create a single enumerator value.
+ DIEnumerator createEnumerator(StringRef Name, uint64_t Val);
+
+ /// createNullPtrType - Create C++0x nullptr type.
+ DIType createNullPtrType(StringRef Name);
+
+ /// createBasicType - Create debugging information entry for a basic
+ /// type.
+ /// @param Name Type name.
+ /// @param SizeInBits Size of the type.
+ /// @param AlignInBits Type alignment.
+ /// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
+ DIType createBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding);
+
+ /// createQualifiedType - Create debugging information entry for a qualified
+ /// type, e.g. 'const int'.
+ /// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
+ /// @param FromTy Base Type.
+ DIType createQualifiedType(unsigned Tag, DIType FromTy);
+
+ /// createPointerType - Create debugging information entry for a pointer.
+ /// @param PointeeTy Type pointed by this pointer.
+ /// @param SizeInBits Size.
+ /// @param AlignInBits Alignment. (optional)
+ /// @param Name Pointer type name. (optional)
+ DIType createPointerType(DIType PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits = 0,
+ StringRef Name = StringRef());
+
+ /// createReferenceType - Create debugging information entry for a c++
+ /// style reference.
+ DIType createReferenceType(DIType RTy);
+
+ /// createTypedef - Create debugging information entry for a typedef.
+ /// @param Ty Original type.
+ /// @param Name Typedef name.
+ /// @param File File where this type is defined.
+ /// @param LineNo Line number.
+ /// @param Context The surrounding context for the typedef.
+ DIType createTypedef(DIType Ty, StringRef Name, DIFile File,
+ unsigned LineNo, DIDescriptor Context);
+
+ /// createFriend - Create debugging information entry for a 'friend'.
+ DIType createFriend(DIType Ty, DIType FriendTy);
+
+ /// createInheritance - Create debugging information entry to establish
+ /// inheritance relationship between two types.
+ /// @param Ty Original type.
+ /// @param BaseTy Base type. Ty is inherits from base.
+ /// @param BaseOffset Base offset.
+ /// @param Flags Flags to describe inheritance attribute,
+ /// e.g. private
+ DIType createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset,
+ unsigned Flags);
+
+ /// createMemberType - Create debugging information entry for a member.
+ /// @param Scope Member scope.
+ /// @param Name Member name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param OffsetInBits Member offset.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Ty Parent type.
+ DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNo, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DIType Ty);
+
+ /// createObjCIVar - Create debugging information entry for Objective-C
+ /// instance variable.
+ /// @param Name Member name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param OffsetInBits Member offset.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Ty Parent type.
+ /// @param PropertyName Name of the Objective C property assoicated with
+ /// this ivar.
+ /// @param GetterName Name of the Objective C property getter selector.
+ /// @param SetterName Name of the Objective C property setter selector.
+ /// @param PropertyAttributes Objective C property attributes.
+ DIType createObjCIVar(StringRef Name, DIFile File,
+ unsigned LineNo, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DIType Ty,
+ StringRef PropertyName = StringRef(),
+ StringRef PropertyGetterName = StringRef(),
+ StringRef PropertySetterName = StringRef(),
+ unsigned PropertyAttributes = 0);
+
+ /// createObjCIVar - Create debugging information entry for Objective-C
+ /// instance variable.
+ /// @param Name Member name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param OffsetInBits Member offset.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Ty Parent type.
+ /// @param Property Property associated with this ivar.
+ DIType createObjCIVar(StringRef Name, DIFile File,
+ unsigned LineNo, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DIType Ty,
+ MDNode *PropertyNode);
+
+ /// createObjCProperty - Create debugging information entry for Objective-C
+ /// property.
+ /// @param Name Property name.
+ /// @param File File where this property is defined.
+ /// @param LineNumber Line number.
+ /// @param GetterName Name of the Objective C property getter selector.
+ /// @param SetterName Name of the Objective C property setter selector.
+ /// @param PropertyAttributes Objective C property attributes.
+ /// @param Ty Type.
+ DIObjCProperty createObjCProperty(StringRef Name,
+ DIFile File, unsigned LineNumber,
+ StringRef GetterName,
+ StringRef SetterName,
+ unsigned PropertyAttributes,
+ DIType Ty);
+
+ /// createClassType - Create debugging information entry for a class.
+ /// @param Scope Scope in which this class is defined.
+ /// @param Name class name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param OffsetInBits Member offset.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Elements class members.
+ /// @param VTableHolder Debug info of the base class that contains vtable
+ /// for this type. This is used in
+ /// DW_AT_containing_type. See DWARF documentation
+ /// for more info.
+ /// @param TemplateParms Template type parameters.
+ DIType createClassType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, uint64_t OffsetInBits,
+ unsigned Flags, DIType DerivedFrom,
+ DIArray Elements, MDNode *VTableHolder = 0,
+ MDNode *TemplateParms = 0);
+
+ /// createStructType - Create debugging information entry for a struct.
+ /// @param Scope Scope in which this struct is defined.
+ /// @param Name Struct name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Elements Struct elements.
+ /// @param RunTimeLang Optional parameter, Objective-C runtime version.
+ DIType createStructType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Flags,
+ DIArray Elements, unsigned RunTimeLang = 0);
+
+ /// createUnionType - Create debugging information entry for an union.
+ /// @param Scope Scope in which this union is defined.
+ /// @param Name Union name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param Flags Flags to encode member attribute, e.g. private
+ /// @param Elements Union elements.
+ /// @param RunTimeLang Optional parameter, Objective-C runtime version.
+ DIType createUnionType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNumber, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Flags,
+ DIArray Elements, unsigned RunTimeLang = 0);
+
+ /// createTemplateTypeParameter - Create debugging information for template
+ /// type parameter.
+ /// @param Scope Scope in which this type is defined.
+ /// @param Name Type parameter name.
+ /// @param Ty Parameter type.
+ /// @param File File where this type parameter is defined.
+ /// @param LineNo Line number.
+ /// @param ColumnNo Column Number.
+ DITemplateTypeParameter
+ createTemplateTypeParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
+ MDNode *File = 0, unsigned LineNo = 0,
+ unsigned ColumnNo = 0);
+
+ /// createTemplateValueParameter - Create debugging information for template
+ /// value parameter.
+ /// @param Scope Scope in which this type is defined.
+ /// @param Name Value parameter name.
+ /// @param Ty Parameter type.
+ /// @param Value Constant parameter value.
+ /// @param File File where this type parameter is defined.
+ /// @param LineNo Line number.
+ /// @param ColumnNo Column Number.
+ DITemplateValueParameter
+ createTemplateValueParameter(DIDescriptor Scope, StringRef Name, DIType Ty,
+ uint64_t Value,
+ MDNode *File = 0, unsigned LineNo = 0,
+ unsigned ColumnNo = 0);
+
+ /// createArrayType - Create debugging information entry for an array.
+ /// @param Size Array size.
+ /// @param AlignInBits Alignment.
+ /// @param Ty Element type.
+ /// @param Subscripts Subscripts.
+ DIType createArrayType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts);
+
+ /// createVectorType - Create debugging information entry for a vector type.
+ /// @param Size Array size.
+ /// @param AlignInBits Alignment.
+ /// @param Ty Element type.
+ /// @param Subscripts Subscripts.
+ DIType createVectorType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts);
+
+ /// createEnumerationType - Create debugging information entry for an
+ /// enumeration.
+ /// @param Scope Scope in which this enumeration is defined.
+ /// @param Name Union name.
+ /// @param File File where this member is defined.
+ /// @param LineNo Line number.
+ /// @param SizeInBits Member size.
+ /// @param AlignInBits Member alignment.
+ /// @param Elements Enumeration elements.
+ DIType createEnumerationType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits,
+ uint64_t AlignInBits, DIArray Elements);
+
+ /// createSubroutineType - Create subroutine type.
+ /// @param File File in which this subroutine is defined.
+ /// @param ParamterTypes An array of subroutine parameter types. This
+ /// includes return type at 0th index.
+ DIType createSubroutineType(DIFile File, DIArray ParameterTypes);
+
+ /// createArtificialType - Create a new DIType with "artificial" flag set.
+ DIType createArtificialType(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, DIFile F,
+ unsigned Line, unsigned RuntimeLang = 0);
+
+ /// retainType - Retain DIType in a module even if it is not referenced
+ /// through debug info anchors.
+ void retainType(DIType T);
+
+ /// createUnspecifiedParameter - Create unspeicified type descriptor
+ /// for a subroutine type.
+ DIDescriptor createUnspecifiedParameter();
+
+ /// getOrCreateArray - Get a DIArray, create one if required.
+ DIArray getOrCreateArray(ArrayRef<Value *> Elements);
+
+ /// getOrCreateSubrange - Create a descriptor for a value range. This
+ /// implicitly uniques the values returned.
+ DISubrange getOrCreateSubrange(int64_t Lo, int64_t Hi);
+
+ /// createGlobalVariable - Create a new descriptor for the specified global.
+ /// @param Name Name of the variable.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type.
+ /// @param isLocalToUnit Boolean flag indicate whether this variable is
+ /// externally visible or not.
+ /// @param Val llvm::Value of the variable.
+ DIGlobalVariable
+ createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+
+
+ /// createStaticVariable - Create a new descriptor for the specified
+ /// variable.
+ /// @param Conext Variable scope.
+ /// @param Name Name of the variable.
+ /// @param LinakgeName Mangled name of the variable.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type.
+ /// @param isLocalToUnit Boolean flag indicate whether this variable is
+ /// externally visible or not.
+ /// @param Val llvm::Value of the variable.
+ DIGlobalVariable
+ createStaticVariable(DIDescriptor Context, StringRef Name,
+ StringRef LinkageName, DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+
+
+ /// createLocalVariable - Create a new descriptor for the specified
+ /// local variable.
+ /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
+ /// DW_TAG_arg_variable.
+ /// @param Scope Variable scope.
+ /// @param Name Variable name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type
+ /// @param AlwaysPreserve Boolean. Set to true if debug info for this
+ /// variable should be preserved in optimized build.
+ /// @param Flags Flags, e.g. artificial variable.
+ /// @param ArgNo If this variable is an arugment then this argument's
+ /// number. 1 indicates 1st argument.
+ DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
+ StringRef Name,
+ DIFile File, unsigned LineNo,
+ DIType Ty, bool AlwaysPreserve = false,
+ unsigned Flags = 0,
+ unsigned ArgNo = 0);
+
+
+ /// createComplexVariable - Create a new descriptor for the specified
+ /// variable which has a complex address expression for its address.
+ /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
+ /// DW_TAG_arg_variable.
+ /// @param Scope Variable scope.
+ /// @param Name Variable name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Variable Type
+ /// @param Addr An array of complex address operations.
+ /// @param ArgNo If this variable is an arugment then this argument's
+ /// number. 1 indicates 1st argument.
+ DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope,
+ StringRef Name, DIFile F, unsigned LineNo,
+ DIType Ty, ArrayRef<Value *> Addr,
+ unsigned ArgNo = 0);
+
+ /// createFunction - Create a new descriptor for the specified subprogram.
+ /// See comments in DISubprogram for descriptions of these fields.
+ /// @param Scope Function scope.
+ /// @param Name Function name.
+ /// @param LinkageName Mangled function name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Function type.
+ /// @param isLocalToUnit True if this function is not externally visible..
+ /// @param isDefinition True if this is a function definition.
+ /// @param ScopeLine Set to the beginning of the scope this starts
+ /// @param Flags e.g. is this function prototyped or not.
+ /// This flags are used to emit dwarf attributes.
+ /// @param isOptimized True if optimization is ON.
+ /// @param Fn llvm::Function pointer.
+ /// @param TParam Function template parameters.
+ DISubprogram createFunction(DIDescriptor Scope, StringRef Name,
+ StringRef LinkageName,
+ DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit,
+ bool isDefinition,
+ unsigned ScopeLine,
+ unsigned Flags = 0,
+ bool isOptimized = false,
+ Function *Fn = 0,
+ MDNode *TParam = 0,
+ MDNode *Decl = 0);
+
+ /// createMethod - Create a new descriptor for the specified C++ method.
+ /// See comments in DISubprogram for descriptions of these fields.
+ /// @param Scope Function scope.
+ /// @param Name Function name.
+ /// @param LinkageName Mangled function name.
+ /// @param File File where this variable is defined.
+ /// @param LineNo Line number.
+ /// @param Ty Function type.
+ /// @param isLocalToUnit True if this function is not externally visible..
+ /// @param isDefinition True if this is a function definition.
+ /// @param Virtuality Attributes describing virtualness. e.g. pure
+ /// virtual function.
+ /// @param VTableIndex Index no of this method in virtual table.
+ /// @param VTableHolder Type that holds vtable.
+ /// @param Flags e.g. is this function prototyped or not.
+ /// This flags are used to emit dwarf attributes.
+ /// @param isOptimized True if optimization is ON.
+ /// @param Fn llvm::Function pointer.
+ /// @param TParam Function template parameters.
+ DISubprogram createMethod(DIDescriptor Scope, StringRef Name,
+ StringRef LinkageName,
+ DIFile File, unsigned LineNo,
+ DIType Ty, bool isLocalToUnit,
+ bool isDefinition,
+ unsigned Virtuality = 0, unsigned VTableIndex = 0,
+ MDNode *VTableHolder = 0,
+ unsigned Flags = 0,
+ bool isOptimized = false,
+ Function *Fn = 0,
+ MDNode *TParam = 0);
+
+ /// createNameSpace - This creates new descriptor for a namespace
+ /// with the specified parent scope.
+ /// @param Scope Namespace scope
+ /// @param Name Name of this namespace
+ /// @param File Source file
+ /// @param LineNo Line number
+ DINameSpace createNameSpace(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNo);
+
+
+ /// createLexicalBlockFile - This creates a descriptor for a lexical
+ /// block with a new file attached. This merely extends the existing
+ /// lexical block as it crosses a file.
+ /// @param Scope Lexical block.
+ /// @param File Source file.
+ DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope,
+ DIFile File);
+
+ /// createLexicalBlock - This creates a descriptor for a lexical block
+ /// with the specified parent context.
+ /// @param Scope Parent lexical scope.
+ /// @param File Source file
+ /// @param Line Line number
+ /// @param Col Column number
+ DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
+ unsigned Line, unsigned Col);
+
+ /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+ /// @param Storage llvm::Value of the variable
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertAtEnd Location for the new intrinsic.
+ Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
+ BasicBlock *InsertAtEnd);
+
+ /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
+ /// @param Storage llvm::Value of the variable
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertBefore Location for the new intrinsic.
+ Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo,
+ Instruction *InsertBefore);
+
+
+ /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+ /// @param Val llvm::Value of the variable
+ /// @param Offset Offset
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertAtEnd Location for the new intrinsic.
+ Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
+ DIVariable VarInfo,
+ BasicBlock *InsertAtEnd);
+
+ /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
+ /// @param Val llvm::Value of the variable
+ /// @param Offset Offset
+ /// @param VarInfo Variable's debug info descriptor.
+ /// @param InsertBefore Location for the new intrinsic.
+ Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
+ DIVariable VarInfo,
+ Instruction *InsertBefore);
+
+ };
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h b/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
new file mode 100644
index 000000000000..b701b8fca5d4
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -0,0 +1,83 @@
+//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Templates to create dotty viewer and printer passes for GraphTraits graphs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
+#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
+
+#include "llvm/Pass.h"
+#include "llvm/Analysis/CFGPrinter.h"
+
+namespace llvm {
+template <class Analysis, bool Simple>
+struct DOTGraphTraitsViewer : public FunctionPass {
+ std::string Name;
+
+ DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
+ Name = GraphName;
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ Analysis *Graph;
+ std::string Title, GraphName;
+ Graph = &getAnalysis<Analysis>();
+ GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ Title = GraphName + " for '" + F.getName().str() + "' function";
+ ViewGraph(Graph, Name, Simple, Title);
+
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<Analysis>();
+ }
+};
+
+template <class Analysis, bool Simple>
+struct DOTGraphTraitsPrinter : public FunctionPass {
+
+ std::string Name;
+
+ DOTGraphTraitsPrinter(std::string GraphName, char &ID)
+ : FunctionPass(ID) {
+ Name = GraphName;
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ Analysis *Graph;
+ std::string Filename = Name + "." + F.getName().str() + ".dot";
+ errs() << "Writing '" << Filename << "'...";
+
+ std::string ErrorInfo;
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo);
+ Graph = &getAnalysis<Analysis>();
+
+ std::string Title, GraphName;
+ GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ Title = GraphName + " for '" + F.getName().str() + "' function";
+
+ if (ErrorInfo.empty())
+ WriteGraph(File, Graph, Simple, Title);
+ else
+ errs() << " error opening file for writing!";
+ errs() << "\n";
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<Analysis>();
+ }
+};
+}
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/DebugInfo.h b/contrib/llvm/include/llvm/Analysis/DebugInfo.h
new file mode 100644
index 000000000000..894c5428b988
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/DebugInfo.h
@@ -0,0 +1,928 @@
+//===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- 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 bunch of datatypes that are useful for creating and
+// walking debug info in LLVM IR form. They essentially provide wrappers around
+// the information in the global variables that's needed when constructing the
+// DWARF information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DEBUGINFO_H
+#define LLVM_ANALYSIS_DEBUGINFO_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Dwarf.h"
+
+namespace llvm {
+ class BasicBlock;
+ class Constant;
+ class Function;
+ class GlobalVariable;
+ class Module;
+ class Type;
+ class Value;
+ class DbgDeclareInst;
+ class Instruction;
+ class MDNode;
+ class NamedMDNode;
+ class LLVMContext;
+ class raw_ostream;
+
+ class DIFile;
+ class DISubprogram;
+ class DILexicalBlock;
+ class DILexicalBlockFile;
+ class DIVariable;
+ class DIType;
+ class DIObjCProperty;
+
+ /// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
+ /// This should not be stored in a container, because underly MDNode may
+ /// change in certain situations.
+ class DIDescriptor {
+ public:
+ enum {
+ FlagPrivate = 1 << 0,
+ FlagProtected = 1 << 1,
+ FlagFwdDecl = 1 << 2,
+ FlagAppleBlock = 1 << 3,
+ FlagBlockByrefStruct = 1 << 4,
+ FlagVirtual = 1 << 5,
+ FlagArtificial = 1 << 6,
+ FlagExplicit = 1 << 7,
+ FlagPrototyped = 1 << 8,
+ FlagObjcClassComplete = 1 << 9
+ };
+ protected:
+ const MDNode *DbgNode;
+
+ StringRef getStringField(unsigned Elt) const;
+ unsigned getUnsignedField(unsigned Elt) const {
+ return (unsigned)getUInt64Field(Elt);
+ }
+ uint64_t getUInt64Field(unsigned Elt) const;
+ DIDescriptor getDescriptorField(unsigned Elt) const;
+
+ template <typename DescTy>
+ DescTy getFieldAs(unsigned Elt) const {
+ return DescTy(getDescriptorField(Elt));
+ }
+
+ GlobalVariable *getGlobalVariableField(unsigned Elt) const;
+ Constant *getConstantField(unsigned Elt) const;
+ Function *getFunctionField(unsigned Elt) const;
+
+ public:
+ explicit DIDescriptor() : DbgNode(0) {}
+ explicit DIDescriptor(const MDNode *N) : DbgNode(N) {}
+ explicit DIDescriptor(const DIFile F);
+ explicit DIDescriptor(const DISubprogram F);
+ explicit DIDescriptor(const DILexicalBlockFile F);
+ explicit DIDescriptor(const DILexicalBlock F);
+ explicit DIDescriptor(const DIVariable F);
+ explicit DIDescriptor(const DIType F);
+
+ bool Verify() const { return DbgNode != 0; }
+
+ operator MDNode *() const { return const_cast<MDNode*>(DbgNode); }
+ MDNode *operator ->() const { return const_cast<MDNode*>(DbgNode); }
+
+ unsigned getVersion() const {
+ return getUnsignedField(0) & LLVMDebugVersionMask;
+ }
+
+ unsigned getTag() const {
+ return getUnsignedField(0) & ~LLVMDebugVersionMask;
+ }
+
+ /// print - print descriptor.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print descriptor to dbgs() with a newline.
+ void dump() const;
+
+ bool isDerivedType() const;
+ bool isCompositeType() const;
+ bool isBasicType() const;
+ bool isVariable() const;
+ bool isSubprogram() const;
+ bool isGlobalVariable() const;
+ bool isScope() const;
+ bool isFile() const;
+ bool isCompileUnit() const;
+ bool isNameSpace() const;
+ bool isLexicalBlockFile() const;
+ bool isLexicalBlock() const;
+ bool isSubrange() const;
+ bool isEnumerator() const;
+ bool isType() const;
+ bool isGlobal() const;
+ bool isUnspecifiedParameter() const;
+ bool isTemplateTypeParameter() const;
+ bool isTemplateValueParameter() const;
+ bool isObjCProperty() const;
+ };
+
+ /// DISubrange - This is used to represent ranges, for array bounds.
+ class DISubrange : public DIDescriptor {
+ public:
+ explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ uint64_t getLo() const { return getUInt64Field(1); }
+ uint64_t getHi() const { return getUInt64Field(2); }
+ };
+
+ /// DIArray - This descriptor holds an array of descriptors.
+ class DIArray : public DIDescriptor {
+ public:
+ explicit DIArray(const MDNode *N = 0)
+ : DIDescriptor(N) {}
+
+ unsigned getNumElements() const;
+ DIDescriptor getElement(unsigned Idx) const {
+ return getDescriptorField(Idx);
+ }
+ };
+
+ /// DIScope - A base class for various scopes.
+ class DIScope : public DIDescriptor {
+ virtual void anchor();
+ public:
+ explicit DIScope(const MDNode *N = 0) : DIDescriptor (N) {}
+ virtual ~DIScope() {}
+
+ StringRef getFilename() const;
+ StringRef getDirectory() const;
+ };
+
+ /// DICompileUnit - A wrapper for a compile unit.
+ class DICompileUnit : public DIScope {
+ virtual void anchor();
+ public:
+ explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
+
+ unsigned getLanguage() const { return getUnsignedField(2); }
+ StringRef getFilename() const { return getStringField(3); }
+ StringRef getDirectory() const { return getStringField(4); }
+ StringRef getProducer() const { return getStringField(5); }
+
+ /// isMain - Each input file is encoded as a separate compile unit in LLVM
+ /// debugging information output. However, many target specific tool chains
+ /// prefer to encode only one compile unit in an object file. In this
+ /// situation, the LLVM code generator will include debugging information
+ /// entities in the compile unit that is marked as main compile unit. The
+ /// code generator accepts maximum one main compile unit per module. If a
+ /// module does not contain any main compile unit then the code generator
+ /// will emit multiple compile units in the output object file.
+
+ bool isMain() const { return getUnsignedField(6) != 0; }
+ bool isOptimized() const { return getUnsignedField(7) != 0; }
+ StringRef getFlags() const { return getStringField(8); }
+ unsigned getRunTimeVersion() const { return getUnsignedField(9); }
+
+ DIArray getEnumTypes() const;
+ DIArray getRetainedTypes() const;
+ DIArray getSubprograms() const;
+ DIArray getGlobalVariables() const;
+
+ /// Verify - Verify that a compile unit is well formed.
+ bool Verify() const;
+
+ /// print - print compile unit.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print compile unit to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DIFile - This is a wrapper for a file.
+ class DIFile : public DIScope {
+ virtual void anchor();
+ public:
+ explicit DIFile(const MDNode *N = 0) : DIScope(N) {
+ if (DbgNode && !isFile())
+ DbgNode = 0;
+ }
+ StringRef getFilename() const { return getStringField(1); }
+ StringRef getDirectory() const { return getStringField(2); }
+ DICompileUnit getCompileUnit() const{
+ assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!");
+ return getFieldAs<DICompileUnit>(3);
+ }
+ };
+
+ /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
+ /// FIXME: it seems strange that this doesn't have either a reference to the
+ /// type/precision or a file/line pair for location info.
+ class DIEnumerator : public DIDescriptor {
+ public:
+ explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ StringRef getName() const { return getStringField(1); }
+ uint64_t getEnumValue() const { return getUInt64Field(2); }
+ };
+
+ /// DIType - This is a wrapper for a type.
+ /// FIXME: Types should be factored much better so that CV qualifiers and
+ /// others do not require a huge and empty descriptor full of zeros.
+ class DIType : public DIScope {
+ virtual void anchor();
+ protected:
+ // This ctor is used when the Tag has already been validated by a derived
+ // ctor.
+ DIType(const MDNode *N, bool, bool) : DIScope(N) {}
+
+ public:
+
+ /// Verify - Verify that a type descriptor is well formed.
+ bool Verify() const;
+ explicit DIType(const MDNode *N);
+ explicit DIType() {}
+ virtual ~DIType() {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ 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); }
+ unsigned getLineNumber() const { return getUnsignedField(4); }
+ uint64_t getSizeInBits() const { return getUInt64Field(5); }
+ uint64_t getAlignInBits() const { return getUInt64Field(6); }
+ // FIXME: Offset is only used for DW_TAG_member nodes. Making every type
+ // carry this is just plain insane.
+ uint64_t getOffsetInBits() const { return getUInt64Field(7); }
+ unsigned getFlags() const { return getUnsignedField(8); }
+ bool isPrivate() const {
+ return (getFlags() & FlagPrivate) != 0;
+ }
+ bool isProtected() const {
+ return (getFlags() & FlagProtected) != 0;
+ }
+ bool isForwardDecl() const {
+ return (getFlags() & FlagFwdDecl) != 0;
+ }
+ // isAppleBlock - Return true if this is the Apple Blocks extension.
+ bool isAppleBlockExtension() const {
+ return (getFlags() & FlagAppleBlock) != 0;
+ }
+ bool isBlockByrefStruct() const {
+ return (getFlags() & FlagBlockByrefStruct) != 0;
+ }
+ bool isVirtual() const {
+ return (getFlags() & FlagVirtual) != 0;
+ }
+ bool isArtificial() const {
+ return (getFlags() & FlagArtificial) != 0;
+ }
+ bool isObjcClassComplete() const {
+ return (getFlags() & FlagObjcClassComplete) != 0;
+ }
+ bool isValid() const {
+ return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
+ }
+ StringRef getDirectory() const {
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getCompileUnit().getDirectory();
+
+ return getFieldAs<DIFile>(3).getDirectory();
+ }
+ StringRef getFilename() const {
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getCompileUnit().getFilename();
+
+ return getFieldAs<DIFile>(3).getFilename();
+ }
+
+ /// isUnsignedDIType - Return true if type encoding is unsigned.
+ bool isUnsignedDIType();
+
+ /// replaceAllUsesWith - Replace all uses of debug info referenced by
+ /// this descriptor.
+ void replaceAllUsesWith(DIDescriptor &D);
+ void replaceAllUsesWith(MDNode *D);
+
+ /// print - print type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print type to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DIBasicType - A basic type, like 'int' or 'float'.
+ class DIBasicType : public DIType {
+ virtual void anchor();
+ public:
+ explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
+
+ unsigned getEncoding() const { return getUnsignedField(9); }
+
+ /// Verify - Verify that a basic type descriptor is well formed.
+ bool Verify() const;
+
+ /// print - print basic type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print basic type to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DIDerivedType - A simple derived type, like a const qualified type,
+ /// a typedef, a pointer or reference, etc.
+ class DIDerivedType : public DIType {
+ virtual void anchor();
+ protected:
+ explicit DIDerivedType(const MDNode *N, bool, bool)
+ : DIType(N, true, true) {}
+ public:
+ explicit DIDerivedType(const MDNode *N = 0)
+ : DIType(N, true, true) {}
+
+ DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
+
+ /// getOriginalTypeSize - If this type is derived from a base type then
+ /// return base type size.
+ uint64_t getOriginalTypeSize() const;
+
+ /// getObjCProperty - Return property node, if this ivar is
+ /// associated with one.
+ MDNode *getObjCProperty() const;
+
+ StringRef getObjCPropertyName() const {
+ if (getVersion() > LLVMDebugVersion11)
+ return StringRef();
+ return getStringField(10);
+ }
+ StringRef getObjCPropertyGetterName() const {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return getStringField(11);
+ }
+ StringRef getObjCPropertySetterName() const {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return getStringField(12);
+ }
+ bool isReadOnlyObjCProperty() {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
+ }
+ bool isReadWriteObjCProperty() {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
+ }
+ bool isAssignObjCProperty() {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
+ }
+ bool isRetainObjCProperty() {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
+ }
+ bool isCopyObjCProperty() {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
+ }
+ bool isNonAtomicObjCProperty() {
+ assert (getVersion() <= LLVMDebugVersion11 && "Invalid Request");
+ return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
+ }
+
+ /// Verify - Verify that a derived type descriptor is well formed.
+ bool Verify() const;
+
+ /// print - print derived type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print derived type to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DICompositeType - This descriptor holds a type that can refer to multiple
+ /// other types, like a function or struct.
+ /// FIXME: Why is this a DIDerivedType??
+ class DICompositeType : public DIDerivedType {
+ virtual void anchor();
+ public:
+ explicit DICompositeType(const MDNode *N = 0)
+ : DIDerivedType(N, true, true) {
+ if (N && !isCompositeType())
+ DbgNode = 0;
+ }
+
+ DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
+ unsigned getRunTimeLang() const { return getUnsignedField(11); }
+ DICompositeType getContainingType() const {
+ return getFieldAs<DICompositeType>(12);
+ }
+ DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
+
+ /// Verify - Verify that a composite type descriptor is well formed.
+ bool Verify() const;
+
+ /// print - print composite type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print composite type to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DITemplateTypeParameter - This is a wrapper for template type parameter.
+ class DITemplateTypeParameter : public DIDescriptor {
+ public:
+ explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DIType getType() const { return getFieldAs<DIType>(3); }
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(4).getFilename();
+ }
+ StringRef getDirectory() const {
+ return getFieldAs<DIFile>(4).getDirectory();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(5); }
+ unsigned getColumnNumber() const { return getUnsignedField(6); }
+ };
+
+ /// DITemplateValueParameter - This is a wrapper for template value parameter.
+ class DITemplateValueParameter : public DIDescriptor {
+ public:
+ explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DIType getType() const { return getFieldAs<DIType>(3); }
+ uint64_t getValue() const { return getUInt64Field(4); }
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(5).getFilename();
+ }
+ StringRef getDirectory() const {
+ return getFieldAs<DIFile>(5).getDirectory();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(6); }
+ unsigned getColumnNumber() const { return getUnsignedField(7); }
+ };
+
+ /// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
+ class DISubprogram : public DIScope {
+ virtual void anchor();
+ public:
+ explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ StringRef getName() const { return getStringField(3); }
+ StringRef getDisplayName() const { return getStringField(4); }
+ StringRef getLinkageName() const { return getStringField(5); }
+ DICompileUnit getCompileUnit() const{
+ assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(6);
+
+ return getFieldAs<DIFile>(6).getCompileUnit();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(7); }
+ DICompositeType getType() const { return getFieldAs<DICompositeType>(8); }
+
+ /// getReturnTypeName - Subprogram return types are encoded either as
+ /// DIType or as DICompositeType.
+ StringRef getReturnTypeName() const {
+ DICompositeType DCT(getFieldAs<DICompositeType>(8));
+ if (DCT.Verify()) {
+ DIArray A = DCT.getTypeArray();
+ DIType T(A.getElement(0));
+ return T.getName();
+ }
+ DIType T(getFieldAs<DIType>(8));
+ return T.getName();
+ }
+
+ /// isLocalToUnit - Return true if this subprogram is local to the current
+ /// compile unit, like 'static' in C.
+ unsigned isLocalToUnit() const { return getUnsignedField(9); }
+ unsigned isDefinition() const { return getUnsignedField(10); }
+
+ unsigned getVirtuality() const { return getUnsignedField(11); }
+ unsigned getVirtualIndex() const { return getUnsignedField(12); }
+
+ DICompositeType getContainingType() const {
+ return getFieldAs<DICompositeType>(13);
+ }
+
+ unsigned isArtificial() const {
+ if (getVersion() <= llvm::LLVMDebugVersion8)
+ return getUnsignedField(14);
+ return (getUnsignedField(14) & FlagArtificial) != 0;
+ }
+ /// isPrivate - Return true if this subprogram has "private"
+ /// access specifier.
+ 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 {
+ if (getVersion() <= llvm::LLVMDebugVersion8)
+ return false;
+ return (getUnsignedField(14) & FlagProtected) != 0;
+ }
+ /// isExplicit - Return true if this subprogram is marked as explicit.
+ 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 {
+ if (getVersion() <= llvm::LLVMDebugVersion8)
+ return false;
+ return (getUnsignedField(14) & FlagPrototyped) != 0;
+ }
+
+ unsigned isOptimized() const;
+
+ StringRef getFilename() const {
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getCompileUnit().getFilename();
+
+ return getFieldAs<DIFile>(6).getFilename();
+ }
+
+ StringRef getDirectory() const {
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getCompileUnit().getFilename();
+
+ return getFieldAs<DIFile>(6).getDirectory();
+ }
+
+ /// getScopeLineNumber - Get the beginning of the scope of the
+ /// function, not necessarily where the name of the program
+ /// starts.
+ unsigned getScopeLineNumber() const { return getUnsignedField(20); }
+
+ /// Verify - Verify that a subprogram descriptor is well formed.
+ bool Verify() const;
+
+ /// print - print subprogram.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print subprogram to dbgs() with a newline.
+ void dump() const;
+
+ /// describes - Return true if this subprogram provides debugging
+ /// information for the function F.
+ bool describes(const Function *F);
+
+ Function *getFunction() const { return getFunctionField(16); }
+ DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); }
+ DISubprogram getFunctionDeclaration() const {
+ return getFieldAs<DISubprogram>(18);
+ }
+ MDNode *getVariablesNodes() const;
+ DIArray getVariables() const;
+ };
+
+ /// DIGlobalVariable - This is a wrapper for a global variable.
+ class DIGlobalVariable : public DIDescriptor {
+ public:
+ explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ StringRef getName() const { return getStringField(3); }
+ StringRef getDisplayName() const { return getStringField(4); }
+ StringRef getLinkageName() const { return getStringField(5); }
+ DICompileUnit getCompileUnit() const{
+ assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(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); }
+ unsigned isLocalToUnit() const { return getUnsignedField(9); }
+ unsigned isDefinition() const { return getUnsignedField(10); }
+
+ GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
+ Constant *getConstant() const { return getConstantField(11); }
+
+ /// Verify - Verify that a global variable descriptor is well formed.
+ bool Verify() const;
+
+ /// print - print global variable.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print global variable to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
+ /// global etc).
+ class DIVariable : public DIDescriptor {
+ public:
+ explicit DIVariable(const MDNode *N = 0)
+ : DIDescriptor(N) {}
+
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ StringRef getName() const { return getStringField(2); }
+ DICompileUnit getCompileUnit() const {
+ assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(3);
+
+ DIFile F = getFieldAs<DIFile>(3);
+ return F.getCompileUnit();
+ }
+ unsigned getLineNumber() const {
+ return (getUnsignedField(4) << 8) >> 8;
+ }
+ unsigned getArgNumber() const {
+ 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 {
+ if (getVersion() <= llvm::LLVMDebugVersion8)
+ return false;
+ return (getUnsignedField(6) & FlagArtificial) != 0;
+ }
+
+ /// getInlinedAt - If this variable is inlined then return inline location.
+ MDNode *getInlinedAt() const;
+
+ /// Verify - Verify that a variable descriptor is well formed.
+ bool Verify() const;
+
+ /// HasComplexAddr - Return true if the variable has a complex address.
+ bool hasComplexAddress() const {
+ return getNumAddrElements() > 0;
+ }
+
+ unsigned getNumAddrElements() const;
+
+ uint64_t getAddrElement(unsigned Idx) const {
+ if (getVersion() <= llvm::LLVMDebugVersion8)
+ return getUInt64Field(Idx+6);
+ if (getVersion() == llvm::LLVMDebugVersion9)
+ return getUInt64Field(Idx+7);
+ return getUInt64Field(Idx+8);
+ }
+
+ /// isBlockByrefVariable - Return true if the variable was declared as
+ /// a "__block" variable (Apple Blocks).
+ bool isBlockByrefVariable() const {
+ return getType().isBlockByrefStruct();
+ }
+
+ /// isInlinedFnArgument - Return trule if this variable provides debugging
+ /// information for an inlined function arguments.
+ bool isInlinedFnArgument(const Function *CurFn);
+
+ /// print - print variable.
+ void print(raw_ostream &OS) const;
+
+ void printExtendedName(raw_ostream &OS) const;
+
+ /// dump - print variable to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// DILexicalBlock - This is a wrapper for a lexical block.
+ class DILexicalBlock : public DIScope {
+ virtual void anchor();
+ public:
+ explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const { return getFieldAs<DIScope>(1); }
+ unsigned getLineNumber() const { return getUnsignedField(2); }
+ unsigned getColumnNumber() const { return getUnsignedField(3); }
+ StringRef getDirectory() const {
+ StringRef dir = getFieldAs<DIFile>(4).getDirectory();
+ return !dir.empty() ? dir : getContext().getDirectory();
+ }
+ StringRef getFilename() const {
+ StringRef filename = getFieldAs<DIFile>(4).getFilename();
+ return !filename.empty() ? filename : getContext().getFilename();
+ }
+ };
+
+ /// DILexicalBlockFile - This is a wrapper for a lexical block with
+ /// a filename change.
+ class DILexicalBlockFile : public DIScope {
+ virtual void anchor();
+ public:
+ explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
+ DIScope getContext() const { return getScope().getContext(); }
+ unsigned getLineNumber() const { return getScope().getLineNumber(); }
+ unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
+ StringRef getDirectory() const {
+ StringRef dir = getFieldAs<DIFile>(2).getDirectory();
+ return !dir.empty() ? dir : getContext().getDirectory();
+ }
+ StringRef getFilename() const {
+ StringRef filename = getFieldAs<DIFile>(2).getFilename();
+ assert(!filename.empty() && "Why'd you create this then?");
+ return filename;
+ }
+ DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(1); }
+ };
+
+ /// DINameSpace - A wrapper for a C++ style name space.
+ class DINameSpace : public DIScope {
+ virtual void anchor();
+ 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 {
+ return getFieldAs<DIFile>(3).getDirectory();
+ }
+ StringRef getFilename() const {
+ return getFieldAs<DIFile>(3).getFilename();
+ }
+ DICompileUnit getCompileUnit() const{
+ assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
+ if (getVersion() == llvm::LLVMDebugVersion7)
+ return getFieldAs<DICompileUnit>(3);
+
+ return getFieldAs<DIFile>(3).getCompileUnit();
+ }
+ unsigned getLineNumber() const { return getUnsignedField(4); }
+ bool Verify() const;
+ };
+
+ /// DILocation - This object holds location information. This object
+ /// is not associated with any DWARF tag.
+ class DILocation : public DIDescriptor {
+ public:
+ explicit DILocation(const MDNode *N) : DIDescriptor(N) { }
+
+ unsigned getLineNumber() const { return getUnsignedField(0); }
+ unsigned getColumnNumber() const { return getUnsignedField(1); }
+ DIScope getScope() const { return getFieldAs<DIScope>(2); }
+ DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
+ StringRef getFilename() const { return getScope().getFilename(); }
+ StringRef getDirectory() const { return getScope().getDirectory(); }
+ bool Verify() const;
+ };
+
+ class DIObjCProperty : public DIDescriptor {
+ public:
+ explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) { }
+
+ StringRef getObjCPropertyName() const { return getStringField(1); }
+ DIFile getFile() const { return getFieldAs<DIFile>(2); }
+ unsigned getLineNumber() const { return getUnsignedField(3); }
+
+ StringRef getObjCPropertyGetterName() const {
+ return getStringField(4);
+ }
+ StringRef getObjCPropertySetterName() const {
+ return getStringField(5);
+ }
+ bool isReadOnlyObjCProperty() {
+ return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
+ }
+ bool isReadWriteObjCProperty() {
+ return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
+ }
+ bool isAssignObjCProperty() {
+ return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
+ }
+ bool isRetainObjCProperty() {
+ return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
+ }
+ bool isCopyObjCProperty() {
+ return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
+ }
+ bool isNonAtomicObjCProperty() {
+ return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
+ }
+
+ DIType getType() const { return getFieldAs<DIType>(7); }
+
+ /// Verify - Verify that a derived type descriptor is well formed.
+ bool Verify() const;
+
+ /// print - print derived type.
+ void print(raw_ostream &OS) const;
+
+ /// dump - print derived type to dbgs() with a newline.
+ void dump() const;
+ };
+
+ /// getDISubprogram - Find subprogram that is enclosing this scope.
+ DISubprogram getDISubprogram(const MDNode *Scope);
+
+ /// getDICompositeType - Find underlying composite type.
+ DICompositeType getDICompositeType(DIType T);
+
+ /// isSubprogramContext - Return true if Context is either a subprogram
+ /// or another context nested inside a subprogram.
+ bool isSubprogramContext(const MDNode *Context);
+
+ /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
+ /// to hold function specific information.
+ NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
+
+ /// getFnSpecificMDNode - Return a NameMDNode, if available, that is
+ /// suitable to hold function specific information.
+ NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
+
+ /// createInlinedVariable - Create a new inlined variable based on current
+ /// variable.
+ /// @param DV Current Variable.
+ /// @param InlinedScope Location at current variable is inlined.
+ DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
+ LLVMContext &VMContext);
+
+ /// cleanseInlinedVariable - Remove inlined scope from the variable.
+ DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
+
+ class DebugInfoFinder {
+ public:
+ /// processModule - Process entire module and collect debug info
+ /// anchors.
+ void processModule(Module &M);
+
+ private:
+ /// processType - Process DIType.
+ void processType(DIType DT);
+
+ /// processLexicalBlock - Process DILexicalBlock.
+ void processLexicalBlock(DILexicalBlock LB);
+
+ /// processSubprogram - Process DISubprogram.
+ void processSubprogram(DISubprogram SP);
+
+ /// processDeclare - Process DbgDeclareInst.
+ void processDeclare(DbgDeclareInst *DDI);
+
+ /// processLocation - Process DILocation.
+ void processLocation(DILocation Loc);
+
+ /// addCompileUnit - Add compile unit into CUs.
+ bool addCompileUnit(DICompileUnit CU);
+
+ /// addGlobalVariable - Add global variable into GVs.
+ bool addGlobalVariable(DIGlobalVariable DIG);
+
+ // addSubprogram - Add subprogram into SPs.
+ bool addSubprogram(DISubprogram SP);
+
+ /// addType - Add type into Tys.
+ bool addType(DIType DT);
+
+ public:
+ typedef SmallVector<MDNode *, 8>::const_iterator iterator;
+ iterator compile_unit_begin() const { return CUs.begin(); }
+ iterator compile_unit_end() const { return CUs.end(); }
+ iterator subprogram_begin() const { return SPs.begin(); }
+ iterator subprogram_end() const { return SPs.end(); }
+ iterator global_variable_begin() const { return GVs.begin(); }
+ iterator global_variable_end() const { return GVs.end(); }
+ iterator type_begin() const { return TYs.begin(); }
+ iterator type_end() const { return TYs.end(); }
+
+ unsigned compile_unit_count() const { return CUs.size(); }
+ unsigned global_variable_count() const { return GVs.size(); }
+ unsigned subprogram_count() const { return SPs.size(); }
+ unsigned type_count() const { return TYs.size(); }
+
+ private:
+ SmallVector<MDNode *, 8> CUs; // Compile Units
+ SmallVector<MDNode *, 8> SPs; // Subprograms
+ SmallVector<MDNode *, 8> GVs; // Global Variables;
+ SmallVector<MDNode *, 8> TYs; // Types
+ SmallPtrSet<MDNode *, 64> NodesSeen;
+ };
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/DomPrinter.h b/contrib/llvm/include/llvm/Analysis/DomPrinter.h
new file mode 100644
index 000000000000..0ed28994995a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/DomPrinter.h
@@ -0,0 +1,30 @@
+//===-- DomPrinter.h - Dom printer external interface ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines external functions that can be called to explicitly
+// instantiate the dominance tree printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMPRINTER_H
+#define LLVM_ANALYSIS_DOMPRINTER_H
+
+namespace llvm {
+ class FunctionPass;
+ FunctionPass *createDomPrinterPass();
+ FunctionPass *createDomOnlyPrinterPass();
+ FunctionPass *createDomViewerPass();
+ FunctionPass *createDomOnlyViewerPass();
+ FunctionPass *createPostDomPrinterPass();
+ FunctionPass *createPostDomOnlyPrinterPass();
+ FunctionPass *createPostDomViewerPass();
+ FunctionPass *createPostDomOnlyViewerPass();
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h b/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h
new file mode 100644
index 000000000000..a2e0675e92b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/DominanceFrontier.h
@@ -0,0 +1,190 @@
+//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- 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 DominanceFrontier class, which calculate and holds the
+// dominance frontier for a function.
+//
+// This should be considered deprecated, don't add any more uses of this data
+// structure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
+#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
+
+#include "llvm/Analysis/Dominators.h"
+#include <map>
+#include <set>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// DominanceFrontierBase - Common base class for computing forward and inverse
+/// dominance frontiers for a function.
+///
+class DominanceFrontierBase : public FunctionPass {
+public:
+ typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
+ typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
+protected:
+ DomSetMapType Frontiers;
+ std::vector<BasicBlock*> Roots;
+ const bool IsPostDominators;
+
+public:
+ DominanceFrontierBase(char &ID, bool isPostDom)
+ : FunctionPass(ID), IsPostDominators(isPostDom) {}
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
+
+ /// isPostDominator - Returns true if analysis based of postdoms
+ ///
+ bool isPostDominator() const { return IsPostDominators; }
+
+ virtual void releaseMemory() { Frontiers.clear(); }
+
+ // Accessor interface:
+ typedef DomSetMapType::iterator iterator;
+ typedef DomSetMapType::const_iterator const_iterator;
+ iterator begin() { return Frontiers.begin(); }
+ const_iterator begin() const { return Frontiers.begin(); }
+ iterator end() { return Frontiers.end(); }
+ const_iterator end() const { return Frontiers.end(); }
+ iterator find(BasicBlock *B) { return Frontiers.find(B); }
+ const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
+
+ iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
+ assert(find(BB) == end() && "Block already in DominanceFrontier!");
+ return Frontiers.insert(std::make_pair(BB, frontier)).first;
+ }
+
+ /// removeBlock - Remove basic block BB's frontier.
+ void removeBlock(BasicBlock *BB) {
+ assert(find(BB) != end() && "Block is not in DominanceFrontier!");
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ I->second.erase(BB);
+ Frontiers.erase(BB);
+ }
+
+ void addToFrontier(iterator I, BasicBlock *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ I->second.insert(Node);
+ }
+
+ void removeFromFrontier(iterator I, BasicBlock *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+ I->second.erase(Node);
+ }
+
+ /// compareDomSet - Return false if two domsets match. Otherwise
+ /// return true;
+ bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
+ std::set<BasicBlock *> tmpSet;
+ for (DomSetType::const_iterator I = DS2.begin(),
+ E = DS2.end(); I != E; ++I)
+ tmpSet.insert(*I);
+
+ for (DomSetType::const_iterator I = DS1.begin(),
+ E = DS1.end(); I != E; ) {
+ BasicBlock *Node = *I++;
+
+ if (tmpSet.erase(Node) == 0)
+ // Node is in DS1 but not in DS2.
+ return true;
+ }
+
+ if (!tmpSet.empty())
+ // There are nodes that are in DS2 but not in DS1.
+ return true;
+
+ // DS1 and DS2 matches.
+ return false;
+ }
+
+ /// compare - Return true if the other dominance frontier base matches
+ /// this dominance frontier base. Otherwise return false.
+ bool compare(DominanceFrontierBase &Other) const {
+ DomSetMapType tmpFrontiers;
+ for (DomSetMapType::const_iterator I = Other.begin(),
+ E = Other.end(); I != E; ++I)
+ tmpFrontiers.insert(std::make_pair(I->first, I->second));
+
+ for (DomSetMapType::iterator I = tmpFrontiers.begin(),
+ E = tmpFrontiers.end(); I != E; ) {
+ BasicBlock *Node = I->first;
+ const_iterator DFI = find(Node);
+ if (DFI == end())
+ return true;
+
+ if (compareDomSet(I->second, DFI->second))
+ return true;
+
+ ++I;
+ tmpFrontiers.erase(Node);
+ }
+
+ if (!tmpFrontiers.empty())
+ return true;
+
+ return false;
+ }
+
+ /// print - Convert to human readable form
+ ///
+ virtual void print(raw_ostream &OS, const Module* = 0) const;
+
+ /// dump - Dump the dominance frontier to dbgs().
+ void dump() const;
+};
+
+
+//===-------------------------------------
+/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
+/// used to compute a forward dominator frontiers.
+///
+class DominanceFrontier : public DominanceFrontierBase {
+ virtual void anchor();
+public:
+ static char ID; // Pass ID, replacement for typeid
+ DominanceFrontier() :
+ DominanceFrontierBase(ID, false) {
+ initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
+ }
+
+ BasicBlock *getRoot() const {
+ assert(Roots.size() == 1 && "Should always have entry node!");
+ return Roots[0];
+ }
+
+ virtual bool runOnFunction(Function &) {
+ Frontiers.clear();
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+ Roots = DT.getRoots();
+ assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
+ calculate(DT, DT[Roots[0]]);
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<DominatorTree>();
+ }
+
+ const DomSetType &calculate(const DominatorTree &DT,
+ const DomTreeNode *Node);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/DominatorInternals.h b/contrib/llvm/include/llvm/Analysis/DominatorInternals.h
new file mode 100644
index 000000000000..0c29236dde96
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/DominatorInternals.h
@@ -0,0 +1,289 @@
+//=== llvm/Analysis/DominatorInternals.h - Dominator Calculation -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
+#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
+
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+//===----------------------------------------------------------------------===//
+//
+// DominatorTree construction - This pass constructs immediate dominator
+// information for a flow-graph based on the algorithm described in this
+// document:
+//
+// A Fast Algorithm for Finding Dominators in a Flowgraph
+// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
+//
+// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns
+// out that the theoretically slower O(n*log(n)) implementation is actually
+// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+template<class GraphT>
+unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* V, unsigned N) {
+ // This is more understandable as a recursive algorithm, but we can't use the
+ // recursive algorithm due to stack depth issues. Keep it here for
+ // documentation purposes.
+#if 0
+ InfoRec &VInfo = DT.Info[DT.Roots[i]];
+ VInfo.DFSNum = VInfo.Semi = ++N;
+ VInfo.Label = V;
+
+ Vertex.push_back(V); // Vertex[n] = V;
+
+ for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
+ InfoRec &SuccVInfo = DT.Info[*SI];
+ if (SuccVInfo.Semi == 0) {
+ SuccVInfo.Parent = V;
+ N = DTDFSPass(DT, *SI, N);
+ }
+ }
+#else
+ bool IsChildOfArtificialExit = (N != 0);
+
+ SmallVector<std::pair<typename GraphT::NodeType*,
+ typename GraphT::ChildIteratorType>, 32> Worklist;
+ Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
+ while (!Worklist.empty()) {
+ typename GraphT::NodeType* BB = Worklist.back().first;
+ typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+ DT.Info[BB];
+
+ // First time we visited this BB?
+ if (NextSucc == GraphT::child_begin(BB)) {
+ BBInfo.DFSNum = BBInfo.Semi = ++N;
+ BBInfo.Label = BB;
+
+ DT.Vertex.push_back(BB); // Vertex[n] = V;
+
+ if (IsChildOfArtificialExit)
+ BBInfo.Parent = 1;
+
+ IsChildOfArtificialExit = false;
+ }
+
+ // store the DFS number of the current BB - the reference to BBInfo might
+ // get invalidated when processing the successors.
+ unsigned BBDFSNum = BBInfo.DFSNum;
+
+ // If we are done with this block, remove it from the worklist.
+ if (NextSucc == GraphT::child_end(BB)) {
+ Worklist.pop_back();
+ continue;
+ }
+
+ // Increment the successor number for the next time we get to it.
+ ++Worklist.back().second;
+
+ // Visit the successor next, if it isn't already visited.
+ typename GraphT::NodeType* Succ = *NextSucc;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
+ DT.Info[Succ];
+ if (SuccVInfo.Semi == 0) {
+ SuccVInfo.Parent = BBDFSNum;
+ Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
+ }
+ }
+#endif
+ return N;
+}
+
+template<class GraphT>
+typename GraphT::NodeType*
+Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType *VIn, unsigned LastLinked) {
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
+ DT.Info[VIn];
+ if (VInInfo.DFSNum < LastLinked)
+ return VIn;
+
+ SmallVector<typename GraphT::NodeType*, 32> Work;
+ SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
+
+ if (VInInfo.Parent >= LastLinked)
+ Work.push_back(VIn);
+
+ while (!Work.empty()) {
+ typename GraphT::NodeType* V = Work.back();
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
+ DT.Info[V];
+ typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
+
+ // Process Ancestor first
+ if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) {
+ Work.push_back(VAncestor);
+ continue;
+ }
+ Work.pop_back();
+
+ // Update VInfo based on Ancestor info
+ if (VInfo.Parent < LastLinked)
+ continue;
+
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
+ DT.Info[VAncestor];
+ typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
+ typename GraphT::NodeType* VLabel = VInfo.Label;
+ if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
+ VInfo.Label = VAncestorLabel;
+ VInfo.Parent = VAInfo.Parent;
+ }
+
+ return VInInfo.Label;
+}
+
+template<class FuncT, class NodeT>
+void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
+ FuncT& F) {
+ typedef GraphTraits<NodeT> GraphT;
+
+ unsigned N = 0;
+ bool MultipleRoots = (DT.Roots.size() > 1);
+ if (MultipleRoots) {
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
+ DT.Info[NULL];
+ BBInfo.DFSNum = BBInfo.Semi = ++N;
+ BBInfo.Label = NULL;
+
+ DT.Vertex.push_back(NULL); // Vertex[n] = V;
+ }
+
+ // Step #1: Number blocks in depth-first order and initialize variables used
+ // in later stages of the algorithm.
+ for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
+ i != e; ++i)
+ N = DFSPass<GraphT>(DT, DT.Roots[i], N);
+
+ // it might be that some blocks did not get a DFS number (e.g., blocks of
+ // infinite loops). In these cases an artificial exit node is required.
+ MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
+
+ // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
+ // bucket for each vertex. However, this is unnecessary, because each vertex
+ // is only placed into a single bucket (that of its semidominator), and each
+ // vertex's bucket is processed before it is added to any bucket itself.
+ //
+ // Instead of using a bucket per vertex, we use a single array Buckets that
+ // has two purposes. Before the vertex V with preorder number i is processed,
+ // Buckets[i] stores the index of the first element in V's bucket. After V's
+ // bucket is processed, Buckets[i] stores the index of the next element in the
+ // bucket containing V, if any.
+ SmallVector<unsigned, 32> Buckets;
+ Buckets.resize(N + 1);
+ for (unsigned i = 1; i <= N; ++i)
+ Buckets[i] = i;
+
+ for (unsigned i = N; i >= 2; --i) {
+ typename GraphT::NodeType* W = DT.Vertex[i];
+ typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
+ DT.Info[W];
+
+ // Step #2: Implicitly define the immediate dominator of vertices
+ for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
+ typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+ typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
+ DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
+ }
+
+ // Step #3: Calculate the semidominators of all vertices
+
+ // initialize the semi dominator to point to the parent node
+ WInfo.Semi = WInfo.Parent;
+ typedef GraphTraits<Inverse<NodeT> > InvTraits;
+ for (typename InvTraits::ChildIteratorType CI =
+ InvTraits::child_begin(W),
+ E = InvTraits::child_end(W); CI != E; ++CI) {
+ typename InvTraits::NodeType *N = *CI;
+ if (DT.Info.count(N)) { // Only if this predecessor is reachable!
+ unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
+ if (SemiU < WInfo.Semi)
+ WInfo.Semi = SemiU;
+ }
+ }
+
+ // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
+ // necessarily parent(V). In this case, set idom(V) here and avoid placing
+ // V into a bucket.
+ if (WInfo.Semi == WInfo.Parent) {
+ DT.IDoms[W] = DT.Vertex[WInfo.Parent];
+ } else {
+ Buckets[i] = Buckets[WInfo.Semi];
+ Buckets[WInfo.Semi] = i;
+ }
+ }
+
+ if (N >= 1) {
+ typename GraphT::NodeType* Root = DT.Vertex[1];
+ for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
+ typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
+ DT.IDoms[V] = Root;
+ }
+ }
+
+ // Step #4: Explicitly define the immediate dominator of each vertex
+ for (unsigned i = 2; i <= N; ++i) {
+ typename GraphT::NodeType* W = DT.Vertex[i];
+ typename GraphT::NodeType*& WIDom = DT.IDoms[W];
+ if (WIDom != DT.Vertex[DT.Info[W].Semi])
+ WIDom = DT.IDoms[WIDom];
+ }
+
+ if (DT.Roots.empty()) return;
+
+ // Add a node for the root. This node might be the actual root, if there is
+ // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
+ // which postdominates all real exits if there are multiple exit blocks, or
+ // an infinite loop.
+ typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;
+
+ DT.DomTreeNodes[Root] = DT.RootNode =
+ new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0);
+
+ // Loop over all of the reachable blocks in the function...
+ for (unsigned i = 2; i <= N; ++i) {
+ typename GraphT::NodeType* W = DT.Vertex[i];
+
+ DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
+ if (BBNode) continue; // Haven't calculated this node yet?
+
+ typename GraphT::NodeType* ImmDom = DT.getIDom(W);
+
+ assert(ImmDom || DT.DomTreeNodes[NULL]);
+
+ // Get or calculate the node for the immediate dominator
+ DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
+ DT.getNodeForBlock(ImmDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DomTreeNodeBase<typename GraphT::NodeType> *C =
+ new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode);
+ DT.DomTreeNodes[W] = IDomNode->addChild(C);
+ }
+
+ // Free temporary memory used to construct idom's
+ DT.IDoms.clear();
+ DT.Info.clear();
+ std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
+
+ DT.updateDFSNumbers();
+}
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/Dominators.h b/contrib/llvm/include/llvm/Analysis/Dominators.h
new file mode 100644
index 000000000000..6e8e4246367e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Dominators.h
@@ -0,0 +1,904 @@
+//===- llvm/Analysis/Dominators.h - Dominator Info Calculation --*- 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 DominatorTree class, which provides fast and efficient
+// dominance queries.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// DominatorBase - Base class that other, more interesting dominator analyses
+/// inherit from.
+///
+template <class NodeT>
+class DominatorBase {
+protected:
+ std::vector<NodeT*> Roots;
+ const bool IsPostDominators;
+ inline explicit DominatorBase(bool isPostDom) :
+ Roots(), IsPostDominators(isPostDom) {}
+public:
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<NodeT*> &getRoots() const { return Roots; }
+
+ /// isPostDominator - Returns true if analysis based of postdoms
+ ///
+ bool isPostDominator() const { return IsPostDominators; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// DomTreeNode - Dominator Tree Node
+template<class NodeT> class DominatorTreeBase;
+struct PostDominatorTree;
+class MachineBasicBlock;
+
+template <class NodeT>
+class DomTreeNodeBase {
+ NodeT *TheBB;
+ DomTreeNodeBase<NodeT> *IDom;
+ std::vector<DomTreeNodeBase<NodeT> *> Children;
+ int DFSNumIn, DFSNumOut;
+
+ template<class N> friend class DominatorTreeBase;
+ friend struct PostDominatorTree;
+public:
+ typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
+ typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
+ const_iterator;
+
+ iterator begin() { return Children.begin(); }
+ iterator end() { return Children.end(); }
+ const_iterator begin() const { return Children.begin(); }
+ const_iterator end() const { return Children.end(); }
+
+ NodeT *getBlock() const { return TheBB; }
+ DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
+ const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const {
+ return Children;
+ }
+
+ DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
+ : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
+
+ DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
+ Children.push_back(C);
+ return C;
+ }
+
+ size_t getNumChildren() const {
+ return Children.size();
+ }
+
+ void clearAllChildren() {
+ Children.clear();
+ }
+
+ bool compare(DomTreeNodeBase<NodeT> *Other) {
+ if (getNumChildren() != Other->getNumChildren())
+ return true;
+
+ SmallPtrSet<NodeT *, 4> OtherChildren;
+ for (iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
+ NodeT *Nd = (*I)->getBlock();
+ OtherChildren.insert(Nd);
+ }
+
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ NodeT *N = (*I)->getBlock();
+ if (OtherChildren.count(N) == 0)
+ return true;
+ }
+ return false;
+ }
+
+ void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
+ assert(IDom && "No immediate dominator?");
+ if (IDom != NewIDom) {
+ typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
+ std::find(IDom->Children.begin(), IDom->Children.end(), this);
+ assert(I != IDom->Children.end() &&
+ "Not in immediate dominator children set!");
+ // I am no longer your child...
+ IDom->Children.erase(I);
+
+ // Switch to new dominator
+ IDom = NewIDom;
+ IDom->Children.push_back(this);
+ }
+ }
+
+ /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do
+ /// not call them.
+ unsigned getDFSNumIn() const { return DFSNumIn; }
+ unsigned getDFSNumOut() const { return DFSNumOut; }
+private:
+ // Return true if this node is dominated by other. Use this only if DFS info
+ // is valid.
+ bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
+ return this->DFSNumIn >= other->DFSNumIn &&
+ this->DFSNumOut <= other->DFSNumOut;
+ }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
+
+template<class NodeT>
+static raw_ostream &operator<<(raw_ostream &o,
+ const DomTreeNodeBase<NodeT> *Node) {
+ if (Node->getBlock())
+ WriteAsOperand(o, Node->getBlock(), false);
+ else
+ o << " <<exit node>>";
+
+ o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
+
+ return o << "\n";
+}
+
+template<class NodeT>
+static void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
+ unsigned Lev) {
+ o.indent(2*Lev) << "[" << Lev << "] " << N;
+ for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
+ E = N->end(); I != E; ++I)
+ PrintDomTree<NodeT>(*I, o, Lev+1);
+}
+
+typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
+
+//===----------------------------------------------------------------------===//
+/// DominatorTree - Calculate the immediate dominator tree for a function.
+///
+
+template<class FuncT, class N>
+void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
+ FuncT& F);
+
+template<class NodeT>
+class DominatorTreeBase : public DominatorBase<NodeT> {
+ bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) const {
+ assert(A != B);
+ assert(isReachableFromEntry(B));
+ assert(isReachableFromEntry(A));
+
+ const DomTreeNodeBase<NodeT> *IDom;
+ while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
+ B = IDom; // Walk up the tree
+ return IDom != 0;
+ }
+
+protected:
+ typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
+ DomTreeNodeMapType DomTreeNodes;
+ DomTreeNodeBase<NodeT> *RootNode;
+
+ bool DFSInfoValid;
+ unsigned int SlowQueries;
+ // Information record used during immediate dominators computation.
+ struct InfoRec {
+ unsigned DFSNum;
+ unsigned Parent;
+ unsigned Semi;
+ NodeT *Label;
+
+ InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {}
+ };
+
+ DenseMap<NodeT*, NodeT*> IDoms;
+
+ // Vertex - Map the DFS number to the BasicBlock*
+ std::vector<NodeT*> Vertex;
+
+ // Info - Collection of information used during the computation of idoms.
+ DenseMap<NodeT*, InfoRec> Info;
+
+ void reset() {
+ for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
+ E = DomTreeNodes.end(); I != E; ++I)
+ delete I->second;
+ DomTreeNodes.clear();
+ IDoms.clear();
+ this->Roots.clear();
+ Vertex.clear();
+ RootNode = 0;
+ }
+
+ // NewBB is split and now it has one successor. Update dominator tree to
+ // reflect this change.
+ template<class N, class GraphT>
+ void Split(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* NewBB) {
+ assert(std::distance(GraphT::child_begin(NewBB),
+ GraphT::child_end(NewBB)) == 1 &&
+ "NewBB should have a single successor!");
+ typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB);
+
+ std::vector<typename GraphT::NodeType*> PredBlocks;
+ typedef GraphTraits<Inverse<N> > InvTraits;
+ for (typename InvTraits::ChildIteratorType PI =
+ InvTraits::child_begin(NewBB),
+ PE = InvTraits::child_end(NewBB); PI != PE; ++PI)
+ PredBlocks.push_back(*PI);
+
+ assert(!PredBlocks.empty() && "No predblocks?");
+
+ bool NewBBDominatesNewBBSucc = true;
+ for (typename InvTraits::ChildIteratorType PI =
+ InvTraits::child_begin(NewBBSucc),
+ E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) {
+ typename InvTraits::NodeType *ND = *PI;
+ if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
+ DT.isReachableFromEntry(ND)) {
+ NewBBDominatesNewBBSucc = false;
+ break;
+ }
+ }
+
+ // Find NewBB's immediate dominator and create new dominator tree node for
+ // NewBB.
+ NodeT *NewBBIDom = 0;
+ unsigned i = 0;
+ for (i = 0; i < PredBlocks.size(); ++i)
+ if (DT.isReachableFromEntry(PredBlocks[i])) {
+ NewBBIDom = PredBlocks[i];
+ break;
+ }
+
+ // It's possible that none of the predecessors of NewBB are reachable;
+ // in that case, NewBB itself is unreachable, so nothing needs to be
+ // changed.
+ if (!NewBBIDom)
+ return;
+
+ for (i = i + 1; i < PredBlocks.size(); ++i) {
+ if (DT.isReachableFromEntry(PredBlocks[i]))
+ NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
+ }
+
+ // Create the new dominator tree node... and set the idom of NewBB.
+ DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
+
+ // If NewBB strictly dominates other blocks, then it is now the immediate
+ // dominator of NewBBSucc. Update the dominator tree as appropriate.
+ if (NewBBDominatesNewBBSucc) {
+ DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc);
+ DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
+ }
+ }
+
+public:
+ explicit DominatorTreeBase(bool isPostDom)
+ : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
+ virtual ~DominatorTreeBase() { reset(); }
+
+ /// compare - Return false if the other dominator tree base matches this
+ /// dominator tree base. Otherwise return true.
+ bool compare(DominatorTreeBase &Other) const {
+
+ const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
+ if (DomTreeNodes.size() != OtherDomTreeNodes.size())
+ return true;
+
+ for (typename DomTreeNodeMapType::const_iterator
+ I = this->DomTreeNodes.begin(),
+ E = this->DomTreeNodes.end(); I != E; ++I) {
+ NodeT *BB = I->first;
+ typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB);
+ if (OI == OtherDomTreeNodes.end())
+ return true;
+
+ DomTreeNodeBase<NodeT>* MyNd = I->second;
+ DomTreeNodeBase<NodeT>* OtherNd = OI->second;
+
+ if (MyNd->compare(OtherNd))
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual void releaseMemory() { reset(); }
+
+ /// getNode - return the (Post)DominatorTree node for the specified basic
+ /// block. This is the same as using operator[] on this class.
+ ///
+ inline DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const {
+ return DomTreeNodes.lookup(BB);
+ }
+
+ /// getRootNode - This returns the entry node for the CFG of the function. If
+ /// this tree represents the post-dominance relations for a function, however,
+ /// this root may be a node with the block == NULL. This is the case when
+ /// there are multiple exit nodes from a particular function. Consumers of
+ /// post-dominance information must be capable of dealing with this
+ /// possibility.
+ ///
+ DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
+ const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
+
+ /// properlyDominates - Returns true iff this dominates N and this != N.
+ /// Note that this is not a constant time operation!
+ ///
+ bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) {
+ if (A == 0 || B == 0)
+ return false;
+ if (A == B)
+ return false;
+ return dominates(A, B);
+ }
+
+ bool properlyDominates(const NodeT *A, const NodeT *B);
+
+ /// isReachableFromEntry - Return true if A is dominated by the entry
+ /// block of the function containing it.
+ bool isReachableFromEntry(const NodeT* A) const {
+ assert(!this->isPostDominator() &&
+ "This is not implemented for post dominators");
+ return isReachableFromEntry(getNode(const_cast<NodeT *>(A)));
+ }
+
+ inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const {
+ return A;
+ }
+
+ /// dominates - Returns true iff A dominates B. Note that this is not a
+ /// constant time operation!
+ ///
+ inline bool dominates(const DomTreeNodeBase<NodeT> *A,
+ const DomTreeNodeBase<NodeT> *B) {
+ // A node trivially dominates itself.
+ if (B == A)
+ return true;
+
+ // An unreachable node is dominated by anything.
+ if (!isReachableFromEntry(B))
+ return true;
+
+ // And dominates nothing.
+ if (!isReachableFromEntry(A))
+ return false;
+
+ // Compare the result of the tree walk and the dfs numbers, if expensive
+ // checks are enabled.
+#ifdef XDEBUG
+ assert((!DFSInfoValid ||
+ (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
+ "Tree walk disagrees with dfs numbers!");
+#endif
+
+ if (DFSInfoValid)
+ return B->DominatedBy(A);
+
+ // If we end up with too many slow queries, just update the
+ // DFS numbers on the theory that we are going to keep querying.
+ SlowQueries++;
+ if (SlowQueries > 32) {
+ updateDFSNumbers();
+ return B->DominatedBy(A);
+ }
+
+ return dominatedBySlowTreeWalk(A, B);
+ }
+
+ bool dominates(const NodeT *A, const NodeT *B);
+
+ NodeT *getRoot() const {
+ assert(this->Roots.size() == 1 && "Should always have entry node!");
+ return this->Roots[0];
+ }
+
+ /// findNearestCommonDominator - Find nearest common dominator basic block
+ /// for basic block A and B. If there is no such block then return NULL.
+ NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
+ assert(A->getParent() == B->getParent() &&
+ "Two blocks are not in same function");
+
+ // If either A or B is a entry block then it is nearest common dominator
+ // (for forward-dominators).
+ if (!this->isPostDominator()) {
+ NodeT &Entry = A->getParent()->front();
+ if (A == &Entry || B == &Entry)
+ return &Entry;
+ }
+
+ // If B dominates A then B is nearest common dominator.
+ if (dominates(B, A))
+ return B;
+
+ // If A dominates B then A is nearest common dominator.
+ if (dominates(A, B))
+ return A;
+
+ DomTreeNodeBase<NodeT> *NodeA = getNode(A);
+ DomTreeNodeBase<NodeT> *NodeB = getNode(B);
+
+ // Collect NodeA dominators set.
+ SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
+ NodeADoms.insert(NodeA);
+ DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+ while (IDomA) {
+ NodeADoms.insert(IDomA);
+ IDomA = IDomA->getIDom();
+ }
+
+ // Walk NodeB immediate dominators chain and find common dominator node.
+ DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();
+ while (IDomB) {
+ if (NodeADoms.count(IDomB) != 0)
+ return IDomB->getBlock();
+
+ IDomB = IDomB->getIDom();
+ }
+
+ return NULL;
+ }
+
+ const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
+ // Cast away the const qualifiers here. This is ok since
+ // const is re-introduced on the return type.
+ return findNearestCommonDominator(const_cast<NodeT *>(A),
+ const_cast<NodeT *>(B));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // API to update (Post)DominatorTree information based on modifications to
+ // the CFG...
+
+ /// addNewBlock - Add a new node to the dominator tree information. This
+ /// creates a new node as a child of DomBB dominator node,linking it into
+ /// the children list of the immediate dominator.
+ DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
+ assert(getNode(BB) == 0 && "Block already in dominator tree!");
+ DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
+ assert(IDomNode && "Not immediate dominator specified for block!");
+ DFSInfoValid = false;
+ return DomTreeNodes[BB] =
+ IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
+ }
+
+ /// changeImmediateDominator - This method is used to update the dominator
+ /// tree information when a node's immediate dominator changes.
+ ///
+ void changeImmediateDominator(DomTreeNodeBase<NodeT> *N,
+ DomTreeNodeBase<NodeT> *NewIDom) {
+ assert(N && NewIDom && "Cannot change null node pointers!");
+ DFSInfoValid = false;
+ N->setIDom(NewIDom);
+ }
+
+ void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
+ changeImmediateDominator(getNode(BB), getNode(NewBB));
+ }
+
+ /// eraseNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Removes node from its immediate dominator's
+ /// children list. Deletes dominator node associated with basic block BB.
+ void eraseNode(NodeT *BB) {
+ DomTreeNodeBase<NodeT> *Node = getNode(BB);
+ assert(Node && "Removing node that isn't in dominator tree.");
+ assert(Node->getChildren().empty() && "Node is not a leaf node.");
+
+ // Remove node from immediate dominator's children list.
+ DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
+ if (IDom) {
+ typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
+ std::find(IDom->Children.begin(), IDom->Children.end(), Node);
+ assert(I != IDom->Children.end() &&
+ "Not in immediate dominator children set!");
+ // I am no longer your child...
+ IDom->Children.erase(I);
+ }
+
+ DomTreeNodes.erase(BB);
+ delete Node;
+ }
+
+ /// removeNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Invalidates any node pointing to removed
+ /// block.
+ void removeNode(NodeT *BB) {
+ assert(getNode(BB) && "Removing node that isn't in dominator tree.");
+ DomTreeNodes.erase(BB);
+ }
+
+ /// splitBlock - BB is split and now it has one successor. Update dominator
+ /// tree to reflect this change.
+ void splitBlock(NodeT* NewBB) {
+ if (this->IsPostDominators)
+ this->Split<Inverse<NodeT*>, GraphTraits<Inverse<NodeT*> > >(*this, NewBB);
+ else
+ this->Split<NodeT*, GraphTraits<NodeT*> >(*this, NewBB);
+ }
+
+ /// print - Convert to human readable form
+ ///
+ void print(raw_ostream &o) const {
+ o << "=============================--------------------------------\n";
+ if (this->isPostDominator())
+ o << "Inorder PostDominator Tree: ";
+ else
+ o << "Inorder Dominator Tree: ";
+ if (!this->DFSInfoValid)
+ o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
+ o << "\n";
+
+ // The postdom tree can have a null root if there are no returns.
+ if (getRootNode())
+ PrintDomTree<NodeT>(getRootNode(), o, 1);
+ }
+
+protected:
+ template<class GraphT>
+ friend typename GraphT::NodeType* Eval(
+ DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* V,
+ unsigned LastLinked);
+
+ template<class GraphT>
+ friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
+ typename GraphT::NodeType* V,
+ unsigned N);
+
+ template<class FuncT, class N>
+ friend void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
+ FuncT& F);
+
+ /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
+ /// dominator tree in dfs order.
+ void updateDFSNumbers() {
+ unsigned DFSNum = 0;
+
+ SmallVector<std::pair<DomTreeNodeBase<NodeT>*,
+ typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
+
+ DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
+
+ if (!ThisRoot)
+ return;
+
+ // Even in the case of multiple exits that form the post dominator root
+ // nodes, do not iterate over all exits, but start from the virtual root
+ // node. Otherwise bbs, that are not post dominated by any exit but by the
+ // virtual root node, will never be assigned a DFS number.
+ WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
+ ThisRoot->DFSNumIn = DFSNum++;
+
+ while (!WorkStack.empty()) {
+ DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
+ typename DomTreeNodeBase<NodeT>::iterator ChildIt =
+ WorkStack.back().second;
+
+ // If we visited all of the children of this node, "recurse" back up the
+ // stack setting the DFOutNum.
+ if (ChildIt == Node->end()) {
+ Node->DFSNumOut = DFSNum++;
+ WorkStack.pop_back();
+ } else {
+ // Otherwise, recursively visit this child.
+ DomTreeNodeBase<NodeT> *Child = *ChildIt;
+ ++WorkStack.back().second;
+
+ WorkStack.push_back(std::make_pair(Child, Child->begin()));
+ Child->DFSNumIn = DFSNum++;
+ }
+ }
+
+ SlowQueries = 0;
+ DFSInfoValid = true;
+ }
+
+ DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
+ if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
+ return Node;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate dominator.
+ NodeT *IDom = getIDom(BB);
+
+ assert(IDom || this->DomTreeNodes[NULL]);
+ DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
+ return this->DomTreeNodes[BB] = IDomNode->addChild(C);
+ }
+
+ inline NodeT *getIDom(NodeT *BB) const {
+ return IDoms.lookup(BB);
+ }
+
+ inline void addRoot(NodeT* BB) {
+ this->Roots.push_back(BB);
+ }
+
+public:
+ /// recalculate - compute a dominator tree for the given function
+ template<class FT>
+ void recalculate(FT& F) {
+ typedef GraphTraits<FT*> TraitsTy;
+ reset();
+ this->Vertex.push_back(0);
+
+ if (!this->IsPostDominators) {
+ // Initialize root
+ NodeT *entry = TraitsTy::getEntryNode(&F);
+ this->Roots.push_back(entry);
+ this->IDoms[entry] = 0;
+ this->DomTreeNodes[entry] = 0;
+
+ Calculate<FT, NodeT*>(*this, F);
+ } else {
+ // Initialize the roots list
+ for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
+ E = TraitsTy::nodes_end(&F); I != E; ++I) {
+ if (std::distance(TraitsTy::child_begin(I),
+ TraitsTy::child_end(I)) == 0)
+ addRoot(I);
+
+ // Prepopulate maps so that we don't get iterator invalidation issues later.
+ this->IDoms[I] = 0;
+ this->DomTreeNodes[I] = 0;
+ }
+
+ Calculate<FT, Inverse<NodeT*> >(*this, F);
+ }
+ }
+};
+
+// These two functions are declared out of line as a workaround for building
+// with old (< r147295) versions of clang because of pr11642.
+template<class NodeT>
+bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
+ if (A == B)
+ return true;
+
+ // Cast away the const qualifiers here. This is ok since
+ // this function doesn't actually return the values returned
+ // from getNode.
+ return dominates(getNode(const_cast<NodeT *>(A)),
+ getNode(const_cast<NodeT *>(B)));
+}
+template<class NodeT>
+bool
+DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
+ if (A == B)
+ return false;
+
+ // Cast away the const qualifiers here. This is ok since
+ // this function doesn't actually return the values returned
+ // from getNode.
+ return dominates(getNode(const_cast<NodeT *>(A)),
+ getNode(const_cast<NodeT *>(B)));
+}
+
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
+
+//===-------------------------------------
+/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
+/// compute a normal dominator tree.
+///
+class DominatorTree : public FunctionPass {
+public:
+ static char ID; // Pass ID, replacement for typeid
+ DominatorTreeBase<BasicBlock>* DT;
+
+ DominatorTree() : FunctionPass(ID) {
+ initializeDominatorTreePass(*PassRegistry::getPassRegistry());
+ DT = new DominatorTreeBase<BasicBlock>(false);
+ }
+
+ ~DominatorTree() {
+ delete DT;
+ }
+
+ DominatorTreeBase<BasicBlock>& getBase() { return *DT; }
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<BasicBlock*> &getRoots() const {
+ return DT->getRoots();
+ }
+
+ inline BasicBlock *getRoot() const {
+ return DT->getRoot();
+ }
+
+ inline DomTreeNode *getRootNode() const {
+ return DT->getRootNode();
+ }
+
+ /// compare - Return false if the other dominator tree matches this
+ /// dominator tree. Otherwise return true.
+ inline bool compare(DominatorTree &Other) const {
+ DomTreeNode *R = getRootNode();
+ DomTreeNode *OtherR = Other.getRootNode();
+
+ if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
+ return true;
+
+ if (DT->compare(Other.getBase()))
+ return true;
+
+ return false;
+ }
+
+ virtual bool runOnFunction(Function &F);
+
+ virtual void verifyAnalysis() const;
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ inline bool dominates(const DomTreeNode* A, const DomTreeNode* B) const {
+ return DT->dominates(A, B);
+ }
+
+ inline bool dominates(const BasicBlock* A, const BasicBlock* B) const {
+ return DT->dominates(A, B);
+ }
+
+ // dominates - Return true if Def dominates a use in User. This performs
+ // the special checks necessary if Def and User are in the same basic block.
+ // Note that Def doesn't dominate a use in Def itself!
+ bool dominates(const Instruction *Def, const Use &U) const;
+ bool dominates(const Instruction *Def, const Instruction *User) const;
+ bool dominates(const Instruction *Def, const BasicBlock *BB) const;
+
+ bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ bool properlyDominates(const BasicBlock *A, const BasicBlock *B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ /// findNearestCommonDominator - Find nearest common dominator basic block
+ /// for basic block A and B. If there is no such block then return NULL.
+ inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
+ return DT->findNearestCommonDominator(A, B);
+ }
+
+ inline const BasicBlock *findNearestCommonDominator(const BasicBlock *A,
+ const BasicBlock *B) {
+ return DT->findNearestCommonDominator(A, B);
+ }
+
+ inline DomTreeNode *operator[](BasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ /// getNode - return the (Post)DominatorTree node for the specified basic
+ /// block. This is the same as using operator[] on this class.
+ ///
+ inline DomTreeNode *getNode(BasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ /// addNewBlock - Add a new node to the dominator tree information. This
+ /// creates a new node as a child of DomBB dominator node,linking it into
+ /// the children list of the immediate dominator.
+ inline DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) {
+ return DT->addNewBlock(BB, DomBB);
+ }
+
+ /// changeImmediateDominator - This method is used to update the dominator
+ /// tree information when a node's immediate dominator changes.
+ ///
+ inline void changeImmediateDominator(BasicBlock *N, BasicBlock* NewIDom) {
+ DT->changeImmediateDominator(N, NewIDom);
+ }
+
+ inline void changeImmediateDominator(DomTreeNode *N, DomTreeNode* NewIDom) {
+ DT->changeImmediateDominator(N, NewIDom);
+ }
+
+ /// eraseNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Removes node from its immediate dominator's
+ /// children list. Deletes dominator node associated with basic block BB.
+ inline void eraseNode(BasicBlock *BB) {
+ DT->eraseNode(BB);
+ }
+
+ /// splitBlock - BB is split and now it has one successor. Update dominator
+ /// tree to reflect this change.
+ inline void splitBlock(BasicBlock* NewBB) {
+ DT->splitBlock(NewBB);
+ }
+
+ bool isReachableFromEntry(const BasicBlock* A) const {
+ return DT->isReachableFromEntry(A);
+ }
+
+ bool isReachableFromEntry(const Use &U) const;
+
+
+ virtual void releaseMemory() {
+ DT->releaseMemory();
+ }
+
+ virtual void print(raw_ostream &OS, const Module* M= 0) const;
+};
+
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+template <> struct GraphTraits<DomTreeNode*> {
+ typedef DomTreeNode NodeType;
+ typedef NodeType::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(NodeType *N) {
+ return N;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+
+ typedef df_iterator<DomTreeNode*> nodes_iterator;
+
+ static nodes_iterator nodes_begin(DomTreeNode *N) {
+ return df_begin(getEntryNode(N));
+ }
+
+ static nodes_iterator nodes_end(DomTreeNode *N) {
+ return df_end(getEntryNode(N));
+ }
+};
+
+template <> struct GraphTraits<DominatorTree*>
+ : public GraphTraits<DomTreeNode*> {
+ static NodeType *getEntryNode(DominatorTree *DT) {
+ return DT->getRootNode();
+ }
+
+ static nodes_iterator nodes_begin(DominatorTree *N) {
+ return df_begin(getEntryNode(N));
+ }
+
+ static nodes_iterator nodes_end(DominatorTree *N) {
+ return df_end(getEntryNode(N));
+ }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/FindUsedTypes.h b/contrib/llvm/include/llvm/Analysis/FindUsedTypes.h
new file mode 100644
index 000000000000..b22cb8813513
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/FindUsedTypes.h
@@ -0,0 +1,66 @@
+//===- llvm/Analysis/FindUsedTypes.h - Find all Types in use ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to seek out all of the types in use by the program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_FINDUSEDTYPES_H
+#define LLVM_ANALYSIS_FINDUSEDTYPES_H
+
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class Type;
+class Value;
+
+class FindUsedTypes : public ModulePass {
+ SetVector<Type *> UsedTypes;
+public:
+ static char ID; // Pass identification, replacement for typeid
+ FindUsedTypes() : ModulePass(ID) {
+ initializeFindUsedTypesPass(*PassRegistry::getPassRegistry());
+ }
+
+ /// getTypes - After the pass has been run, return the set containing all of
+ /// the types used in the module.
+ ///
+ const SetVector<Type *> &getTypes() const { return UsedTypes; }
+
+ /// Print the types found in the module. If the optional Module parameter is
+ /// passed in, then the types are printed symbolically if possible, using the
+ /// symbol table from the module.
+ ///
+ void print(raw_ostream &o, const Module *M) const;
+
+private:
+ /// IncorporateType - Incorporate one type and all of its subtypes into the
+ /// collection of used types.
+ ///
+ void IncorporateType(Type *Ty);
+
+ /// IncorporateValue - Incorporate all of the types used by this value.
+ ///
+ void IncorporateValue(const Value *V);
+
+public:
+ /// run - This incorporates all types used by the specified module
+ bool runOnModule(Module &M);
+
+ /// getAnalysisUsage - We do not modify anything.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/IVUsers.h b/contrib/llvm/include/llvm/Analysis/IVUsers.h
new file mode 100644
index 000000000000..2bf79b9c932b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/IVUsers.h
@@ -0,0 +1,185 @@
+//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- 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 bookkeeping for "interesting" users of expressions
+// computed from induction variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_IVUSERS_H
+#define LLVM_ANALYSIS_IVUSERS_H
+
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/ScalarEvolutionNormalization.h"
+#include "llvm/Support/ValueHandle.h"
+
+namespace llvm {
+
+class DominatorTree;
+class Instruction;
+class Value;
+class IVUsers;
+class ScalarEvolution;
+class SCEV;
+class IVUsers;
+class TargetData;
+
+/// IVStrideUse - Keep track of one use of a strided induction variable.
+/// The Expr member keeps track of the expression, User is the actual user
+/// instruction of the operand, and 'OperandValToReplace' is the operand of
+/// the User that is the use.
+class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
+ friend class IVUsers;
+public:
+ IVStrideUse(IVUsers *P, Instruction* U, Value *O)
+ : CallbackVH(U), Parent(P), OperandValToReplace(O) {
+ }
+
+ /// getUser - Return the user instruction for this use.
+ Instruction *getUser() const {
+ return cast<Instruction>(getValPtr());
+ }
+
+ /// setUser - Assign a new user instruction for this use.
+ void setUser(Instruction *NewUser) {
+ setValPtr(NewUser);
+ }
+
+ /// getOperandValToReplace - Return the Value of the operand in the user
+ /// instruction that this IVStrideUse is representing.
+ Value *getOperandValToReplace() const {
+ return OperandValToReplace;
+ }
+
+ /// setOperandValToReplace - Assign a new Value as the operand value
+ /// to replace.
+ void setOperandValToReplace(Value *Op) {
+ OperandValToReplace = Op;
+ }
+
+ /// getPostIncLoops - Return the set of loops for which the expression has
+ /// been adjusted to use post-inc mode.
+ const PostIncLoopSet &getPostIncLoops() const {
+ return PostIncLoops;
+ }
+
+ /// transformToPostInc - Transform the expression to post-inc form for the
+ /// given loop.
+ void transformToPostInc(const Loop *L);
+
+private:
+ /// Parent - a pointer to the IVUsers that owns this IVStrideUse.
+ IVUsers *Parent;
+
+ /// OperandValToReplace - The Value of the operand in the user instruction
+ /// that this IVStrideUse is representing.
+ WeakVH OperandValToReplace;
+
+ /// PostIncLoops - The set of loops for which Expr has been adjusted to
+ /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
+ PostIncLoopSet PostIncLoops;
+
+ /// Deleted - Implementation of CallbackVH virtual function to
+ /// receive notification when the User is deleted.
+ virtual void deleted();
+};
+
+template<> struct ilist_traits<IVStrideUse>
+ : public ilist_default_traits<IVStrideUse> {
+ // createSentinel is used to get hold of a node that marks the end of
+ // the list...
+ // The sentinel is relative to this instance, so we use a non-static
+ // method.
+ IVStrideUse *createSentinel() const {
+ // since i(p)lists always publicly derive from the corresponding
+ // traits, placing a data member in this class will augment i(p)list.
+ // But since the NodeTy is expected to publicly derive from
+ // ilist_node<NodeTy>, there is a legal viable downcast from it
+ // to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
+ // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
+ // forbidden (save the ilist_node<NodeTy>) so no one will ever notice
+ // the superposition.
+ return static_cast<IVStrideUse*>(&Sentinel);
+ }
+ static void destroySentinel(IVStrideUse*) {}
+
+ IVStrideUse *provideInitialHead() const { return createSentinel(); }
+ IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
+ static void noteHead(IVStrideUse*, IVStrideUse*) {}
+
+private:
+ mutable ilist_node<IVStrideUse> Sentinel;
+};
+
+class IVUsers : public LoopPass {
+ friend class IVStrideUse;
+ Loop *L;
+ LoopInfo *LI;
+ DominatorTree *DT;
+ ScalarEvolution *SE;
+ TargetData *TD;
+ SmallPtrSet<Instruction*,16> Processed;
+
+ /// IVUses - A list of all tracked IV uses of induction variable expressions
+ /// we are interested in.
+ ilist<IVStrideUse> IVUses;
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
+
+ virtual void releaseMemory();
+
+public:
+ static char ID; // Pass ID, replacement for typeid
+ IVUsers();
+
+ Loop *getLoop() const { return L; }
+
+ /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
+ /// reducible SCEV, recursively add its users to the IVUsesByStride set and
+ /// return true. Otherwise, return false.
+ bool AddUsersIfInteresting(Instruction *I);
+
+ IVStrideUse &AddUser(Instruction *User, Value *Operand);
+
+ /// getReplacementExpr - Return a SCEV expression which computes the
+ /// value of the OperandValToReplace of the given IVStrideUse.
+ const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
+
+ /// getExpr - Return the expression for the use.
+ const SCEV *getExpr(const IVStrideUse &IU) const;
+
+ const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
+
+ typedef ilist<IVStrideUse>::iterator iterator;
+ typedef ilist<IVStrideUse>::const_iterator const_iterator;
+ iterator begin() { return IVUses.begin(); }
+ iterator end() { return IVUses.end(); }
+ const_iterator begin() const { return IVUses.begin(); }
+ const_iterator end() const { return IVUses.end(); }
+ bool empty() const { return IVUses.empty(); }
+
+ bool isIVUserOrOperand(Instruction *Inst) const {
+ return Processed.count(Inst);
+ }
+
+ void print(raw_ostream &OS, const Module* = 0) const;
+
+ /// dump - This method is used for debugging.
+ void dump() const;
+protected:
+ bool AddUsersImpl(Instruction *I, SmallPtrSet<Loop*,16> &SimpleLoopNests);
+};
+
+Pass *createIVUsersPass();
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/InlineCost.h b/contrib/llvm/include/llvm/Analysis/InlineCost.h
new file mode 100644
index 000000000000..691c2d19be9a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/InlineCost.h
@@ -0,0 +1,136 @@
+//===- InlineCost.h - Cost analysis for inliner -----------------*- 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 heuristics for inlining decisions.
+//
+//===----------------------------------------------------------------------===//
+
+#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 <cassert>
+#include <climits>
+#include <vector>
+
+namespace llvm {
+
+ class CallSite;
+ class TargetData;
+
+ namespace InlineConstants {
+ // Various magic constants used to adjust heuristics.
+ const int InstrCost = 5;
+ const int IndirectCallThreshold = 100;
+ const int CallPenalty = 25;
+ const int LastCallToStaticBonus = -15000;
+ const int ColdccPenalty = 2000;
+ const int NoreturnPenalty = 10000;
+ }
+
+ /// \brief Represents the cost of inlining a function.
+ ///
+ /// This supports special values for functions which should "always" or
+ /// "never" be inlined. Otherwise, the cost represents a unitless amount;
+ /// smaller values increase the likelihood of the function being inlined.
+ ///
+ /// Objects of this type also provide the adjusted threshold for inlining
+ /// based on the information available for a particular callsite. They can be
+ /// directly tested to determine if inlining should occur given the cost and
+ /// threshold for this cost metric.
+ class InlineCost {
+ enum SentinelValues {
+ AlwaysInlineCost = INT_MIN,
+ NeverInlineCost = INT_MAX
+ };
+
+ /// \brief The estimated cost of inlining this callsite.
+ const int Cost;
+
+ /// \brief The adjusted threshold against which this cost was computed.
+ const int Threshold;
+
+ // Trivial constructor, interesting logic in the factory functions below.
+ InlineCost(int Cost, int Threshold)
+ : Cost(Cost), Threshold(Threshold) {}
+
+ public:
+ static InlineCost get(int Cost, int Threshold) {
+ assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
+ assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
+ return InlineCost(Cost, Threshold);
+ }
+ static InlineCost getAlways() {
+ return InlineCost(AlwaysInlineCost, 0);
+ }
+ static InlineCost getNever() {
+ return InlineCost(NeverInlineCost, 0);
+ }
+
+ /// \brief Test whether the inline cost is low enough for inlining.
+ operator bool() const {
+ return Cost < Threshold;
+ }
+
+ bool isAlways() const { return Cost == AlwaysInlineCost; }
+ bool isNever() const { return Cost == NeverInlineCost; }
+ bool isVariable() const { return !isAlways() && !isNever(); }
+
+ /// \brief Get the inline cost estimate.
+ /// It is an error to call this on an "always" or "never" InlineCost.
+ int getCost() const {
+ assert(isVariable() && "Invalid access of InlineCost");
+ return Cost;
+ }
+
+ /// \brief Get the cost delta from the threshold for inlining.
+ /// Only valid if the cost is of the variable kind. Returns a negative
+ /// value if the cost is too high to inline.
+ int getCostDelta() const { return Threshold - getCost(); }
+ };
+
+ /// InlineCostAnalyzer - Cost analyzer used by inliner.
+ class InlineCostAnalyzer {
+ // TargetData if available, or null.
+ const TargetData *TD;
+
+ public:
+ InlineCostAnalyzer(): TD(0) {}
+
+ void setTargetData(const TargetData *TData) { TD = TData; }
+
+ /// \brief Get an InlineCost object representing the cost of inlining this
+ /// callsite.
+ ///
+ /// Note that threshold is passed into this function. Only costs below the
+ /// threshold are computed with any accuracy. The threshold can be used to
+ /// 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.
+ //
+ // 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);
+ };
+
+ /// callIsSmall - If a call is likely to lower to a single target instruction,
+ /// or is otherwise deemed small return true.
+ bool callIsSmall(const Function *Callee);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h b/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h
new file mode 100644
index 000000000000..152e885bf667
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -0,0 +1,218 @@
+//===-- InstructionSimplify.h - Fold instructions into simpler forms ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares routines for folding instructions into simpler forms
+// that do not require creating new instructions. This does constant folding
+// ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
+// returning a constant ("and i32 %x, 0" -> "0") or an already existing value
+// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
+// then it dominates the original instruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
+#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
+
+namespace llvm {
+ template<typename T>
+ class ArrayRef;
+ class DominatorTree;
+ class Instruction;
+ class TargetData;
+ class TargetLibraryInfo;
+ class Type;
+ class Value;
+
+ /// 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 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 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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 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 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 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,
+ 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,
+ 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,
+ 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 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 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 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,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
+ /// can fold the result. If not, this returns null.
+ Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const TargetData *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,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ //=== Helper functions for higher up the class hierarchy.
+
+
+ /// 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 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 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,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+
+ /// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses
+ /// recursively.
+ ///
+ /// This first performs a normal RAUW of I with SimpleV. It then recursively
+ /// attempts to simplify those users updated by the operation. The 'I'
+ /// instruction must not be equal to the simplified value 'SimpleV'.
+ ///
+ /// The function returns true if any simplifications were performed.
+ bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
+ const TargetData *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+
+ /// \brief Recursively attempt to simplify an instruction.
+ ///
+ /// This routine uses SimplifyInstruction to simplify 'I', and if successful
+ /// replaces uses of 'I' with the simplified value. It then recurses on each
+ /// of the users impacted. It returns true if any simplifications were
+ /// performed.
+ bool recursivelySimplifyInstruction(Instruction *I,
+ const TargetData *TD = 0,
+ const TargetLibraryInfo *TLI = 0,
+ const DominatorTree *DT = 0);
+} // end namespace llvm
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Analysis/Interval.h b/contrib/llvm/include/llvm/Analysis/Interval.h
new file mode 100644
index 000000000000..ca8ad73131a9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Interval.h
@@ -0,0 +1,153 @@
+//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Interval class, which
+// represents a set of CFG nodes and is a portion of an interval partition.
+//
+// Intervals have some interesting and useful properties, including the
+// following:
+// 1. The header node of an interval dominates all of the elements of the
+// interval
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTERVAL_H
+#define LLVM_INTERVAL_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include <vector>
+
+namespace llvm {
+
+class BasicBlock;
+class raw_ostream;
+
+//===----------------------------------------------------------------------===//
+//
+/// Interval Class - An Interval is a set of nodes defined such that every node
+/// in the interval has all of its predecessors in the interval (except for the
+/// header)
+///
+class Interval {
+ /// HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
+ /// interval. Also, any loops in this interval must go through the HeaderNode.
+ ///
+ BasicBlock *HeaderNode;
+public:
+ typedef std::vector<BasicBlock*>::iterator succ_iterator;
+ typedef std::vector<BasicBlock*>::iterator pred_iterator;
+ typedef std::vector<BasicBlock*>::iterator node_iterator;
+
+ inline Interval(BasicBlock *Header) : HeaderNode(Header) {
+ Nodes.push_back(Header);
+ }
+
+ inline Interval(const Interval &I) // copy ctor
+ : HeaderNode(I.HeaderNode), Nodes(I.Nodes), Successors(I.Successors) {}
+
+ inline BasicBlock *getHeaderNode() const { return HeaderNode; }
+
+ /// Nodes - The basic blocks in this interval.
+ ///
+ std::vector<BasicBlock*> Nodes;
+
+ /// Successors - List of BasicBlocks that are reachable directly from nodes in
+ /// this interval, but are not in the interval themselves.
+ /// These nodes necessarily must be header nodes for other intervals.
+ ///
+ std::vector<BasicBlock*> Successors;
+
+ /// Predecessors - List of BasicBlocks that have this Interval's header block
+ /// as one of their successors.
+ ///
+ std::vector<BasicBlock*> Predecessors;
+
+ /// contains - Find out if a basic block is in this interval
+ inline bool contains(BasicBlock *BB) const {
+ for (unsigned i = 0; i < Nodes.size(); ++i)
+ if (Nodes[i] == BB) return true;
+ return false;
+ // I don't want the dependency on <algorithm>
+ //return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
+ }
+
+ /// isSuccessor - find out if a basic block is a successor of this Interval
+ inline bool isSuccessor(BasicBlock *BB) const {
+ for (unsigned i = 0; i < Successors.size(); ++i)
+ if (Successors[i] == BB) return true;
+ return false;
+ // I don't want the dependency on <algorithm>
+ //return find(Successors.begin(), Successors.end(), BB) != Successors.end();
+ }
+
+ /// Equality operator. It is only valid to compare two intervals from the
+ /// same partition, because of this, all we have to check is the header node
+ /// for equality.
+ ///
+ inline bool operator==(const Interval &I) const {
+ return HeaderNode == I.HeaderNode;
+ }
+
+ /// isLoop - Find out if there is a back edge in this interval...
+ bool isLoop() const;
+
+ /// print - Show contents in human readable format...
+ void print(raw_ostream &O) const;
+};
+
+/// succ_begin/succ_end - define methods so that Intervals may be used
+/// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
+///
+inline Interval::succ_iterator succ_begin(Interval *I) {
+ return I->Successors.begin();
+}
+inline Interval::succ_iterator succ_end(Interval *I) {
+ return I->Successors.end();
+}
+
+/// pred_begin/pred_end - define methods so that Intervals may be used
+/// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
+///
+inline Interval::pred_iterator pred_begin(Interval *I) {
+ return I->Predecessors.begin();
+}
+inline Interval::pred_iterator pred_end(Interval *I) {
+ return I->Predecessors.end();
+}
+
+template <> struct GraphTraits<Interval*> {
+ typedef Interval NodeType;
+ typedef Interval::succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Interval *I) { return I; }
+
+ /// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+template <> struct GraphTraits<Inverse<Interval*> > {
+ typedef Interval NodeType;
+ typedef Interval::pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<Interval *> G) { return G.Graph; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/IntervalIterator.h b/contrib/llvm/include/llvm/Analysis/IntervalIterator.h
new file mode 100644
index 000000000000..0968c7468e68
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/IntervalIterator.h
@@ -0,0 +1,259 @@
+//===- IntervalIterator.h - Interval Iterator Declaration -------*- 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 an iterator that enumerates the intervals in a control flow
+// graph of some sort. This iterator is parametric, allowing iterator over the
+// following types of graphs:
+//
+// 1. A Function* object, composed of BasicBlock nodes.
+// 2. An IntervalPartition& object, composed of Interval nodes.
+//
+// This iterator is defined to walk the control flow graph, returning intervals
+// in depth first order. These intervals are completely filled in except for
+// the predecessor fields (the successor information is filled in however).
+//
+// By default, the intervals created by this iterator are deleted after they
+// are no longer any use to the iterator. This behavior can be changed by
+// passing a false value into the intervals_begin() function. This causes the
+// IOwnMem member to be set, and the intervals to not be deleted.
+//
+// It is only safe to use this if all of the intervals are deleted by the caller
+// and all of the intervals are processed. However, the user of the iterator is
+// not allowed to modify or delete the intervals until after the iterator has
+// been used completely. The IntervalPartition class uses this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTERVAL_ITERATOR_H
+#define LLVM_INTERVAL_ITERATOR_H
+
+#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/Function.h"
+#include "llvm/Support/CFG.h"
+#include <algorithm>
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+// getNodeHeader - Given a source graph node and the source graph, return the
+// BasicBlock that is the header node. This is the opposite of
+// getSourceGraphNode.
+//
+inline BasicBlock *getNodeHeader(BasicBlock *BB) { return BB; }
+inline BasicBlock *getNodeHeader(Interval *I) { return I->getHeaderNode(); }
+
+// getSourceGraphNode - Given a BasicBlock and the source graph, return the
+// source graph node that corresponds to the BasicBlock. This is the opposite
+// of getNodeHeader.
+//
+inline BasicBlock *getSourceGraphNode(Function *, BasicBlock *BB) {
+ return BB;
+}
+inline Interval *getSourceGraphNode(IntervalPartition *IP, BasicBlock *BB) {
+ return IP->getBlockInterval(BB);
+}
+
+// addNodeToInterval - This method exists to assist the generic ProcessNode
+// with the task of adding a node to the new interval, depending on the
+// type of the source node. In the case of a CFG source graph (BasicBlock
+// case), the BasicBlock itself is added to the interval.
+//
+inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
+ Int->Nodes.push_back(BB);
+}
+
+// addNodeToInterval - This method exists to assist the generic ProcessNode
+// with the task of adding a node to the new interval, depending on the
+// type of the source node. In the case of a CFG source graph (BasicBlock
+// case), the BasicBlock itself is added to the interval. In the case of
+// an IntervalPartition source graph (Interval case), all of the member
+// BasicBlocks are added to the interval.
+//
+inline void addNodeToInterval(Interval *Int, Interval *I) {
+ // Add all of the nodes in I as new nodes in Int.
+ copy(I->Nodes.begin(), I->Nodes.end(), back_inserter(Int->Nodes));
+}
+
+
+
+
+
+template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy*>,
+ class IGT = GraphTraits<Inverse<NodeTy*> > >
+class IntervalIterator {
+ std::vector<std::pair<Interval*, typename Interval::succ_iterator> > IntStack;
+ std::set<BasicBlock*> Visited;
+ OrigContainer_t *OrigContainer;
+ bool IOwnMem; // If True, delete intervals when done with them
+ // See file header for conditions of use
+public:
+ typedef IntervalIterator<NodeTy, OrigContainer_t> _Self;
+ typedef std::forward_iterator_tag iterator_category;
+
+ IntervalIterator() {} // End iterator, empty stack
+ IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
+ OrigContainer = M;
+ if (!ProcessInterval(&M->front())) {
+ llvm_unreachable("ProcessInterval should never fail for first interval!");
+ }
+ }
+
+ IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
+ OrigContainer = &IP;
+ if (!ProcessInterval(IP.getRootInterval())) {
+ llvm_unreachable("ProcessInterval should never fail for first interval!");
+ }
+ }
+
+ inline ~IntervalIterator() {
+ if (IOwnMem)
+ while (!IntStack.empty()) {
+ delete operator*();
+ IntStack.pop_back();
+ }
+ }
+
+ inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;}
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline const Interval *operator*() const { return IntStack.back().first; }
+ inline Interval *operator*() { return IntStack.back().first; }
+ inline const Interval *operator->() const { return operator*(); }
+ inline Interval *operator->() { return operator*(); }
+
+ _Self& operator++() { // Preincrement
+ assert(!IntStack.empty() && "Attempting to use interval iterator at end!");
+ do {
+ // All of the intervals on the stack have been visited. Try visiting
+ // their successors now.
+ Interval::succ_iterator &SuccIt = IntStack.back().second,
+ EndIt = succ_end(IntStack.back().first);
+ while (SuccIt != EndIt) { // Loop over all interval succs
+ bool Done = ProcessInterval(getSourceGraphNode(OrigContainer, *SuccIt));
+ ++SuccIt; // Increment iterator
+ if (Done) return *this; // Found a new interval! Use it!
+ }
+
+ // Free interval memory... if necessary
+ if (IOwnMem) delete IntStack.back().first;
+
+ // We ran out of successors for this interval... pop off the stack
+ IntStack.pop_back();
+ } while (!IntStack.empty());
+
+ return *this;
+ }
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ // ProcessInterval - This method is used during the construction of the
+ // interval graph. It walks through the source graph, recursively creating
+ // an interval per invokation until the entire graph is covered. This uses
+ // the ProcessNode method to add all of the nodes to the interval.
+ //
+ // This method is templated because it may operate on two different source
+ // graphs: a basic block graph, or a preexisting interval graph.
+ //
+ bool ProcessInterval(NodeTy *Node) {
+ BasicBlock *Header = getNodeHeader(Node);
+ if (Visited.count(Header)) return false;
+
+ Interval *Int = new Interval(Header);
+ Visited.insert(Header); // The header has now been visited!
+
+ // Check all of our successors to see if they are in the interval...
+ for (typename GT::ChildIteratorType I = GT::child_begin(Node),
+ E = GT::child_end(Node); I != E; ++I)
+ ProcessNode(Int, getSourceGraphNode(OrigContainer, *I));
+
+ IntStack.push_back(std::make_pair(Int, succ_begin(Int)));
+ return true;
+ }
+
+ // ProcessNode - This method is called by ProcessInterval to add nodes to the
+ // interval being constructed, and it is also called recursively as it walks
+ // the source graph. A node is added to the current interval only if all of
+ // its predecessors are already in the graph. This also takes care of keeping
+ // the successor set of an interval up to date.
+ //
+ // This method is templated because it may operate on two different source
+ // graphs: a basic block graph, or a preexisting interval graph.
+ //
+ void ProcessNode(Interval *Int, NodeTy *Node) {
+ assert(Int && "Null interval == bad!");
+ assert(Node && "Null Node == bad!");
+
+ BasicBlock *NodeHeader = getNodeHeader(Node);
+
+ if (Visited.count(NodeHeader)) { // Node already been visited?
+ if (Int->contains(NodeHeader)) { // Already in this interval...
+ return;
+ } else { // In other interval, add as successor
+ if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
+ Int->Successors.push_back(NodeHeader);
+ }
+ } else { // Otherwise, not in interval yet
+ for (typename IGT::ChildIteratorType I = IGT::child_begin(Node),
+ E = IGT::child_end(Node); I != E; ++I) {
+ if (!Int->contains(*I)) { // If pred not in interval, we can't be
+ if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
+ Int->Successors.push_back(NodeHeader);
+ return; // See you later
+ }
+ }
+
+ // If we get here, then all of the predecessors of BB are in the interval
+ // already. In this case, we must add BB to the interval!
+ addNodeToInterval(Int, Node);
+ Visited.insert(NodeHeader); // The node has now been visited!
+
+ if (Int->isSuccessor(NodeHeader)) {
+ // If we were in the successor list from before... remove from succ list
+ Int->Successors.erase(std::remove(Int->Successors.begin(),
+ Int->Successors.end(), NodeHeader),
+ Int->Successors.end());
+ }
+
+ // Now that we have discovered that Node is in the interval, perhaps some
+ // of its successors are as well?
+ for (typename GT::ChildIteratorType It = GT::child_begin(Node),
+ End = GT::child_end(Node); It != End; ++It)
+ ProcessNode(Int, getSourceGraphNode(OrigContainer, *It));
+ }
+ }
+};
+
+typedef IntervalIterator<BasicBlock, Function> function_interval_iterator;
+typedef IntervalIterator<Interval, IntervalPartition>
+ interval_part_interval_iterator;
+
+
+inline function_interval_iterator intervals_begin(Function *F,
+ bool DeleteInts = true) {
+ return function_interval_iterator(F, DeleteInts);
+}
+inline function_interval_iterator intervals_end(Function *) {
+ return function_interval_iterator();
+}
+
+inline interval_part_interval_iterator
+ intervals_begin(IntervalPartition &IP, bool DeleteIntervals = true) {
+ return interval_part_interval_iterator(IP, DeleteIntervals);
+}
+
+inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) {
+ return interval_part_interval_iterator();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/IntervalPartition.h b/contrib/llvm/include/llvm/Analysis/IntervalPartition.h
new file mode 100644
index 000000000000..df7313f18f3d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/IntervalPartition.h
@@ -0,0 +1,111 @@
+//===- IntervalPartition.h - Interval partition Calculation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the IntervalPartition class, which
+// calculates and represents the interval partition of a function, or a
+// preexisting interval partition.
+//
+// In this way, the interval partition may be used to reduce a flow graph down
+// to its degenerate single node interval partition (unless it is irreducible).
+//
+// TODO: The IntervalPartition class should take a bool parameter that tells
+// whether it should add the "tails" of an interval to an interval itself or if
+// they should be represented as distinct intervals.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTERVAL_PARTITION_H
+#define LLVM_INTERVAL_PARTITION_H
+
+#include "llvm/Analysis/Interval.h"
+#include "llvm/Pass.h"
+#include <map>
+
+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
+// nodes following it.
+//
+class IntervalPartition : public FunctionPass {
+ typedef std::map<BasicBlock*, Interval*> IntervalMapTy;
+ IntervalMapTy IntervalMap;
+
+ typedef std::vector<Interval*> IntervalListTy;
+ Interval *RootInterval;
+ std::vector<Interval*> Intervals;
+
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ IntervalPartition() : FunctionPass(ID), RootInterval(0) {
+ initializeIntervalPartitionPass(*PassRegistry::getPassRegistry());
+ }
+
+ // run - Calculate the interval partition for this function
+ virtual bool runOnFunction(Function &F);
+
+ // IntervalPartition ctor - Build a reduced interval partition from an
+ // existing interval graph. This takes an additional boolean parameter to
+ // distinguish it from a copy constructor. Always pass in false for now.
+ //
+ IntervalPartition(IntervalPartition &I, bool);
+
+ // print - Show contents in human readable format...
+ virtual void print(raw_ostream &O, const Module* = 0) const;
+
+ // getRootInterval() - Return the root interval that contains the starting
+ // block of the function.
+ inline Interval *getRootInterval() { return RootInterval; }
+
+ // isDegeneratePartition() - Returns true if the interval partition contains
+ // a single interval, and thus cannot be simplified anymore.
+ bool isDegeneratePartition() { return Intervals.size() == 1; }
+
+ // TODO: isIrreducible - look for triangle graph.
+
+ // getBlockInterval - Return the interval that a basic block exists in.
+ inline Interval *getBlockInterval(BasicBlock *BB) {
+ IntervalMapTy::iterator I = IntervalMap.find(BB);
+ return I != IntervalMap.end() ? I->second : 0;
+ }
+
+ // getAnalysisUsage - Implement the Pass API
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ // Interface to Intervals vector...
+ const std::vector<Interval*> &getIntervals() const { return Intervals; }
+
+ // releaseMemory - Reset state back to before function was analyzed
+ void releaseMemory();
+
+private:
+ // addIntervalToPartition - Add an interval to the internal list of intervals,
+ // and then add mappings from all of the basic blocks in the interval to the
+ // interval itself (in the IntervalMap).
+ //
+ void addIntervalToPartition(Interval *I);
+
+ // updatePredecessors - Interval generation only sets the successor fields of
+ // the interval data structures. After interval generation is complete,
+ // run through all of the intervals and propagate successor info as
+ // predecessor info.
+ //
+ void updatePredecessors(Interval *Int);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h b/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h
new file mode 100644
index 000000000000..065c230fb2fd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LazyValueInfo.h
@@ -0,0 +1,81 @@
+//===- LazyValueInfo.h - Value constraint analysis --------------*- 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 interface for lazy computation of value constraint
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
+#define LLVM_ANALYSIS_LAZYVALUEINFO_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+ class Constant;
+ class TargetData;
+ class TargetLibraryInfo;
+ class Value;
+
+/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
+/// information.
+class LazyValueInfo : public FunctionPass {
+ class TargetData *TD;
+ class TargetLibraryInfo *TLI;
+ void *PImpl;
+ LazyValueInfo(const LazyValueInfo&); // DO NOT IMPLEMENT.
+ void operator=(const LazyValueInfo&); // DO NOT IMPLEMENT.
+public:
+ static char ID;
+ LazyValueInfo() : FunctionPass(ID), PImpl(0) {
+ initializeLazyValueInfoPass(*PassRegistry::getPassRegistry());
+ }
+ ~LazyValueInfo() { assert(PImpl == 0 && "releaseMemory not called"); }
+
+ /// Tristate - This is used to return true/false/dunno results.
+ enum Tristate {
+ Unknown = -1, False = 0, True = 1
+ };
+
+
+ // Public query interface.
+
+ /// getPredicateOnEdge - Determine whether the specified value comparison
+ /// with a constant is known to be true or false on the specified CFG edge.
+ /// Pred is a CmpInst predicate.
+ Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
+ BasicBlock *FromBB, BasicBlock *ToBB);
+
+
+ /// getConstant - Determine whether the specified value is known to be a
+ /// constant at the end of the specified block. Return null if not.
+ Constant *getConstant(Value *V, BasicBlock *BB);
+
+ /// getConstantOnEdge - Determine whether the specified value is known to be a
+ /// constant on the specified edge. Return null if not.
+ Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB);
+
+ /// threadEdge - Inform the analysis cache that we have threaded an edge from
+ /// PredBB to OldSucc to be from PredBB to NewSucc instead.
+ void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
+
+ /// eraseBlock - Inform the analysis cache that we have erased a block.
+ void eraseBlock(BasicBlock *BB);
+
+ // Implementation boilerplate.
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+ virtual bool runOnFunction(Function &F);
+};
+
+} // end namespace llvm
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h b/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h
new file mode 100644
index 000000000000..243234b75635
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LibCallAliasAnalysis.h
@@ -0,0 +1,73 @@
+//===- LibCallAliasAnalysis.h - Implement AliasAnalysis for libcalls ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LibCallAliasAnalysis class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LIBCALL_AA_H
+#define LLVM_ANALYSIS_LIBCALL_AA_H
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ class LibCallInfo;
+ struct LibCallFunctionInfo;
+
+ /// LibCallAliasAnalysis - Alias analysis driven from LibCallInfo.
+ struct LibCallAliasAnalysis : public FunctionPass, public AliasAnalysis {
+ static char ID; // Class identification
+
+ LibCallInfo *LCI;
+
+ explicit LibCallAliasAnalysis(LibCallInfo *LC = 0)
+ : FunctionPass(ID), LCI(LC) {
+ initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
+ }
+ explicit LibCallAliasAnalysis(char &ID, LibCallInfo *LC)
+ : FunctionPass(ID), LCI(LC) {
+ initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
+ }
+ ~LibCallAliasAnalysis();
+
+ ModRefResult getModRefInfo(ImmutableCallSite CS,
+ const Location &Loc);
+
+ ModRefResult getModRefInfo(ImmutableCallSite CS1,
+ ImmutableCallSite CS2) {
+ // TODO: Could compare two direct calls against each other if we cared to.
+ return AliasAnalysis::getModRefInfo(CS1, CS2);
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ virtual bool runOnFunction(Function &F) {
+ InitializeAliasAnalysis(this); // set up super class
+ return false;
+ }
+
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it
+ /// should override this to adjust the this pointer as needed for the
+ /// specified pass info.
+ virtual void *getAdjustedAnalysisPointer(const void *PI) {
+ if (PI == &AliasAnalysis::ID)
+ return (AliasAnalysis*)this;
+ return this;
+ }
+
+ private:
+ ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
+ ImmutableCallSite CS,
+ const Location &Loc);
+ };
+} // End of llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LibCallSemantics.h b/contrib/llvm/include/llvm/Analysis/LibCallSemantics.h
new file mode 100644
index 000000000000..f5a9e96cbdd0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LibCallSemantics.h
@@ -0,0 +1,167 @@
+//===- LibCallSemantics.h - Describe library semantics --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces that can be used to describe language specific
+// runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H
+#define LLVM_ANALYSIS_LIBCALLSEMANTICS_H
+
+#include "llvm/Analysis/AliasAnalysis.h"
+
+namespace llvm {
+
+ /// LibCallLocationInfo - This struct describes a set of memory locations that
+ /// are accessed by libcalls. Identification of a location is doing with a
+ /// simple callback function.
+ ///
+ /// For example, the LibCallInfo may be set up to model the behavior of
+ /// standard libm functions. The location that they may be interested in is
+ /// an abstract location that represents errno for the current target. In
+ /// this case, a location for errno is anything such that the predicate
+ /// returns true. On Mac OS/X, this predicate would return true if the
+ /// pointer is the result of a call to "__error()".
+ ///
+ /// Locations can also be defined in a constant-sensitive way. For example,
+ /// it is possible to define a location that returns true iff it is passed
+ /// into the call as a specific argument. This is useful for modeling things
+ /// like "printf", which can store to memory, but only through pointers passed
+ /// with a '%n' constraint.
+ ///
+ struct LibCallLocationInfo {
+ // TODO: Flags: isContextSensitive etc.
+
+ /// isLocation - Return a LocResult if the specified pointer refers to this
+ /// location for the specified call site. This returns "Yes" if we can tell
+ /// that the pointer *does definitely* refer to the location, "No" if we can
+ /// tell that the location *definitely does not* refer to the location, and
+ /// returns "Unknown" if we cannot tell for certain.
+ enum LocResult {
+ Yes, No, Unknown
+ };
+ LocResult (*isLocation)(ImmutableCallSite CS,
+ const AliasAnalysis::Location &Loc);
+ };
+
+ /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
+ /// records the behavior of one libcall that is known by the optimizer. This
+ /// captures things like the side effects of the call. Side effects are
+ /// modeled both universally (in the readnone/readonly) sense, but also
+ /// potentially against a set of abstract locations defined by the optimizer.
+ /// This allows an optimizer to define that some libcall (e.g. sqrt) is
+ /// side-effect free except that it might modify errno (thus, the call is
+ /// *not* universally readonly). Or it might say that the side effects
+ /// are unknown other than to say that errno is not modified.
+ ///
+ struct LibCallFunctionInfo {
+ /// Name - This is the name of the libcall this describes.
+ const char *Name;
+
+ /// TODO: Constant folding function: Constant* vector -> Constant*.
+
+ /// UniversalBehavior - This captures the absolute mod/ref behavior without
+ /// any specific context knowledge. For example, if the function is known
+ /// to be readonly, this would be set to 'ref'. If known to be readnone,
+ /// this is set to NoModRef.
+ AliasAnalysis::ModRefResult UniversalBehavior;
+
+ /// LocationMRInfo - This pair captures info about whether a specific
+ /// location is modified or referenced by a libcall.
+ struct LocationMRInfo {
+ /// LocationID - ID # of the accessed location or ~0U for array end.
+ unsigned LocationID;
+ /// MRInfo - Mod/Ref info for this location.
+ AliasAnalysis::ModRefResult MRInfo;
+ };
+
+ /// DetailsType - Indicate the sense of the LocationDetails array. This
+ /// controls how the LocationDetails array is interpreted.
+ enum {
+ /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the
+ /// *only* mod/ref behavior of this function is captured by the
+ /// LocationDetails array. If we are trying to say that 'sqrt' can only
+ /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails
+ /// array and have DetailsType set to DoesOnly.
+ DoesOnly,
+
+ /// DoesNot - If DetailsType is set to DoesNot, then the sense of the
+ /// LocationDetails array is completely inverted. This means that we *do
+ /// not* know everything about the side effects of this libcall, but we do
+ /// know things that the libcall cannot do. This is useful for complex
+ /// functions like 'ctime' which have crazy mod/ref behavior, but are
+ /// known to never read or write errno. In this case, we'd have
+ /// {errnoloc,modref} in the LocationDetails array and DetailsType would
+ /// be set to DoesNot, indicating that ctime does not read or write the
+ /// errno location.
+ DoesNot
+ } DetailsType;
+
+ /// LocationDetails - This is a pointer to an array of LocationMRInfo
+ /// structs which indicates the behavior of the libcall w.r.t. specific
+ /// locations. For example, if this libcall is known to only modify
+ /// 'errno', it would have a LocationDetails array with the errno ID and
+ /// 'mod' in it. See the DetailsType field for how this is interpreted.
+ ///
+ /// In the "DoesOnly" case, this information is 'may' information for: there
+ /// is no guarantee that the specified side effect actually does happen,
+ /// just that it could. In the "DoesNot" case, this is 'must not' info.
+ ///
+ /// If this pointer is null, no details are known.
+ ///
+ const LocationMRInfo *LocationDetails;
+ };
+
+
+ /// LibCallInfo - Abstract interface to query about library call information.
+ /// Instances of this class return known information about some set of
+ /// libcalls.
+ ///
+ class LibCallInfo {
+ // Implementation details of this object, private.
+ mutable void *Impl;
+ mutable const LibCallLocationInfo *Locations;
+ mutable unsigned NumLocations;
+ public:
+ LibCallInfo() : Impl(0), Locations(0), NumLocations(0) {}
+ virtual ~LibCallInfo();
+
+ //===------------------------------------------------------------------===//
+ // Accessor Methods: Efficient access to contained data.
+ //===------------------------------------------------------------------===//
+
+ /// getLocationInfo - Return information about the specified LocationID.
+ const LibCallLocationInfo &getLocationInfo(unsigned LocID) const;
+
+
+ /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
+ /// the specified function if we have it. If not, return null.
+ const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
+
+
+ //===------------------------------------------------------------------===//
+ // Implementation Methods: Subclasses should implement these.
+ //===------------------------------------------------------------------===//
+
+ /// getLocationInfo - Return descriptors for the locations referenced by
+ /// this set of libcalls.
+ virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const {
+ return 0;
+ }
+
+ /// getFunctionInfoArray - Return an array of descriptors that describe the
+ /// set of libcalls represented by this LibCallInfo object. This array is
+ /// terminated by an entry with a NULL name.
+ virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0;
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/Lint.h b/contrib/llvm/include/llvm/Analysis/Lint.h
new file mode 100644
index 000000000000..7c88b137ec3b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Lint.h
@@ -0,0 +1,49 @@
+//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- 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 lint interfaces that can be used for some sanity checking
+// of input to the system, and for checking that transformations
+// haven't done something bad. In contrast to the Verifier, the Lint checker
+// checks for undefined behavior or constructions with likely unintended
+// behavior.
+//
+// To see what specifically is checked, look at Lint.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LINT_H
+#define LLVM_ANALYSIS_LINT_H
+
+namespace llvm {
+
+class FunctionPass;
+class Module;
+class Function;
+
+/// @brief Create a lint pass.
+///
+/// Check a module or function.
+FunctionPass *createLintPass();
+
+/// @brief Check a module.
+///
+/// This should only be used for debugging, because it plays games with
+/// PassManagers and stuff.
+void lintModule(
+ const Module &M ///< The module to be checked
+);
+
+// lintFunction - Check a function.
+void lintFunction(
+ const Function &F ///< The function to be checked
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/Loads.h b/contrib/llvm/include/llvm/Analysis/Loads.h
new file mode 100644
index 000000000000..5f0aefbeb015
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Loads.h
@@ -0,0 +1,57 @@
+//===- Loads.h - Local load analysis --------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares simple local analyses for load instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOADS_H
+#define LLVM_ANALYSIS_LOADS_H
+
+#include "llvm/BasicBlock.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class TargetData;
+class MDNode;
+
+/// isSafeToLoadUnconditionally - Return true if we know that executing a load
+/// from this value cannot trap. If it is not obviously safe to load from the
+/// 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);
+
+/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
+/// the instruction before ScanFrom) checking to see if we have the value at
+/// the memory address *Ptr locally available within a small number of
+/// instructions. If the value is available, return it.
+///
+/// If not, return the iterator for the last validated instruction that the
+/// value would be live through. If we scanned the entire block and didn't
+/// find something that invalidates *Ptr or provides it, ScanFrom would be
+/// left at begin() and this returns null. ScanFrom could also be left
+///
+/// MaxInstsToScan specifies the maximum instructions to scan in the block.
+/// If it is set to 0, it will scan the whole block. You can also optionally
+/// specify an alias analysis implementation, which makes this more precise.
+///
+/// If TBAATag is non-null and a load or store is found, the TBAA tag from the
+/// load or store is recorded there. If there is no TBAA tag or if no access
+/// is found, it is left unmodified.
+Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
+ BasicBlock::iterator &ScanFrom,
+ unsigned MaxInstsToScan = 6,
+ AliasAnalysis *AA = 0,
+ MDNode **TBAATag = 0);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LoopDependenceAnalysis.h b/contrib/llvm/include/llvm/Analysis/LoopDependenceAnalysis.h
new file mode 100644
index 000000000000..f195d2782418
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LoopDependenceAnalysis.h
@@ -0,0 +1,124 @@
+//===- 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/contrib/llvm/include/llvm/Analysis/LoopInfo.h b/contrib/llvm/include/llvm/Analysis/LoopInfo.h
new file mode 100644
index 000000000000..91feaaac038d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LoopInfo.h
@@ -0,0 +1,1100 @@
+//===- llvm/Analysis/LoopInfo.h - Natural Loop Calculator -------*- 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 LoopInfo class that is used to identify natural loops
+// and determine the loop depth of various nodes of the CFG. A natural loop
+// has exactly one entry-point, which is called the header. Note that natural
+// loops may actually be several loops that share the same header node.
+//
+// This analysis calculates the nesting structure of loops in a function. For
+// each natural loop identified, this analysis identifies natural loops
+// contained entirely within the loop and the basic blocks the make up the loop.
+//
+// It can calculate on the fly various bits of information, for example:
+//
+// * whether there is a preheader for the loop
+// * the number of back edges to the header
+// * whether or not a particular block branches out of the loop
+// * the successor blocks of the loop
+// * the loop depth
+// * etc...
+//
+//===----------------------------------------------------------------------===//
+
+#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/Analysis/Dominators.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <map>
+
+namespace llvm {
+
+template<typename T>
+static void RemoveFromVector(std::vector<T*> &V, T *N) {
+ typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
+ assert(I != V.end() && "N is not in this list!");
+ V.erase(I);
+}
+
+class DominatorTree;
+class LoopInfo;
+class Loop;
+class PHINode;
+template<class N, class M> class LoopInfoBase;
+template<class N, class M> class LoopBase;
+
+//===----------------------------------------------------------------------===//
+/// LoopBase class - Instances of this class are used to represent loops that
+/// are detected in the flow graph
+///
+template<class BlockT, class LoopT>
+class LoopBase {
+ LoopT *ParentLoop;
+ // SubLoops - Loops contained entirely within this one.
+ std::vector<LoopT *> SubLoops;
+
+ // 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> &);
+public:
+ /// Loop ctor - This creates an empty loop.
+ LoopBase() : ParentLoop(0) {}
+ ~LoopBase() {
+ for (size_t i = 0, e = SubLoops.size(); i != e; ++i)
+ delete SubLoops[i];
+ }
+
+ /// getLoopDepth - Return the nesting level of this loop. An outer-most
+ /// loop has depth 1, for consistency with loop depth values used for basic
+ /// blocks, where depth 0 is used for blocks not inside any loops.
+ unsigned getLoopDepth() const {
+ unsigned D = 1;
+ for (const LoopT *CurLoop = ParentLoop; CurLoop;
+ CurLoop = CurLoop->ParentLoop)
+ ++D;
+ return D;
+ }
+ BlockT *getHeader() const { return Blocks.front(); }
+ LoopT *getParentLoop() const { return ParentLoop; }
+
+ /// contains - Return true if the specified loop is contained within in
+ /// this loop.
+ ///
+ bool contains(const LoopT *L) const {
+ if (L == this) return true;
+ if (L == 0) return false;
+ return contains(L->getParentLoop());
+ }
+
+ /// contains - Return true if the specified basic block is in this loop.
+ ///
+ bool contains(const BlockT *BB) const {
+ return std::find(block_begin(), block_end(), BB) != block_end();
+ }
+
+ /// contains - Return true if the specified instruction is in this loop.
+ ///
+ template<class InstT>
+ bool contains(const InstT *Inst) const {
+ return contains(Inst->getParent());
+ }
+
+ /// iterator/begin/end - Return the loops contained entirely within this loop.
+ ///
+ const std::vector<LoopT *> &getSubLoops() const { return SubLoops; }
+ typedef typename std::vector<LoopT *>::const_iterator iterator;
+ iterator begin() const { return SubLoops.begin(); }
+ iterator end() const { return SubLoops.end(); }
+ bool empty() const { return SubLoops.empty(); }
+
+ /// getBlocks - Get a list of the basic blocks which make up this loop.
+ ///
+ const std::vector<BlockT*> &getBlocks() const { return Blocks; }
+ typedef typename std::vector<BlockT*>::const_iterator block_iterator;
+ block_iterator block_begin() const { return Blocks.begin(); }
+ block_iterator block_end() const { return Blocks.end(); }
+
+ /// getNumBlocks - Get the number of blocks in this loop in constant time.
+ unsigned getNumBlocks() const {
+ return Blocks.size();
+ }
+
+ /// isLoopExiting - True if terminator in the block can branch to another
+ /// block that is outside of the current loop.
+ ///
+ bool isLoopExiting(const BlockT *BB) const {
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (typename BlockTraits::ChildIteratorType SI =
+ BlockTraits::child_begin(const_cast<BlockT*>(BB)),
+ SE = BlockTraits::child_end(const_cast<BlockT*>(BB)); SI != SE; ++SI) {
+ if (!contains(*SI))
+ return true;
+ }
+ return false;
+ }
+
+ /// getNumBackEdges - Calculate the number of back edges to the loop header
+ ///
+ unsigned getNumBackEdges() const {
+ unsigned NumBackEdges = 0;
+ BlockT *H = getHeader();
+
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType I =
+ InvBlockTraits::child_begin(const_cast<BlockT*>(H)),
+ E = InvBlockTraits::child_end(const_cast<BlockT*>(H)); I != E; ++I)
+ if (contains(*I))
+ ++NumBackEdges;
+
+ return NumBackEdges;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // APIs for simple analysis of the loop.
+ //
+ // Note that all of these methods can fail on general loops (ie, there may not
+ // be a preheader, etc). For best success, the loop simplification and
+ // induction variable canonicalization pass should be used to normalize loops
+ // for easy analysis. These methods assume canonical loops.
+
+ /// getExitingBlocks - Return all blocks inside the loop that have successors
+ /// outside of the loop. These are the blocks _inside of the current loop_
+ /// which branch out. The returned list is always unique.
+ ///
+ void getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) {
+ // Not in current loop? It must be an exit block.
+ ExitingBlocks.push_back(*BI);
+ break;
+ }
+ }
+
+ /// getExitingBlock - If getExitingBlocks would return exactly one block,
+ /// return that block. Otherwise return null.
+ BlockT *getExitingBlock() const {
+ SmallVector<BlockT*, 8> ExitingBlocks;
+ getExitingBlocks(ExitingBlocks);
+ if (ExitingBlocks.size() == 1)
+ return ExitingBlocks[0];
+ return 0;
+ }
+
+ /// getExitBlocks - Return all of the successor blocks of this loop. These
+ /// are the blocks _outside of the current loop_ which are branched to.
+ ///
+ void getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitBlocks.push_back(*I);
+ }
+
+ /// getExitBlock - If getExitBlocks would return exactly one block,
+ /// return that block. Otherwise return null.
+ BlockT *getExitBlock() const {
+ SmallVector<BlockT*, 8> ExitBlocks;
+ getExitBlocks(ExitBlocks);
+ if (ExitBlocks.size() == 1)
+ return ExitBlocks[0];
+ return 0;
+ }
+
+ /// Edge type.
+ typedef std::pair<BlockT*, BlockT*> Edge;
+
+ /// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
+ template <typename EdgeT>
+ void getExitEdges(SmallVectorImpl<EdgeT> &ExitEdges) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ array_pod_sort(LoopBBs.begin(), LoopBBs.end());
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
+ for (typename BlockTraits::ChildIteratorType I =
+ BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
+ I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitEdges.push_back(EdgeT(*BI, *I));
+ }
+
+ /// getLoopPreheader - If there is a preheader for this loop, return it. A
+ /// loop has a preheader if there is only one edge to the header of the loop
+ /// from outside of the loop. If this is the case, the block branching to the
+ /// header of the loop is the preheader node.
+ ///
+ /// This method returns null if there is no preheader for the loop.
+ ///
+ BlockT *getLoopPreheader() const {
+ // Keep track of nodes outside the loop branching to the header...
+ BlockT *Out = getLoopPredecessor();
+ if (!Out) return 0;
+
+ // Make sure there is only one exit out of the preheader.
+ typedef GraphTraits<BlockT*> BlockTraits;
+ typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
+ ++SI;
+ if (SI != BlockTraits::child_end(Out))
+ return 0; // Multiple exits from the block, must not be a preheader.
+
+ // The predecessor has exactly one successor, so it is a preheader.
+ return Out;
+ }
+
+ /// getLoopPredecessor - If the given loop's header has exactly one unique
+ /// predecessor outside the loop, return it. Otherwise return null.
+ /// This is less strict that the loop "preheader" concept, which requires
+ /// the predecessor to have exactly one successor.
+ ///
+ BlockT *getLoopPredecessor() const {
+ // Keep track of nodes outside the loop branching to the header...
+ BlockT *Out = 0;
+
+ // Loop over the predecessors of the header node...
+ BlockT *Header = getHeader();
+ typedef GraphTraits<BlockT*> BlockTraits;
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(Header),
+ PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
+ typename InvBlockTraits::NodeType *N = *PI;
+ if (!contains(N)) { // If the block is not in the loop...
+ if (Out && Out != N)
+ return 0; // Multiple predecessors outside the loop
+ Out = N;
+ }
+ }
+
+ // Make sure there is only one exit out of the preheader.
+ assert(Out && "Header of loop has no predecessors from outside loop?");
+ return Out;
+ }
+
+ /// getLoopLatch - If there is a single latch block for this loop, return it.
+ /// A latch block is a block that contains a branch back to the header.
+ BlockT *getLoopLatch() const {
+ BlockT *Header = getHeader();
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(Header);
+ typename InvBlockTraits::ChildIteratorType PE =
+ InvBlockTraits::child_end(Header);
+ BlockT *Latch = 0;
+ for (; PI != PE; ++PI) {
+ typename InvBlockTraits::NodeType *N = *PI;
+ if (contains(N)) {
+ if (Latch) return 0;
+ Latch = N;
+ }
+ }
+
+ return Latch;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // APIs for updating loop information after changing the CFG
+ //
+
+ /// addBasicBlockToLoop - This method is used by other analyses to update loop
+ /// information. NewBB is set to be a new member of the current loop.
+ /// Because of this, it is added as a member of all parent loops, and is added
+ /// to the specified LoopInfo object as being in the current basic block. It
+ /// is not valid to replace the loop header with this method.
+ ///
+ void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LI);
+
+ /// replaceChildLoopWith - This is used when splitting loops up. It replaces
+ /// the OldChild entry in our children list with NewChild, and updates the
+ /// parent pointer of OldChild to be null and the NewChild to be this loop.
+ /// This updates the loop depth of the new child.
+ void replaceChildLoopWith(LoopT *OldChild,
+ LoopT *NewChild) {
+ assert(OldChild->ParentLoop == this && "This loop is already broken!");
+ assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
+ typename std::vector<LoopT *>::iterator I =
+ std::find(SubLoops.begin(), SubLoops.end(), OldChild);
+ assert(I != SubLoops.end() && "OldChild not in loop!");
+ *I = NewChild;
+ OldChild->ParentLoop = 0;
+ NewChild->ParentLoop = static_cast<LoopT *>(this);
+ }
+
+ /// addChildLoop - Add the specified loop to be a child of this loop. This
+ /// updates the loop depth of the new child.
+ ///
+ void addChildLoop(LoopT *NewChild) {
+ assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
+ NewChild->ParentLoop = static_cast<LoopT *>(this);
+ SubLoops.push_back(NewChild);
+ }
+
+ /// removeChildLoop - This removes the specified child from being a subloop of
+ /// this loop. The loop is not deleted, as it will presumably be inserted
+ /// into another loop.
+ LoopT *removeChildLoop(iterator I) {
+ assert(I != SubLoops.end() && "Cannot remove end iterator!");
+ LoopT *Child = *I;
+ assert(Child->ParentLoop == this && "Child is not a child of this loop!");
+ SubLoops.erase(SubLoops.begin()+(I-begin()));
+ Child->ParentLoop = 0;
+ return Child;
+ }
+
+ /// addBlockEntry - This adds a basic block directly to the basic block list.
+ /// This should only be used by transformations that create new loops. Other
+ /// transformations should use addBasicBlockToLoop.
+ void addBlockEntry(BlockT *BB) {
+ Blocks.push_back(BB);
+ }
+
+ /// moveToHeader - This method is used to move BB (which must be part of this
+ /// loop) to be the loop header of the loop (the block that dominates all
+ /// others).
+ void moveToHeader(BlockT *BB) {
+ if (Blocks[0] == BB) return;
+ for (unsigned i = 0; ; ++i) {
+ assert(i != Blocks.size() && "Loop does not contain BB!");
+ if (Blocks[i] == BB) {
+ Blocks[i] = Blocks[0];
+ Blocks[0] = BB;
+ return;
+ }
+ }
+ }
+
+ /// removeBlockFromLoop - This removes the specified basic block from the
+ /// current loop, updating the Blocks as appropriate. This does not update
+ /// the mapping in the LoopInfo class.
+ void removeBlockFromLoop(BlockT *BB) {
+ RemoveFromVector(Blocks, BB);
+ }
+
+ /// verifyLoop - Verify loop structure
+ void verifyLoop() const {
+#ifndef NDEBUG
+ assert(!Blocks.empty() && "Loop header is missing");
+
+ // Setup for using a depth-first iterator to visit every block in the loop.
+ SmallVector<BlockT*, 8> ExitBBs;
+ getExitBlocks(ExitBBs);
+ llvm::SmallPtrSet<BlockT*, 8> VisitSet;
+ VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
+ df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
+ BI = df_ext_begin(getHeader(), VisitSet),
+ BE = df_ext_end(getHeader(), VisitSet);
+
+ // Keep track of the number of BBs visited.
+ unsigned NumVisited = 0;
+
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ // Check the individual blocks.
+ for ( ; BI != BE; ++BI) {
+ BlockT *BB = *BI;
+ bool HasInsideLoopSuccs = false;
+ bool HasInsideLoopPreds = false;
+ SmallVector<BlockT *, 2> OutsideLoopPreds;
+
+ typedef GraphTraits<BlockT*> BlockTraits;
+ for (typename BlockTraits::ChildIteratorType SI =
+ BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB);
+ SI != SE; ++SI)
+ if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *SI)) {
+ HasInsideLoopSuccs = true;
+ break;
+ }
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType PI =
+ InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB);
+ PI != PE; ++PI) {
+ BlockT *N = *PI;
+ if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N))
+ HasInsideLoopPreds = true;
+ else
+ OutsideLoopPreds.push_back(N);
+ }
+
+ if (BB == getHeader()) {
+ assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");
+ } else if (!OutsideLoopPreds.empty()) {
+ // A non-header loop shouldn't be reachable from outside the loop,
+ // though it is permitted if the predecessor is not itself actually
+ // reachable.
+ BlockT *EntryBB = BB->getParent()->begin();
+ for (df_iterator<BlockT *> NI = df_begin(EntryBB),
+ NE = df_end(EntryBB); NI != NE; ++NI)
+ for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
+ assert(*NI != OutsideLoopPreds[i] &&
+ "Loop has multiple entry points!");
+ }
+ assert(HasInsideLoopPreds && "Loop block has no in-loop predecessors!");
+ assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!");
+ assert(BB != getHeader()->getParent()->begin() &&
+ "Loop contains function entry block!");
+
+ NumVisited++;
+ }
+
+ assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
+
+ // Check the subloops.
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ // Each block in each subloop should be contained within this loop.
+ for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
+ BI != BE; ++BI) {
+ assert(std::binary_search(LoopBBs.begin(), LoopBBs.end(), *BI) &&
+ "Loop does not contain all the blocks of a subloop!");
+ }
+
+ // Check the parent loop pointer.
+ if (ParentLoop) {
+ assert(std::find(ParentLoop->begin(), ParentLoop->end(), this) !=
+ ParentLoop->end() &&
+ "Loop is not a subloop of its parent!");
+ }
+#endif
+ }
+
+ /// verifyLoop - Verify loop structure of this loop and all nested loops.
+ void verifyLoopNest(DenseSet<const LoopT*> *Loops) const {
+ Loops->insert(static_cast<const LoopT *>(this));
+ // Verify this loop.
+ verifyLoop();
+ // Verify the subloops.
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (*I)->verifyLoopNest(Loops);
+ }
+
+ void print(raw_ostream &OS, unsigned Depth = 0) const {
+ OS.indent(Depth*2) << "Loop at depth " << getLoopDepth()
+ << " containing: ";
+
+ for (unsigned i = 0; i < getBlocks().size(); ++i) {
+ if (i) OS << ",";
+ BlockT *BB = getBlocks()[i];
+ WriteAsOperand(OS, BB, false);
+ if (BB == getHeader()) OS << "<header>";
+ if (BB == getLoopLatch()) OS << "<latch>";
+ if (isLoopExiting(BB)) OS << "<exiting>";
+ }
+ OS << "\n";
+
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (*I)->print(OS, Depth+2);
+ }
+
+protected:
+ friend class LoopInfoBase<BlockT, LoopT>;
+ explicit LoopBase(BlockT *BB) : ParentLoop(0) {
+ Blocks.push_back(BB);
+ }
+};
+
+template<class BlockT, class LoopT>
+raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
+ Loop.print(OS);
+ return OS;
+}
+
+class Loop : public LoopBase<BasicBlock, Loop> {
+public:
+ Loop() {}
+
+ /// isLoopInvariant - Return true if the specified value is loop invariant
+ ///
+ bool isLoopInvariant(Value *V) const;
+
+ /// hasLoopInvariantOperands - Return true if all the operands of the
+ /// specified instruction are loop invariant.
+ bool hasLoopInvariantOperands(Instruction *I) const;
+
+ /// makeLoopInvariant - If the given value is an instruction inside of the
+ /// loop and it can be hoisted, do so to make it trivially loop-invariant.
+ /// Return true if the value after any hoisting is loop invariant. This
+ /// function can be used as a slightly more aggressive replacement for
+ /// isLoopInvariant.
+ ///
+ /// If InsertPt is specified, it is the point to hoist instructions to.
+ /// If null, the terminator of the loop preheader is used.
+ ///
+ bool makeLoopInvariant(Value *V, bool &Changed,
+ Instruction *InsertPt = 0) const;
+
+ /// makeLoopInvariant - If the given instruction is inside of the
+ /// loop and it can be hoisted, do so to make it trivially loop-invariant.
+ /// Return true if the instruction after any hoisting is loop invariant. This
+ /// function can be used as a slightly more aggressive replacement for
+ /// isLoopInvariant.
+ ///
+ /// If InsertPt is specified, it is the point to hoist instructions to.
+ /// If null, the terminator of the loop preheader is used.
+ ///
+ bool makeLoopInvariant(Instruction *I, bool &Changed,
+ Instruction *InsertPt = 0) const;
+
+ /// getCanonicalInductionVariable - Check to see if the loop has a canonical
+ /// induction variable: an integer recurrence that starts at 0 and increments
+ /// by one each time through the loop. If so, return the phi node that
+ /// corresponds to it.
+ ///
+ /// The IndVarSimplify pass transforms loops to have a canonical induction
+ /// variable.
+ ///
+ PHINode *getCanonicalInductionVariable() const;
+
+ /// isLCSSAForm - Return true if the Loop is in LCSSA form
+ bool isLCSSAForm(DominatorTree &DT) const;
+
+ /// isLoopSimplifyForm - Return true if the Loop is in the form that
+ /// the LoopSimplify form transforms loops to, which is sometimes called
+ /// normal form.
+ bool isLoopSimplifyForm() const;
+
+ /// isSafeToClone - Return true if the loop body is safe to clone in practice.
+ bool isSafeToClone() const;
+
+ /// hasDedicatedExits - Return true if no exit block for the loop
+ /// has a predecessor that is outside the loop.
+ bool hasDedicatedExits() const;
+
+ /// getUniqueExitBlocks - Return all unique successor blocks of this loop.
+ /// These are the blocks _outside of the current loop_ which are branched to.
+ /// This assumes that loop exits are in canonical form.
+ ///
+ void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const;
+
+ /// getUniqueExitBlock - If getUniqueExitBlocks would return exactly one
+ /// block, return that block. Otherwise return null.
+ BasicBlock *getUniqueExitBlock() const;
+
+ void dump() const;
+
+private:
+ friend class LoopInfoBase<BasicBlock, Loop>;
+ explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
+};
+
+//===----------------------------------------------------------------------===//
+/// LoopInfo - This class builds and contains all of the top level loop
+/// structures in the specified function.
+///
+
+template<class BlockT, class LoopT>
+class LoopInfoBase {
+ // BBMap - Mapping of basic blocks to the inner most loop they occur in
+ DenseMap<BlockT *, LoopT *> BBMap;
+ std::vector<LoopT *> TopLevelLoops;
+ friend class LoopBase<BlockT, LoopT>;
+ friend class LoopInfo;
+
+ void operator=(const LoopInfoBase &); // do not implement
+ LoopInfoBase(const LoopInfo &); // do not implement
+public:
+ LoopInfoBase() { }
+ ~LoopInfoBase() { releaseMemory(); }
+
+ void releaseMemory() {
+ for (typename std::vector<LoopT *>::iterator I =
+ TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I)
+ delete *I; // Delete all of the loops...
+
+ BBMap.clear(); // Reset internal state of analysis
+ TopLevelLoops.clear();
+ }
+
+ /// iterator/begin/end - The interface to the top-level loops in the current
+ /// function.
+ ///
+ typedef typename std::vector<LoopT *>::const_iterator iterator;
+ iterator begin() const { return TopLevelLoops.begin(); }
+ iterator end() const { return TopLevelLoops.end(); }
+ bool empty() const { return TopLevelLoops.empty(); }
+
+ /// getLoopFor - Return the inner most loop that BB lives in. If a basic
+ /// block is in no loop (for example the entry node), null is returned.
+ ///
+ LoopT *getLoopFor(const BlockT *BB) const {
+ return BBMap.lookup(const_cast<BlockT*>(BB));
+ }
+
+ /// operator[] - same as getLoopFor...
+ ///
+ const LoopT *operator[](const BlockT *BB) const {
+ return getLoopFor(BB);
+ }
+
+ /// getLoopDepth - Return the loop nesting level of the specified block. A
+ /// depth of 0 means the block is not inside any loop.
+ ///
+ unsigned getLoopDepth(const BlockT *BB) const {
+ const LoopT *L = getLoopFor(BB);
+ return L ? L->getLoopDepth() : 0;
+ }
+
+ // isLoopHeader - True if the block is a loop header node
+ bool isLoopHeader(BlockT *BB) const {
+ const LoopT *L = getLoopFor(BB);
+ return L && L->getHeader() == BB;
+ }
+
+ /// removeLoop - This removes the specified top-level loop from this loop info
+ /// object. The loop is not deleted, as it will presumably be inserted into
+ /// another loop.
+ LoopT *removeLoop(iterator I) {
+ assert(I != end() && "Cannot remove end iterator!");
+ LoopT *L = *I;
+ assert(L->getParentLoop() == 0 && "Not a top-level loop!");
+ TopLevelLoops.erase(TopLevelLoops.begin() + (I-begin()));
+ return L;
+ }
+
+ /// changeLoopFor - Change the top-level loop that contains BB to the
+ /// specified loop. This should be used by transformations that restructure
+ /// the loop hierarchy tree.
+ void changeLoopFor(BlockT *BB, LoopT *L) {
+ if (!L) {
+ BBMap.erase(BB);
+ return;
+ }
+ BBMap[BB] = L;
+ }
+
+ /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+ /// list with the indicated loop.
+ void changeTopLevelLoop(LoopT *OldLoop,
+ LoopT *NewLoop) {
+ typename std::vector<LoopT *>::iterator I =
+ std::find(TopLevelLoops.begin(), TopLevelLoops.end(), OldLoop);
+ assert(I != TopLevelLoops.end() && "Old loop not at top level!");
+ *I = NewLoop;
+ assert(NewLoop->ParentLoop == 0 && OldLoop->ParentLoop == 0 &&
+ "Loops already embedded into a subloop!");
+ }
+
+ /// addTopLevelLoop - This adds the specified loop to the collection of
+ /// top-level loops.
+ void addTopLevelLoop(LoopT *New) {
+ assert(New->getParentLoop() == 0 && "Loop already in subloop!");
+ TopLevelLoops.push_back(New);
+ }
+
+ /// removeBlock - This method completely removes BB from all data structures,
+ /// including all of the Loop objects it is nested in and our mapping from
+ /// BasicBlocks to loops.
+ void removeBlock(BlockT *BB) {
+ typename DenseMap<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
+ if (I != BBMap.end()) {
+ for (LoopT *L = I->second; L; L = L->getParentLoop())
+ L->removeBlockFromLoop(BB);
+
+ BBMap.erase(I);
+ }
+ }
+
+ // Internals
+
+ static bool isNotAlreadyContainedIn(const LoopT *SubLoop,
+ const LoopT *ParentLoop) {
+ if (SubLoop == 0) return true;
+ if (SubLoop == ParentLoop) return false;
+ return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop);
+ }
+
+ void Calculate(DominatorTreeBase<BlockT> &DT) {
+ BlockT *RootNode = DT.getRootNode()->getBlock();
+
+ for (df_iterator<BlockT*> NI = df_begin(RootNode),
+ NE = df_end(RootNode); NI != NE; ++NI)
+ if (LoopT *L = ConsiderForLoop(*NI, DT))
+ TopLevelLoops.push_back(L);
+ }
+
+ LoopT *ConsiderForLoop(BlockT *BB, DominatorTreeBase<BlockT> &DT) {
+ if (BBMap.count(BB)) return 0; // Haven't processed this node?
+
+ std::vector<BlockT *> TodoStack;
+
+ // Scan the predecessors of BB, checking to see if BB dominates any of
+ // them. This identifies backedges which target this node...
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType I =
+ InvBlockTraits::child_begin(BB), E = InvBlockTraits::child_end(BB);
+ I != E; ++I) {
+ typename InvBlockTraits::NodeType *N = *I;
+ // If BB dominates its predecessor...
+ if (DT.dominates(BB, N) && DT.isReachableFromEntry(N))
+ TodoStack.push_back(N);
+ }
+
+ if (TodoStack.empty()) return 0; // No backedges to this block...
+
+ // Create a new loop to represent this basic block...
+ LoopT *L = new LoopT(BB);
+ BBMap[BB] = L;
+
+ while (!TodoStack.empty()) { // Process all the nodes in the loop
+ BlockT *X = TodoStack.back();
+ TodoStack.pop_back();
+
+ if (!L->contains(X) && // As of yet unprocessed??
+ DT.isReachableFromEntry(X)) {
+ // Check to see if this block already belongs to a loop. If this occurs
+ // then we have a case where a loop that is supposed to be a child of
+ // the current loop was processed before the current loop. When this
+ // occurs, this child loop gets added to a part of the current loop,
+ // making it a sibling to the current loop. We have to reparent this
+ // loop.
+ if (LoopT *SubLoop =
+ const_cast<LoopT *>(getLoopFor(X)))
+ if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)){
+ // Remove the subloop from its current parent...
+ assert(SubLoop->ParentLoop && SubLoop->ParentLoop != L);
+ LoopT *SLP = SubLoop->ParentLoop; // SubLoopParent
+ typename std::vector<LoopT *>::iterator I =
+ std::find(SLP->SubLoops.begin(), SLP->SubLoops.end(), SubLoop);
+ assert(I != SLP->SubLoops.end() &&"SubLoop not a child of parent?");
+ SLP->SubLoops.erase(I); // Remove from parent...
+
+ // Add the subloop to THIS loop...
+ SubLoop->ParentLoop = L;
+ L->SubLoops.push_back(SubLoop);
+ }
+
+ // Normal case, add the block to our loop...
+ L->Blocks.push_back(X);
+
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+
+ // Add all of the predecessors of X to the end of the work stack...
+ TodoStack.insert(TodoStack.end(), InvBlockTraits::child_begin(X),
+ InvBlockTraits::child_end(X));
+ }
+ }
+
+ // If there are any loops nested within this loop, create them now!
+ for (typename std::vector<BlockT*>::iterator I = L->Blocks.begin(),
+ E = L->Blocks.end(); I != E; ++I)
+ if (LoopT *NewLoop = ConsiderForLoop(*I, DT)) {
+ L->SubLoops.push_back(NewLoop);
+ NewLoop->ParentLoop = L;
+ }
+
+ // Add the basic blocks that comprise this loop to the BBMap so that this
+ // loop can be found for them.
+ //
+ for (typename std::vector<BlockT*>::iterator I = L->Blocks.begin(),
+ E = L->Blocks.end(); I != E; ++I)
+ BBMap.insert(std::make_pair(*I, L));
+
+ // Now that we have a list of all of the child loops of this loop, check to
+ // see if any of them should actually be nested inside of each other. We
+ // can accidentally pull loops our of their parents, so we must make sure to
+ // organize the loop nests correctly now.
+ {
+ std::map<BlockT *, LoopT *> ContainingLoops;
+ for (unsigned i = 0; i != L->SubLoops.size(); ++i) {
+ LoopT *Child = L->SubLoops[i];
+ assert(Child->getParentLoop() == L && "Not proper child loop?");
+
+ if (LoopT *ContainingLoop = ContainingLoops[Child->getHeader()]) {
+ // If there is already a loop which contains this loop, move this loop
+ // into the containing loop.
+ MoveSiblingLoopInto(Child, ContainingLoop);
+ --i; // The loop got removed from the SubLoops list.
+ } else {
+ // This is currently considered to be a top-level loop. Check to see
+ // if any of the contained blocks are loop headers for subloops we
+ // have already processed.
+ for (unsigned b = 0, e = Child->Blocks.size(); b != e; ++b) {
+ LoopT *&BlockLoop = ContainingLoops[Child->Blocks[b]];
+ if (BlockLoop == 0) { // Child block not processed yet...
+ BlockLoop = Child;
+ } else if (BlockLoop != Child) {
+ LoopT *SubLoop = BlockLoop;
+ // Reparent all of the blocks which used to belong to BlockLoops
+ for (unsigned j = 0, f = SubLoop->Blocks.size(); j != f; ++j)
+ ContainingLoops[SubLoop->Blocks[j]] = Child;
+
+ // There is already a loop which contains this block, that means
+ // that we should reparent the loop which the block is currently
+ // considered to belong to to be a child of this loop.
+ MoveSiblingLoopInto(SubLoop, Child);
+ --i; // We just shrunk the SubLoops list.
+ }
+ }
+ }
+ }
+ }
+
+ return L;
+ }
+
+ /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside
+ /// of the NewParent Loop, instead of being a sibling of it.
+ void MoveSiblingLoopInto(LoopT *NewChild,
+ LoopT *NewParent) {
+ LoopT *OldParent = NewChild->getParentLoop();
+ assert(OldParent && OldParent == NewParent->getParentLoop() &&
+ NewChild != NewParent && "Not sibling loops!");
+
+ // Remove NewChild from being a child of OldParent
+ typename std::vector<LoopT *>::iterator I =
+ std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(),
+ NewChild);
+ assert(I != OldParent->SubLoops.end() && "Parent fields incorrect??");
+ OldParent->SubLoops.erase(I); // Remove from parent's subloops list
+ NewChild->ParentLoop = 0;
+
+ InsertLoopInto(NewChild, NewParent);
+ }
+
+ /// InsertLoopInto - This inserts loop L into the specified parent loop. If
+ /// the parent loop contains a loop which should contain L, the loop gets
+ /// inserted into L instead.
+ void InsertLoopInto(LoopT *L, LoopT *Parent) {
+ BlockT *LHeader = L->getHeader();
+ assert(Parent->contains(LHeader) &&
+ "This loop should not be inserted here!");
+
+ // Check to see if it belongs in a child loop...
+ for (unsigned i = 0, e = static_cast<unsigned>(Parent->SubLoops.size());
+ i != e; ++i)
+ if (Parent->SubLoops[i]->contains(LHeader)) {
+ InsertLoopInto(L, Parent->SubLoops[i]);
+ return;
+ }
+
+ // If not, insert it here!
+ Parent->SubLoops.push_back(L);
+ L->ParentLoop = Parent;
+ }
+
+ // Debugging
+
+ void print(raw_ostream &OS) const {
+ for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
+ TopLevelLoops[i]->print(OS);
+ #if 0
+ for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
+ E = BBMap.end(); I != E; ++I)
+ OS << "BB '" << I->first->getName() << "' level = "
+ << I->second->getLoopDepth() << "\n";
+ #endif
+ }
+};
+
+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
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ LoopInfo() : FunctionPass(ID) {
+ initializeLoopInfoPass(*PassRegistry::getPassRegistry());
+ }
+
+ LoopInfoBase<BasicBlock, Loop>& getBase() { return LI; }
+
+ /// iterator/begin/end - The interface to the top-level loops in the current
+ /// function.
+ ///
+ typedef LoopInfoBase<BasicBlock, Loop>::iterator iterator;
+ inline iterator begin() const { return LI.begin(); }
+ inline iterator end() const { return LI.end(); }
+ bool empty() const { return LI.empty(); }
+
+ /// getLoopFor - Return the inner most loop that BB lives in. If a basic
+ /// block is in no loop (for example the entry node), null is returned.
+ ///
+ inline Loop *getLoopFor(const BasicBlock *BB) const {
+ return LI.getLoopFor(BB);
+ }
+
+ /// operator[] - same as getLoopFor...
+ ///
+ inline const Loop *operator[](const BasicBlock *BB) const {
+ return LI.getLoopFor(BB);
+ }
+
+ /// getLoopDepth - Return the loop nesting level of the specified block. A
+ /// depth of 0 means the block is not inside any loop.
+ ///
+ inline unsigned getLoopDepth(const BasicBlock *BB) const {
+ return LI.getLoopDepth(BB);
+ }
+
+ // isLoopHeader - True if the block is a loop header node
+ inline bool isLoopHeader(BasicBlock *BB) const {
+ return LI.isLoopHeader(BB);
+ }
+
+ /// runOnFunction - Calculate the natural loop information.
+ ///
+ virtual bool runOnFunction(Function &F);
+
+ virtual void verifyAnalysis() const;
+
+ virtual void releaseMemory() { LI.releaseMemory(); }
+
+ virtual void print(raw_ostream &O, const Module* M = 0) const;
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// removeLoop - This removes the specified top-level loop from this loop info
+ /// object. The loop is not deleted, as it will presumably be inserted into
+ /// another loop.
+ inline Loop *removeLoop(iterator I) { return LI.removeLoop(I); }
+
+ /// changeLoopFor - Change the top-level loop that contains BB to the
+ /// specified loop. This should be used by transformations that restructure
+ /// the loop hierarchy tree.
+ inline void changeLoopFor(BasicBlock *BB, Loop *L) {
+ LI.changeLoopFor(BB, L);
+ }
+
+ /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+ /// list with the indicated loop.
+ inline void changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop) {
+ LI.changeTopLevelLoop(OldLoop, NewLoop);
+ }
+
+ /// addTopLevelLoop - This adds the specified loop to the collection of
+ /// top-level loops.
+ inline void addTopLevelLoop(Loop *New) {
+ LI.addTopLevelLoop(New);
+ }
+
+ /// removeBlock - This method completely removes BB from all data structures,
+ /// including all of the Loop objects it is nested in and our mapping from
+ /// BasicBlocks to loops.
+ void removeBlock(BasicBlock *BB) {
+ LI.removeBlock(BB);
+ }
+
+ /// updateUnloop - Update LoopInfo after removing the last backedge from a
+ /// loop--now the "unloop". This updates the loop forest and parent loops for
+ /// each block so that Unloop is no longer referenced, but the caller must
+ /// actually delete the Unloop object.
+ void updateUnloop(Loop *Unloop);
+
+ /// replacementPreservesLCSSAForm - Returns true if replacing From with To
+ /// everywhere is guaranteed to preserve LCSSA form.
+ bool replacementPreservesLCSSAForm(Instruction *From, Value *To) {
+ // Preserving LCSSA form is only problematic if the replacing value is an
+ // instruction.
+ Instruction *I = dyn_cast<Instruction>(To);
+ if (!I) return true;
+ // If both instructions are defined in the same basic block then replacement
+ // cannot break LCSSA form.
+ if (I->getParent() == From->getParent())
+ return true;
+ // If the instruction is not defined in a loop then it can safely replace
+ // anything.
+ Loop *ToLoop = getLoopFor(I->getParent());
+ if (!ToLoop) return true;
+ // If the replacing instruction is defined in the same loop as the original
+ // instruction, or in a loop that contains it as an inner loop, then using
+ // it as a replacement will not break LCSSA form.
+ return ToLoop->contains(getLoopFor(From->getParent()));
+ }
+};
+
+
+// Allow clients to walk the list of nested loops...
+template <> struct GraphTraits<const Loop*> {
+ typedef const Loop NodeType;
+ typedef LoopInfo::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const Loop *L) { return L; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+};
+
+template <> struct GraphTraits<Loop*> {
+ typedef Loop NodeType;
+ typedef LoopInfo::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Loop *L) { return L; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+};
+
+template<class BlockT, class LoopT>
+void
+LoopBase<BlockT, LoopT>::addBasicBlockToLoop(BlockT *NewBB,
+ LoopInfoBase<BlockT, LoopT> &LIB) {
+ assert((Blocks.empty() || LIB[getHeader()] == this) &&
+ "Incorrect LI specified for this loop!");
+ assert(NewBB && "Cannot add a null basic block to the loop!");
+ assert(LIB[NewBB] == 0 && "BasicBlock already in the loop!");
+
+ LoopT *L = static_cast<LoopT *>(this);
+
+ // Add the loop mapping to the LoopInfo object...
+ LIB.BBMap[NewBB] = L;
+
+ // Add the basic block to this loop and all parent loops...
+ while (L) {
+ L->Blocks.push_back(NewBB);
+ L = L->getParentLoop();
+ }
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LoopIterator.h b/contrib/llvm/include/llvm/Analysis/LoopIterator.h
new file mode 100644
index 000000000000..269ac8074054
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LoopIterator.h
@@ -0,0 +1,186 @@
+//===--------- LoopIterator.h - Iterate over loop blocks --------*- 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 iterators to visit the basic blocks within a loop.
+//
+// These iterators currently visit blocks within subloops as well.
+// Unfortunately we have no efficient way of summarizing loop exits which would
+// allow skipping subloops during traversal.
+//
+// If you want to visit all blocks in a loop and don't need an ordered traveral,
+// use Loop::block_begin() instead.
+//
+// This is intentionally designed to work with ill-formed loops in which the
+// backedge has been deleted. The only prerequisite is that all blocks
+// contained within the loop according to the most recent LoopInfo analysis are
+// reachable from the loop header.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H
+#define LLVM_ANALYSIS_LOOP_ITERATOR_H
+
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/Analysis/LoopInfo.h"
+
+namespace llvm {
+
+class LoopBlocksTraversal;
+
+/// Store the result of a depth first search within basic blocks contained by a
+/// single loop.
+///
+/// TODO: This could be generalized for any CFG region, or the entire CFG.
+class LoopBlocksDFS {
+public:
+ /// Postorder list iterators.
+ typedef std::vector<BasicBlock*>::const_iterator POIterator;
+ typedef std::vector<BasicBlock*>::const_reverse_iterator RPOIterator;
+
+ friend class LoopBlocksTraversal;
+
+private:
+ Loop *L;
+
+ /// Map each block to its postorder number. A block is only mapped after it is
+ /// preorder visited by DFS. It's postorder number is initially zero and set
+ /// to nonzero after it is finished by postorder traversal.
+ DenseMap<BasicBlock*, unsigned> PostNumbers;
+ std::vector<BasicBlock*> PostBlocks;
+
+public:
+ LoopBlocksDFS(Loop *Container) :
+ L(Container), PostNumbers(NextPowerOf2(Container->getNumBlocks())) {
+ PostBlocks.reserve(Container->getNumBlocks());
+ }
+
+ Loop *getLoop() const { return L; }
+
+ /// Traverse the loop blocks and store the DFS result.
+ void perform(LoopInfo *LI);
+
+ /// Return true if postorder numbers are assigned to all loop blocks.
+ bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); }
+
+ /// Iterate over the cached postorder blocks.
+ POIterator beginPostorder() const {
+ assert(isComplete() && "bad loop DFS");
+ return PostBlocks.begin();
+ }
+ POIterator endPostorder() const { return PostBlocks.end(); }
+
+ /// Reverse iterate over the cached postorder blocks.
+ RPOIterator beginRPO() const {
+ assert(isComplete() && "bad loop DFS");
+ return PostBlocks.rbegin();
+ }
+ RPOIterator endRPO() const { return PostBlocks.rend(); }
+
+ /// Return true if this block has been preorder visited.
+ bool hasPreorder(BasicBlock *BB) const { return PostNumbers.count(BB); }
+
+ /// Return true if this block has a postorder number.
+ bool hasPostorder(BasicBlock *BB) const {
+ DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
+ return I != PostNumbers.end() && I->second;
+ }
+
+ /// Get a block's postorder number.
+ unsigned getPostorder(BasicBlock *BB) const {
+ DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
+ assert(I != PostNumbers.end() && "block not visited by DFS");
+ assert(I->second && "block not finished by DFS");
+ return I->second;
+ }
+
+ /// Get a block's reverse postorder number.
+ unsigned getRPO(BasicBlock *BB) const {
+ return 1 + PostBlocks.size() - getPostorder(BB);
+ }
+
+ void clear() {
+ PostNumbers.clear();
+ PostBlocks.clear();
+ }
+};
+
+/// Traverse the blocks in a loop using a depth-first search.
+class LoopBlocksTraversal {
+public:
+ /// Graph traversal iterator.
+ typedef po_iterator<BasicBlock*, LoopBlocksTraversal, true> POTIterator;
+
+private:
+ LoopBlocksDFS &DFS;
+ LoopInfo *LI;
+
+public:
+ LoopBlocksTraversal(LoopBlocksDFS &Storage, LoopInfo *LInfo) :
+ DFS(Storage), LI(LInfo) {}
+
+ /// Postorder traversal over the graph. This only needs to be done once.
+ /// po_iterator "automatically" calls back to visitPreorder and
+ /// finishPostorder to record the DFS result.
+ POTIterator begin() {
+ assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing");
+ assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph");
+ return po_ext_begin(DFS.L->getHeader(), *this);
+ }
+ POTIterator end() {
+ // po_ext_end interface requires a basic block, but ignores its value.
+ return po_ext_end(DFS.L->getHeader(), *this);
+ }
+
+ /// Called by po_iterator upon reaching a block via a CFG edge. If this block
+ /// is contained in the loop and has not been visited, then mark it preorder
+ /// visited and return true.
+ ///
+ /// TODO: If anyone is interested, we could record preorder numbers here.
+ bool visitPreorder(BasicBlock *BB) {
+ if (!DFS.L->contains(LI->getLoopFor(BB)))
+ return false;
+
+ return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second;
+ }
+
+ /// Called by po_iterator each time it advances, indicating a block's
+ /// postorder.
+ void finishPostorder(BasicBlock *BB) {
+ assert(DFS.PostNumbers.count(BB) && "Loop DFS skipped preorder");
+ DFS.PostBlocks.push_back(BB);
+ DFS.PostNumbers[BB] = DFS.PostBlocks.size();
+ }
+
+ //===----------------------------------------------------------------------
+ // Implement part of the std::set interface for the purpose of driving the
+ // generic po_iterator.
+
+ /// Return true if the block is outside the loop or has already been visited.
+ /// Sorry if this is counterintuitive.
+ bool count(BasicBlock *BB) const {
+ return !DFS.L->contains(LI->getLoopFor(BB)) || DFS.PostNumbers.count(BB);
+ }
+
+ /// If this block is contained in the loop and has not been visited, return
+ /// true and assign a preorder number. This is a proxy for visitPreorder
+ /// called by POIterator.
+ bool insert(BasicBlock *BB) {
+ return visitPreorder(BB);
+ }
+};
+
+/// Specialize DFSetTraits to record postorder numbers.
+template<> struct DFSetTraits<LoopBlocksTraversal> {
+ static void finishPostorder(BasicBlock *BB, LoopBlocksTraversal& LBT) {
+ LBT.finishPostorder(BB);
+ }
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/LoopPass.h b/contrib/llvm/include/llvm/Analysis/LoopPass.h
new file mode 100644
index 000000000000..e6ed9bccee31
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/LoopPass.h
@@ -0,0 +1,158 @@
+//===- LoopPass.h - LoopPass class ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines LoopPass class. All loop optimization
+// and transformation passes are derived from LoopPass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LOOP_PASS_H
+#define LLVM_LOOP_PASS_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/PassManagers.h"
+#include "llvm/Function.h"
+#include <deque>
+
+namespace llvm {
+
+class LPPassManager;
+class Function;
+class PMStack;
+
+class LoopPass : public Pass {
+public:
+ explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {}
+
+ /// getPrinterPass - Get a pass to print the function corresponding
+ /// to a Loop.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
+ // runOnLoop - This method should be implemented by the subclass to perform
+ // whatever action is necessary for the specified Loop.
+ virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
+
+ // Initialization and finalization hooks.
+ virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
+ return false;
+ }
+
+ // Finalization hook does not supply Loop because at this time
+ // loop nest is completely different.
+ virtual bool doFinalization() { return false; }
+
+ // Check if this pass is suitable for the current LPPassManager, if
+ // available. This pass P is not suitable for a LPPassManager if P
+ // is not preserving higher level analysis info used by other
+ // LPPassManager passes. In such case, pop LPPassManager from the
+ // stack. This will force assignPassManager() to create new
+ // LPPassManger as expected.
+ void preparePassManager(PMStack &PMS);
+
+ /// Assign pass manager to manage this pass
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType PMT);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_LoopPassManager;
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// SimpleAnalysis - Provides simple interface to update analysis info
+ /// maintained by various passes. Note, if required this interface can
+ /// be extracted into a separate abstract class but it would require
+ /// additional use of multiple inheritance in Pass class hierarchy, something
+ /// we are trying to avoid.
+
+ /// Each loop pass can override these simple analysis hooks to update
+ /// desired analysis information.
+ /// cloneBasicBlockAnalysis - Clone analysis info associated with basic block.
+ virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {}
+
+ /// deleteAnalysisValue - Delete analysis info associated with value V.
+ virtual void deleteAnalysisValue(Value *V, Loop *L) {}
+};
+
+class LPPassManager : public FunctionPass, public PMDataManager {
+public:
+ static char ID;
+ explicit LPPassManager();
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool runOnFunction(Function &F);
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ // LPPassManager needs LoopInfo.
+ void getAnalysisUsage(AnalysisUsage &Info) const;
+
+ virtual const char *getPassName() const {
+ return "Loop Pass Manager";
+ }
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
+ /// Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset);
+
+ LoopPass *getContainedPass(unsigned N) {
+ assert(N < PassVector.size() && "Pass number out of range!");
+ LoopPass *LP = static_cast<LoopPass *>(PassVector[N]);
+ return LP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_LoopPassManager;
+ }
+
+public:
+ // Delete loop from the loop queue and loop nest (LoopInfo).
+ void deleteLoopFromQueue(Loop *L);
+
+ // Insert loop into the loop queue and add it as a child of the
+ // given parent.
+ void insertLoop(Loop *L, Loop *ParentLoop);
+
+ // Insert a loop into the loop queue.
+ void insertLoopIntoQueue(Loop *L);
+
+ // Reoptimize this loop. LPPassManager will re-insert this loop into the
+ // queue. This allows LoopPass to change loop nest for the loop. This
+ // utility may send LPPassManager into infinite loops so use caution.
+ void redoLoop(Loop *L);
+
+ //===--------------------------------------------------------------------===//
+ /// SimpleAnalysis - Provides simple interface to update analysis info
+ /// maintained by various passes. Note, if required this interface can
+ /// be extracted into a separate abstract class but it would require
+ /// additional use of multiple inheritance in Pass class hierarchy, something
+ /// we are trying to avoid.
+
+ /// cloneBasicBlockSimpleAnalysis - Invoke cloneBasicBlockAnalysis hook for
+ /// all passes that implement simple analysis interface.
+ void cloneBasicBlockSimpleAnalysis(BasicBlock *From, BasicBlock *To, Loop *L);
+
+ /// deleteSimpleAnalysisValue - Invoke deleteAnalysisValue hook for all passes
+ /// that implement simple analysis interface.
+ void deleteSimpleAnalysisValue(Value *V, Loop *L);
+
+private:
+ std::deque<Loop *> LQ;
+ bool skipThisLoop;
+ bool redoThisLoop;
+ LoopInfo *LI;
+ Loop *CurrentLoop;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h b/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h
new file mode 100644
index 000000000000..865d236f6f3a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -0,0 +1,84 @@
+//===- llvm/Analysis/MemoryBuiltins.h- Calls to memory builtins -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions identifies calls to builtin functions that allocate
+// or free memory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
+#define LLVM_ANALYSIS_MEMORYBUILTINS_H
+
+namespace llvm {
+class CallInst;
+class PointerType;
+class TargetData;
+class Type;
+class Value;
+
+//===----------------------------------------------------------------------===//
+// malloc Call Utility Functions.
+//
+
+/// isMalloc - Returns true if the value is either a malloc call or a bitcast of
+/// the result of a malloc call
+bool isMalloc(const Value *I);
+
+/// extractMallocCall - Returns the corresponding CallInst if the instruction
+/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
+/// ignore InvokeInst here.
+const CallInst *extractMallocCall(const Value *I);
+CallInst *extractMallocCall(Value *I);
+
+/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
+/// instruction is a bitcast of the result of a malloc call.
+const CallInst *extractMallocCallFromBitCast(const Value *I);
+CallInst *extractMallocCallFromBitCast(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);
+
+/// getMallocType - Returns the PointerType resulting from the malloc call.
+/// The PointerType depends on the number of bitcast uses of the malloc call:
+/// 0: PointerType is the malloc calls' return type.
+/// 1: PointerType is the bitcast's result type.
+/// >1: Unique PointerType cannot be determined, return NULL.
+PointerType *getMallocType(const CallInst *CI);
+
+/// getMallocAllocatedType - Returns the Type allocated by malloc call.
+/// The Type depends on the number of bitcast uses of the malloc call:
+/// 0: PointerType is the malloc calls' return type.
+/// 1: PointerType is the bitcast's result type.
+/// >1: Unique PointerType cannot be determined, return NULL.
+Type *getMallocAllocatedType(const CallInst *CI);
+
+/// getMallocArraySize - Returns the array size of a malloc call. If the
+/// argument passed to malloc is a multiple of the size of the malloced type,
+/// 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,
+ bool LookThroughSExt = false);
+
+//===----------------------------------------------------------------------===//
+// free Call Utility Functions.
+//
+
+/// isFreeCall - Returns non-null if the value is a call to the builtin free()
+const CallInst *isFreeCall(const Value *I);
+
+static inline CallInst *isFreeCall(Value *I) {
+ return const_cast<CallInst*>(isFreeCall((const Value*)I));
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h b/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
new file mode 100644
index 000000000000..68ce364f4413
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -0,0 +1,445 @@
+//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps --*- 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 MemoryDependenceAnalysis analysis pass.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+ class Function;
+ class FunctionPass;
+ class Instruction;
+ class CallSite;
+ class AliasAnalysis;
+ class TargetData;
+ class MemoryDependenceAnalysis;
+ class PredIteratorCache;
+ class DominatorTree;
+ class PHITransAddr;
+
+ /// MemDepResult - A memory dependence query can return one of three different
+ /// answers, described below.
+ class MemDepResult {
+ enum DepType {
+ /// Invalid - Clients of MemDep never see this.
+ Invalid = 0,
+
+ /// Clobber - This is a dependence on the specified instruction which
+ /// clobbers the desired value. The pointer member of the MemDepResult
+ /// pair holds the instruction that clobbers the memory. For example,
+ /// this occurs when we see a may-aliased store to the memory location we
+ /// care about.
+ ///
+ /// There are several cases that may be interesting here:
+ /// 1. Loads are clobbered by may-alias stores.
+ /// 2. Loads are considered clobbered by partially-aliased loads. The
+ /// client may choose to analyze deeper into these cases.
+ Clobber,
+
+ /// Def - This is a dependence on the specified instruction which
+ /// defines/produces the desired memory location. The pointer member of
+ /// the MemDepResult pair holds the instruction that defines the memory.
+ /// Cases of interest:
+ /// 1. This could be a load or store for dependence queries on
+ /// load/store. The value loaded or stored is the produced value.
+ /// Note that the pointer operand may be different than that of the
+ /// queried pointer due to must aliases and phi translation. Note
+ /// that the def may not be the same type as the query, the pointers
+ /// may just be must aliases.
+ /// 2. For loads and stores, this could be an allocation instruction. In
+ /// this case, the load is loading an undef value or a store is the
+ /// first store to (that part of) the allocation.
+ /// 3. Dependence queries on calls return Def only when they are
+ /// readonly calls or memory use intrinsics with identical callees
+ /// and no intervening clobbers. No validation is done that the
+ /// operands to the calls are the same.
+ Def,
+
+ /// Other - This marker indicates that the query has no known dependency
+ /// in the specified block. More detailed state info is encoded in the
+ /// upper part of the pair (i.e. the Instruction*)
+ Other
+ };
+ /// If DepType is "Other", the upper part of the pair
+ /// (i.e. the Instruction* part) is instead used to encode more detailed
+ /// type information as follows
+ enum OtherType {
+ /// NonLocal - This marker indicates that the query has no dependency in
+ /// the specified block. To find out more, the client should query other
+ /// predecessor blocks.
+ NonLocal = 0x4,
+ /// NonFuncLocal - This marker indicates that the query has no
+ /// dependency in the specified function.
+ NonFuncLocal = 0x8,
+ /// Unknown - This marker indicates that the query dependency
+ /// is unknown.
+ Unknown = 0xc
+ };
+
+ typedef PointerIntPair<Instruction*, 2, DepType> PairTy;
+ PairTy Value;
+ explicit MemDepResult(PairTy V) : Value(V) {}
+ public:
+ MemDepResult() : Value(0, Invalid) {}
+
+ /// get methods: These are static ctor methods for creating various
+ /// MemDepResult kinds.
+ static MemDepResult getDef(Instruction *Inst) {
+ assert(Inst && "Def requires inst");
+ return MemDepResult(PairTy(Inst, Def));
+ }
+ static MemDepResult getClobber(Instruction *Inst) {
+ assert(Inst && "Clobber requires inst");
+ return MemDepResult(PairTy(Inst, Clobber));
+ }
+ static MemDepResult getNonLocal() {
+ return MemDepResult(
+ PairTy(reinterpret_cast<Instruction*>(NonLocal), Other));
+ }
+ static MemDepResult getNonFuncLocal() {
+ return MemDepResult(
+ PairTy(reinterpret_cast<Instruction*>(NonFuncLocal), Other));
+ }
+ static MemDepResult getUnknown() {
+ return MemDepResult(
+ PairTy(reinterpret_cast<Instruction*>(Unknown), Other));
+ }
+
+ /// isClobber - Return true if this MemDepResult represents a query that is
+ /// a instruction clobber dependency.
+ bool isClobber() const { return Value.getInt() == Clobber; }
+
+ /// isDef - Return true if this MemDepResult represents a query that is
+ /// a instruction definition dependency.
+ bool isDef() const { return Value.getInt() == Def; }
+
+ /// isNonLocal - Return true if this MemDepResult represents a query that
+ /// is transparent to the start of the block, but where a non-local hasn't
+ /// been done.
+ bool isNonLocal() const {
+ return Value.getInt() == Other
+ && Value.getPointer() == reinterpret_cast<Instruction*>(NonLocal);
+ }
+
+ /// isNonFuncLocal - Return true if this MemDepResult represents a query
+ /// that is transparent to the start of the function.
+ bool isNonFuncLocal() const {
+ return Value.getInt() == Other
+ && Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
+ }
+
+ /// isUnknown - Return true if this MemDepResult represents a query which
+ /// cannot and/or will not be computed.
+ bool isUnknown() const {
+ return Value.getInt() == Other
+ && Value.getPointer() == reinterpret_cast<Instruction*>(Unknown);
+ }
+
+ /// getInst() - If this is a normal dependency, return the instruction that
+ /// is depended on. Otherwise, return null.
+ Instruction *getInst() const {
+ if (Value.getInt() == Other) return NULL;
+ return Value.getPointer();
+ }
+
+ bool operator==(const MemDepResult &M) const { return Value == M.Value; }
+ bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
+ bool operator<(const MemDepResult &M) const { return Value < M.Value; }
+ bool operator>(const MemDepResult &M) const { return Value > M.Value; }
+ private:
+ friend class MemoryDependenceAnalysis;
+ /// Dirty - Entries with this marker occur in a LocalDeps map or
+ /// NonLocalDeps map when the instruction they previously referenced was
+ /// removed from MemDep. In either case, the entry may include an
+ /// instruction pointer. If so, the pointer is an instruction in the
+ /// block where scanning can start from, saving some work.
+ ///
+ /// In a default-constructed MemDepResult object, the type will be Dirty
+ /// and the instruction pointer will be null.
+ ///
+
+ /// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
+ /// state.
+ bool isDirty() const { return Value.getInt() == Invalid; }
+
+ static MemDepResult getDirty(Instruction *Inst) {
+ return MemDepResult(PairTy(Inst, Invalid));
+ }
+ };
+
+ /// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache. For
+ /// each BasicBlock (the BB entry) it keeps a MemDepResult.
+ class NonLocalDepEntry {
+ BasicBlock *BB;
+ MemDepResult Result;
+ public:
+ NonLocalDepEntry(BasicBlock *bb, MemDepResult result)
+ : BB(bb), Result(result) {}
+
+ // This is used for searches.
+ NonLocalDepEntry(BasicBlock *bb) : BB(bb) {}
+
+ // BB is the sort key, it can't be changed.
+ BasicBlock *getBB() const { return BB; }
+
+ void setResult(const MemDepResult &R) { Result = R; }
+
+ const MemDepResult &getResult() const { return Result; }
+
+ bool operator<(const NonLocalDepEntry &RHS) const {
+ return BB < RHS.BB;
+ }
+ };
+
+ /// NonLocalDepResult - This is a result from a NonLocal dependence query.
+ /// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
+ /// (potentially phi translated) address that was live in the block.
+ class NonLocalDepResult {
+ NonLocalDepEntry Entry;
+ Value *Address;
+ public:
+ NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
+ : Entry(bb, result), Address(address) {}
+
+ // BB is the sort key, it can't be changed.
+ BasicBlock *getBB() const { return Entry.getBB(); }
+
+ void setResult(const MemDepResult &R, Value *Addr) {
+ Entry.setResult(R);
+ Address = Addr;
+ }
+
+ const MemDepResult &getResult() const { return Entry.getResult(); }
+
+ /// getAddress - Return the address of this pointer in this block. This can
+ /// be different than the address queried for the non-local result because
+ /// of phi translation. This returns null if the address was not available
+ /// in a block (i.e. because phi translation failed) or if this is a cached
+ /// result and that address was deleted.
+ ///
+ /// The address is always null for a non-local 'call' dependence.
+ Value *getAddress() const { return Address; }
+ };
+
+ /// MemoryDependenceAnalysis - This is an analysis that determines, for a
+ /// given memory operation, what preceding memory operations it depends on.
+ /// It builds on alias analysis information, and tries to provide a lazy,
+ /// caching interface to a common kind of alias information query.
+ ///
+ /// The dependency information returned is somewhat unusual, but is pragmatic.
+ /// If queried about a store or call that might modify memory, the analysis
+ /// will return the instruction[s] that may either load from that memory or
+ /// store to it. If queried with a load or call that can never modify memory,
+ /// the analysis will return calls and stores that might modify the pointer,
+ /// but generally does not return loads unless a) they are volatile, or
+ /// b) they load from *must-aliased* pointers. Returning a dependence on
+ /// must-alias'd pointers instead of all pointers interacts well with the
+ /// internal caching mechanism.
+ ///
+ class MemoryDependenceAnalysis : public FunctionPass {
+ // A map from instructions to their dependency.
+ typedef DenseMap<Instruction*, MemDepResult> LocalDepMapType;
+ LocalDepMapType LocalDeps;
+
+ public:
+ typedef std::vector<NonLocalDepEntry> NonLocalDepInfo;
+ private:
+ /// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if
+ /// the dependence is a read only dependence, false if read/write.
+ typedef PointerIntPair<const Value*, 1, bool> ValueIsLoadPair;
+
+ /// BBSkipFirstBlockPair - This pair is used when caching information for a
+ /// block. If the pointer is null, the cache value is not a full query that
+ /// starts at the specified block. If non-null, the bool indicates whether
+ /// or not the contents of the block was skipped.
+ typedef PointerIntPair<BasicBlock*, 1, bool> BBSkipFirstBlockPair;
+
+ /// NonLocalPointerInfo - This record is the information kept for each
+ /// (value, is load) pair.
+ struct NonLocalPointerInfo {
+ /// Pair - The pair of the block and the skip-first-block flag.
+ BBSkipFirstBlockPair Pair;
+ /// NonLocalDeps - The results of the query for each relevant block.
+ NonLocalDepInfo NonLocalDeps;
+ /// Size - The maximum size of the dereferences of the
+ /// pointer. May be UnknownSize if the sizes are unknown.
+ uint64_t Size;
+ /// TBAATag - The TBAA tag associated with dereferences of the
+ /// pointer. May be null if there are no tags or conflicting tags.
+ const MDNode *TBAATag;
+
+ NonLocalPointerInfo() : Size(AliasAnalysis::UnknownSize), TBAATag(0) {}
+ };
+
+ /// CachedNonLocalPointerInfo - This map stores the cached results of doing
+ /// a pointer lookup at the bottom of a block. The key of this map is the
+ /// pointer+isload bit, the value is a list of <bb->result> mappings.
+ typedef DenseMap<ValueIsLoadPair,
+ NonLocalPointerInfo> CachedNonLocalPointerInfo;
+ CachedNonLocalPointerInfo NonLocalPointerDeps;
+
+ // A map from instructions to their non-local pointer dependencies.
+ typedef DenseMap<Instruction*,
+ SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
+ ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
+
+
+ /// PerInstNLInfo - This is the instruction we keep for each cached access
+ /// that we have for an instruction. The pointer is an owning pointer and
+ /// the bool indicates whether we have any dirty bits in the set.
+ typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
+
+ // A map from instructions to their non-local dependencies.
+ typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
+
+ NonLocalDepMapType NonLocalDeps;
+
+ // A reverse mapping from dependencies to the dependees. This is
+ // used when removing instructions to keep the cache coherent.
+ typedef DenseMap<Instruction*,
+ SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
+ ReverseDepMapType ReverseLocalDeps;
+
+ // A reverse mapping from dependencies to the non-local dependees.
+ ReverseDepMapType ReverseNonLocalDeps;
+
+ /// Current AA implementation, just a cache.
+ AliasAnalysis *AA;
+ TargetData *TD;
+ DominatorTree *DT;
+ OwningPtr<PredIteratorCache> PredCache;
+ public:
+ MemoryDependenceAnalysis();
+ ~MemoryDependenceAnalysis();
+ static char ID;
+
+ /// Pass Implementation stuff. This doesn't do any analysis eagerly.
+ bool runOnFunction(Function &);
+
+ /// Clean up memory in between runs
+ void releaseMemory();
+
+ /// getAnalysisUsage - Does not modify anything. It uses Value Numbering
+ /// and Alias Analysis.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// getDependency - Return the instruction on which a memory operation
+ /// depends. See the class comment for more details. It is illegal to call
+ /// this on non-memory instructions.
+ MemDepResult getDependency(Instruction *QueryInst);
+
+ /// getNonLocalCallDependency - Perform a full dependency query for the
+ /// specified call, returning the set of blocks that the value is
+ /// potentially live across. The returned set of results will include a
+ /// "NonLocal" result for all blocks where the value is live across.
+ ///
+ /// This method assumes the instruction returns a "NonLocal" dependency
+ /// within its own block.
+ ///
+ /// This returns a reference to an internal data structure that may be
+ /// invalidated on the next non-local query or when an instruction is
+ /// removed. Clients must copy this data if they want it around longer than
+ /// that.
+ const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
+
+
+ /// getNonLocalPointerDependency - Perform a full dependency query for an
+ /// access to the specified (non-volatile) memory location, returning the
+ /// set of instructions that either define or clobber the value.
+ ///
+ /// This method assumes the pointer has a "NonLocal" dependency within BB.
+ void getNonLocalPointerDependency(const AliasAnalysis::Location &Loc,
+ bool isLoad, BasicBlock *BB,
+ SmallVectorImpl<NonLocalDepResult> &Result);
+
+ /// removeInstruction - Remove an instruction from the dependence analysis,
+ /// updating the dependence of instructions that previously depended on it.
+ void removeInstruction(Instruction *InstToRemove);
+
+ /// invalidateCachedPointerInfo - This method is used to invalidate cached
+ /// information about the specified pointer, because it may be too
+ /// conservative in memdep. This is an optional call that can be used when
+ /// the client detects an equivalence between the pointer and some other
+ /// value and replaces the other value with ptr. This can make Ptr available
+ /// in more places that cached info does not necessarily keep.
+ void invalidateCachedPointerInfo(Value *Ptr);
+
+ /// invalidateCachedPredecessors - Clear the PredIteratorCache info.
+ /// This needs to be done when the CFG changes, e.g., due to splitting
+ /// critical edges.
+ void invalidateCachedPredecessors();
+
+ /// getPointerDependencyFrom - Return the instruction on which a memory
+ /// location depends. If isLoad is true, this routine ignores may-aliases
+ /// with read-only operations. If isLoad is false, this routine ignores
+ /// may-aliases with reads from read-only locations.
+ ///
+ /// Note that this is an uncached query, and thus may be inefficient.
+ ///
+ MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
+ bool isLoad,
+ BasicBlock::iterator ScanIt,
+ BasicBlock *BB);
+
+
+ /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
+ /// looks at a memory location for a load (specified by MemLocBase, Offs,
+ /// and Size) and compares it against a load. If the specified load could
+ /// be safely widened to a larger integer load that is 1) still efficient,
+ /// 2) safe for the target, and 3) would provide the specified memory
+ /// location value, then this function returns the size in bytes of the
+ /// load width to use. If not, this returns zero.
+ static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
+ int64_t MemLocOffs,
+ unsigned MemLocSize,
+ const LoadInst *LI,
+ const TargetData &TD);
+
+ private:
+ MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
+ BasicBlock::iterator ScanIt,
+ BasicBlock *BB);
+ bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer,
+ const AliasAnalysis::Location &Loc,
+ bool isLoad, BasicBlock *BB,
+ SmallVectorImpl<NonLocalDepResult> &Result,
+ DenseMap<BasicBlock*, Value*> &Visited,
+ bool SkipFirstBlock = false);
+ MemDepResult GetNonLocalInfoForBlock(const AliasAnalysis::Location &Loc,
+ bool isLoad, BasicBlock *BB,
+ NonLocalDepInfo *Cache,
+ unsigned NumSortedEntries);
+
+ void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
+
+ AliasAnalysis::ModRefResult
+ getModRefInfo(const Instruction *Inst, const AliasAnalysis::Location &Loc);
+
+ /// verifyRemoved - Verify that the specified instruction does not occur
+ /// in our internal data structures.
+ void verifyRemoved(Instruction *Inst) const;
+
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/PHITransAddr.h b/contrib/llvm/include/llvm/Analysis/PHITransAddr.h
new file mode 100644
index 000000000000..ff9a24790a99
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/PHITransAddr.h
@@ -0,0 +1,121 @@
+//===- PHITransAddr.h - PHI Translation for Addresses -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the PHITransAddr class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
+#define LLVM_ANALYSIS_PHITRANSADDR_H
+
+#include "llvm/Instruction.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+ class DominatorTree;
+ class TargetData;
+ class TargetLibraryInfo;
+
+/// PHITransAddr - An address value which tracks and handles phi translation.
+/// As we walk "up" the CFG through predecessors, we need to ensure that the
+/// address we're tracking is kept up to date. For example, if we're analyzing
+/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI
+/// node, we *must* phi translate i to get "&A[j]" or else we will analyze an
+/// incorrect pointer in the predecessor block.
+///
+/// This is designed to be a relatively small object that lives on the stack and
+/// is copyable.
+///
+class PHITransAddr {
+ /// Addr - The actual address we're analyzing.
+ Value *Addr;
+
+ /// TD - The target data we are playing with if known, otherwise null.
+ const TargetData *TD;
+
+ /// TLI - The target library info if known, otherwise null.
+ const TargetLibraryInfo *TLI;
+
+ /// InstInputs - The inputs for our symbolic address.
+ SmallVector<Instruction*, 4> InstInputs;
+public:
+ PHITransAddr(Value *addr, const TargetData *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);
+ }
+
+ Value *getAddr() const { return Addr; }
+
+ /// NeedsPHITranslationFromBlock - Return true if moving from the specified
+ /// BasicBlock to its predecessors requires PHI translation.
+ bool NeedsPHITranslationFromBlock(BasicBlock *BB) const {
+ // We do need translation if one of our input instructions is defined in
+ // this block.
+ for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
+ if (InstInputs[i]->getParent() == BB)
+ return true;
+ return false;
+ }
+
+ /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
+ /// if we have some hope of doing it. This should be used as a filter to
+ /// avoid calling PHITranslateValue in hopeless situations.
+ bool IsPotentiallyPHITranslatable() const;
+
+ /// PHITranslateValue - PHI translate the current address up the CFG from
+ /// CurBB to Pred, updating our state to reflect any needed changes. If the
+ /// dominator tree DT is non-null, the translated value must dominate
+ /// PredBB. This returns true on failure and sets Addr to null.
+ bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
+ const DominatorTree *DT);
+
+ /// PHITranslateWithInsertion - PHI translate this value into the specified
+ /// predecessor block, inserting a computation of the value if it is
+ /// unavailable.
+ ///
+ /// All newly created instructions are added to the NewInsts list. This
+ /// returns null on failure.
+ ///
+ Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
+ const DominatorTree &DT,
+ SmallVectorImpl<Instruction*> &NewInsts);
+
+ void dump() const;
+
+ /// Verify - Check internal consistency of this data structure. If the
+ /// structure is valid, it returns true. If invalid, it prints errors and
+ /// returns false.
+ bool Verify() const;
+private:
+ Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB,
+ const DominatorTree *DT);
+
+ /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated
+ /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
+ /// block. All newly created instructions are added to the NewInsts list.
+ /// This returns null on failure.
+ ///
+ Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
+ BasicBlock *PredBB, const DominatorTree &DT,
+ SmallVectorImpl<Instruction*> &NewInsts);
+
+ /// AddAsInput - If the specified value is an instruction, add it as an input.
+ Value *AddAsInput(Value *V) {
+ // If V is an instruction, it is now an input.
+ if (Instruction *VI = dyn_cast<Instruction>(V))
+ InstInputs.push_back(VI);
+ return V;
+ }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/Passes.h b/contrib/llvm/include/llvm/Analysis/Passes.h
new file mode 100644
index 000000000000..a22bd12dec1e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Passes.h
@@ -0,0 +1,205 @@
+//===-- llvm/Analysis/Passes.h - Constructors for analyses ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the analysis libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PASSES_H
+#define LLVM_ANALYSIS_PASSES_H
+
+namespace llvm {
+ class FunctionPass;
+ class ImmutablePass;
+ class LoopPass;
+ class ModulePass;
+ class Pass;
+ class PassInfo;
+ class LibCallInfo;
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createGlobalsModRefPass - This pass provides alias and mod/ref info for
+ // global values that do not have their addresses taken.
+ //
+ Pass *createGlobalsModRefPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAliasDebugger - This pass helps debug clients of AA
+ //
+ Pass *createAliasDebugger();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAliasAnalysisCounterPass - This pass counts alias queries and how the
+ // alias analysis implementation responds.
+ //
+ ModulePass *createAliasAnalysisCounterPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAAEvalPass - This pass implements a simple N^2 alias analysis
+ // accuracy evaluator.
+ //
+ FunctionPass *createAAEvalPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createNoAAPass - This pass implements a "I don't know" alias analysis.
+ //
+ ImmutablePass *createNoAAPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createBasicAliasAnalysisPass - This pass implements the stateless alias
+ // analysis.
+ //
+ ImmutablePass *createBasicAliasAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ /// createLibCallAliasAnalysisPass - Create an alias analysis pass that knows
+ /// about the semantics of a set of libcalls specified by LCI. The newly
+ /// constructed pass takes ownership of the pointer that is provided.
+ ///
+ FunctionPass *createLibCallAliasAnalysisPass(LibCallInfo *LCI);
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createScalarEvolutionAliasAnalysisPass - This pass implements a simple
+ // alias analysis using ScalarEvolution queries.
+ //
+ FunctionPass *createScalarEvolutionAliasAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createTypeBasedAliasAnalysisPass - This pass implements metadata-based
+ // type-based alias analysis.
+ //
+ ImmutablePass *createTypeBasedAliasAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based
+ // alias analysis.
+ //
+ ImmutablePass *createObjCARCAliasAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createProfileLoaderPass - This pass loads information from a profile dump
+ // file.
+ //
+ ModulePass *createProfileLoaderPass();
+ extern char &ProfileLoaderPassID;
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createNoProfileInfoPass - This pass implements the default "no profile".
+ //
+ ImmutablePass *createNoProfileInfoPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createProfileEstimatorPass - This pass estimates profiling information
+ // instead of loading it from a previous run.
+ //
+ FunctionPass *createProfileEstimatorPass();
+ extern char &ProfileEstimatorPassID;
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createProfileVerifierPass - This pass verifies profiling information.
+ //
+ FunctionPass *createProfileVerifierPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createPathProfileLoaderPass - This pass loads information from a path
+ // profile dump file.
+ //
+ ModulePass *createPathProfileLoaderPass();
+ extern char &PathProfileLoaderPassID;
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createNoPathProfileInfoPass - This pass implements the default
+ // "no path profile".
+ //
+ ImmutablePass *createNoPathProfileInfoPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createPathProfileVerifierPass - This pass verifies path profiling
+ // information.
+ //
+ ModulePass *createPathProfileVerifierPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createDSAAPass - This pass implements simple context sensitive alias
+ // analysis.
+ //
+ ModulePass *createDSAAPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createDSOptPass - This pass uses DSA to do a series of simple
+ // optimizations.
+ //
+ ModulePass *createDSOptPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createSteensgaardPass - This pass uses the data structure graphs to do a
+ // simple context insensitive alias analysis.
+ //
+ ModulePass *createSteensgaardPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ /// createLazyValueInfoPass - This creates an instance of the LazyValueInfo
+ /// pass.
+ FunctionPass *createLazyValueInfoPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createLoopDependenceAnalysisPass - This creates an instance of the
+ // LoopDependenceAnalysis pass.
+ //
+ LoopPass *createLoopDependenceAnalysisPass();
+
+ // Minor pass prototypes, allowing us to expose them through bugpoint and
+ // analyze.
+ FunctionPass *createInstCountPass();
+
+ // print debug info intrinsics in human readable form
+ FunctionPass *createDbgInfoPrinterPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createRegionInfoPass - This pass finds all single entry single exit regions
+ // in a function and builds the region hierarchy.
+ //
+ FunctionPass *createRegionInfoPass();
+
+ // Print module-level debug info metadata in human-readable form.
+ ModulePass *createModuleDebugInfoPrinterPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createMemDepPrinter - This pass exhaustively collects all memdep
+ // information and prints it with -analyze.
+ //
+ FunctionPass *createMemDepPrinter();
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/PathNumbering.h b/contrib/llvm/include/llvm/Analysis/PathNumbering.h
new file mode 100644
index 000000000000..7025e28484cc
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/PathNumbering.h
@@ -0,0 +1,304 @@
+//===- PathNumbering.h ----------------------------------------*- C++ -*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Ball-Larus path numbers uniquely identify paths through a directed acyclic
+// graph (DAG) [Ball96]. For a CFG backedges are removed and replaced by phony
+// edges to obtain a DAG, and thus the unique path numbers [Ball96].
+//
+// The purpose of this analysis is to enumerate the edges in a CFG in order
+// to obtain paths from path numbers in a convenient manner. As described in
+// [Ball96] edges can be enumerated such that given a path number by following
+// the CFG and updating the path number, the path is obtained.
+//
+// [Ball96]
+// T. Ball and J. R. Larus. "Efficient Path Profiling."
+// International Symposium on Microarchitecture, pages 46-57, 1996.
+// http://portal.acm.org/citation.cfm?id=243857
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PATH_NUMBERING_H
+#define LLVM_PATH_NUMBERING_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Analysis/ProfileInfoTypes.h"
+#include <map>
+#include <stack>
+#include <vector>
+
+namespace llvm {
+class BallLarusNode;
+class BallLarusEdge;
+class BallLarusDag;
+
+// typedefs for storage/ interators of various DAG components
+typedef std::vector<BallLarusNode*> BLNodeVector;
+typedef std::vector<BallLarusNode*>::iterator BLNodeIterator;
+typedef std::vector<BallLarusEdge*> BLEdgeVector;
+typedef std::vector<BallLarusEdge*>::iterator BLEdgeIterator;
+typedef std::map<BasicBlock*, BallLarusNode*> BLBlockNodeMap;
+typedef std::stack<BallLarusNode*> BLNodeStack;
+
+// Represents a basic block with information necessary for the BallLarus
+// algorithms.
+class BallLarusNode {
+public:
+ enum NodeColor { WHITE, GRAY, BLACK };
+
+ // Constructor: Initializes a new Node for the given BasicBlock
+ BallLarusNode(BasicBlock* BB) :
+ _basicBlock(BB), _numberPaths(0), _color(WHITE) {
+ static unsigned nextUID = 0;
+ _uid = nextUID++;
+ }
+
+ // Returns the basic block for the BallLarusNode
+ BasicBlock* getBlock();
+
+ // Get/set the number of paths to the exit starting at the node.
+ unsigned getNumberPaths();
+ void setNumberPaths(unsigned numberPaths);
+
+ // Get/set the NodeColor used in graph algorithms.
+ NodeColor getColor();
+ void setColor(NodeColor color);
+
+ // Iterator information for predecessor edges. Includes phony and
+ // backedges.
+ BLEdgeIterator predBegin();
+ BLEdgeIterator predEnd();
+ unsigned getNumberPredEdges();
+
+ // Iterator information for successor edges. Includes phony and
+ // backedges.
+ BLEdgeIterator succBegin();
+ BLEdgeIterator succEnd();
+ unsigned getNumberSuccEdges();
+
+ // Add an edge to the predecessor list.
+ void addPredEdge(BallLarusEdge* edge);
+
+ // Remove an edge from the predecessor list.
+ void removePredEdge(BallLarusEdge* edge);
+
+ // Add an edge to the successor list.
+ void addSuccEdge(BallLarusEdge* edge);
+
+ // Remove an edge from the successor list.
+ void removeSuccEdge(BallLarusEdge* edge);
+
+ // Returns the name of the BasicBlock being represented. If BasicBlock
+ // is null then returns "<null>". If BasicBlock has no name, then
+ // "<unnamed>" is returned. Intended for use with debug output.
+ std::string getName();
+
+private:
+ // The corresponding underlying BB.
+ BasicBlock* _basicBlock;
+
+ // Holds the predecessor edges of this node.
+ BLEdgeVector _predEdges;
+
+ // Holds the successor edges of this node.
+ BLEdgeVector _succEdges;
+
+ // The number of paths from the node to the exit.
+ unsigned _numberPaths;
+
+ // 'Color' used by graph algorithms to mark the node.
+ NodeColor _color;
+
+ // Unique ID to ensure naming difference with dotgraphs
+ unsigned _uid;
+
+ // Removes an edge from an edgeVector. Used by removePredEdge and
+ // removeSuccEdge.
+ void removeEdge(BLEdgeVector& v, BallLarusEdge* e);
+};
+
+// Represents an edge in the Dag. For an edge, v -> w, v is the source, and
+// w is the target.
+class BallLarusEdge {
+public:
+ enum EdgeType { NORMAL, BACKEDGE, SPLITEDGE,
+ BACKEDGE_PHONY, SPLITEDGE_PHONY, CALLEDGE_PHONY };
+
+ // Constructor: Initializes an BallLarusEdge with a source and target.
+ BallLarusEdge(BallLarusNode* source, BallLarusNode* target,
+ unsigned duplicateNumber)
+ : _source(source), _target(target), _weight(0), _edgeType(NORMAL),
+ _realEdge(NULL), _duplicateNumber(duplicateNumber) {}
+
+ // Returns the source/ target node of this edge.
+ BallLarusNode* getSource() const;
+ BallLarusNode* getTarget() const;
+
+ // Sets the type of the edge.
+ EdgeType getType() const;
+
+ // Gets the type of the edge.
+ void setType(EdgeType type);
+
+ // Returns the weight of this edge. Used to decode path numbers to
+ // sequences of basic blocks.
+ unsigned getWeight();
+
+ // Sets the weight of the edge. Used during path numbering.
+ void setWeight(unsigned weight);
+
+ // Gets/sets the phony edge originating at the root.
+ BallLarusEdge* getPhonyRoot();
+ void setPhonyRoot(BallLarusEdge* phonyRoot);
+
+ // Gets/sets the phony edge terminating at the exit.
+ BallLarusEdge* getPhonyExit();
+ void setPhonyExit(BallLarusEdge* phonyExit);
+
+ // Gets/sets the associated real edge if this is a phony edge.
+ BallLarusEdge* getRealEdge();
+ void setRealEdge(BallLarusEdge* realEdge);
+
+ // Returns the duplicate number of the edge.
+ unsigned getDuplicateNumber();
+
+protected:
+ // Source node for this edge.
+ BallLarusNode* _source;
+
+ // Target node for this edge.
+ BallLarusNode* _target;
+
+private:
+ // Edge weight cooresponding to path number increments before removing
+ // increments along a spanning tree. The sum over the edge weights gives
+ // the path number.
+ unsigned _weight;
+
+ // Type to represent for what this edge is intended
+ EdgeType _edgeType;
+
+ // For backedges and split-edges, the phony edge which is linked to the
+ // root node of the DAG. This contains a path number initialization.
+ BallLarusEdge* _phonyRoot;
+
+ // For backedges and split-edges, the phony edge which is linked to the
+ // exit node of the DAG. This contains a path counter increment, and
+ // potentially a path number increment.
+ BallLarusEdge* _phonyExit;
+
+ // If this is a phony edge, _realEdge is a link to the back or split
+ // edge. Otherwise, this is null.
+ BallLarusEdge* _realEdge;
+
+ // An ID to differentiate between those edges which have the same source
+ // and destination blocks.
+ unsigned _duplicateNumber;
+};
+
+// Represents the Ball Larus DAG for a given Function. Can calculate
+// various properties required for instrumentation or analysis. E.g. the
+// edge weights that determine the path number.
+class BallLarusDag {
+public:
+ // Initializes a BallLarusDag from the CFG of a given function. Must
+ // call init() after creation, since some initialization requires
+ // virtual functions.
+ BallLarusDag(Function &F)
+ : _root(NULL), _exit(NULL), _function(F) {}
+
+ // Initialization that requires virtual functions which are not fully
+ // functional in the constructor.
+ void init();
+
+ // Frees all memory associated with the DAG.
+ virtual ~BallLarusDag();
+
+ // Calculate the path numbers by assigning edge increments as prescribed
+ // in Ball-Larus path profiling.
+ void calculatePathNumbers();
+
+ // Returns the number of paths for the DAG.
+ unsigned getNumberOfPaths();
+
+ // Returns the root (i.e. entry) node for the DAG.
+ BallLarusNode* getRoot();
+
+ // Returns the exit node for the DAG.
+ BallLarusNode* getExit();
+
+ // Returns the function for the DAG.
+ Function& getFunction();
+
+ // Clears the node colors.
+ void clearColors(BallLarusNode::NodeColor color);
+
+protected:
+ // All nodes in the DAG.
+ BLNodeVector _nodes;
+
+ // All edges in the DAG.
+ BLEdgeVector _edges;
+
+ // All backedges in the DAG.
+ BLEdgeVector _backEdges;
+
+ // Allows subclasses to determine which type of Node is created.
+ // Override this method to produce subclasses of BallLarusNode if
+ // necessary. The destructor of BallLarusDag will call free on each pointer
+ // created.
+ virtual BallLarusNode* createNode(BasicBlock* BB);
+
+ // Allows subclasses to determine which type of Edge is created.
+ // Override this method to produce subclasses of BallLarusEdge if
+ // necessary. Parameters source and target will have been created by
+ // createNode and can be cast to the subclass of BallLarusNode*
+ // returned by createNode. The destructor of BallLarusDag will call free
+ // on each pointer created.
+ virtual BallLarusEdge* createEdge(BallLarusNode* source, BallLarusNode*
+ target, unsigned duplicateNumber);
+
+ // Proxy to node's constructor. Updates the DAG state.
+ BallLarusNode* addNode(BasicBlock* BB);
+
+ // Proxy to edge's constructor. Updates the DAG state.
+ BallLarusEdge* addEdge(BallLarusNode* source, BallLarusNode* target,
+ unsigned duplicateNumber);
+
+private:
+ // The root (i.e. entry) node for this DAG.
+ BallLarusNode* _root;
+
+ // The exit node for this DAG.
+ BallLarusNode* _exit;
+
+ // The function represented by this DAG.
+ Function& _function;
+
+ // Processes one node and its imediate edges for building the DAG.
+ void buildNode(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack);
+
+ // Process an edge in the CFG for DAG building.
+ void buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack,
+ BallLarusNode* currentNode, BasicBlock* succBB,
+ unsigned duplicateNumber);
+
+ // The weight on each edge is the increment required along any path that
+ // contains that edge.
+ void calculatePathNumbersFrom(BallLarusNode* node);
+
+ // Adds a backedge with its phony edges. Updates the DAG state.
+ void addBackedge(BallLarusNode* source, BallLarusNode* target,
+ unsigned duplicateCount);
+};
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h b/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h
new file mode 100644
index 000000000000..cef6d2d2a6c8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/PathProfileInfo.h
@@ -0,0 +1,112 @@
+//===- PathProfileInfo.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 outlines the interface used by optimizers to load path profiles.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PATHPROFILEINFO_H
+#define LLVM_PATHPROFILEINFO_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Analysis/PathNumbering.h"
+
+namespace llvm {
+
+class ProfilePath;
+class ProfilePathEdge;
+class PathProfileInfo;
+
+typedef std::vector<ProfilePathEdge> ProfilePathEdgeVector;
+typedef std::vector<ProfilePathEdge>::iterator ProfilePathEdgeIterator;
+
+typedef std::vector<BasicBlock*> ProfilePathBlockVector;
+typedef std::vector<BasicBlock*>::iterator ProfilePathBlockIterator;
+
+typedef std::map<unsigned int,ProfilePath*> ProfilePathMap;
+typedef std::map<unsigned int,ProfilePath*>::iterator ProfilePathIterator;
+
+typedef std::map<Function*,unsigned int> FunctionPathCountMap;
+typedef std::map<Function*,ProfilePathMap> FunctionPathMap;
+typedef std::map<Function*,ProfilePathMap>::iterator FunctionPathIterator;
+
+class ProfilePathEdge {
+public:
+ ProfilePathEdge(BasicBlock* source, BasicBlock* target,
+ unsigned duplicateNumber);
+
+ inline unsigned getDuplicateNumber() { return _duplicateNumber; }
+ inline BasicBlock* getSource() { return _source; }
+ inline BasicBlock* getTarget() { return _target; }
+
+protected:
+ BasicBlock* _source;
+ BasicBlock* _target;
+ unsigned _duplicateNumber;
+};
+
+class ProfilePath {
+public:
+ ProfilePath(unsigned int number, unsigned int count,
+ double countStdDev, PathProfileInfo* ppi);
+
+ double getFrequency() const;
+
+ inline unsigned int getNumber() const { return _number; }
+ inline unsigned int getCount() const { return _count; }
+ inline double getCountStdDev() const { return _countStdDev; }
+
+ ProfilePathEdgeVector* getPathEdges() const;
+ ProfilePathBlockVector* getPathBlocks() const;
+
+ BasicBlock* getFirstBlockInPath() const;
+
+private:
+ unsigned int _number;
+ unsigned int _count;
+ double _countStdDev;
+
+ // double pointer back to the profiling info
+ PathProfileInfo* _ppi;
+};
+
+// TODO: overload [] operator for getting path
+// Add: getFunctionCallCount()
+class PathProfileInfo {
+ public:
+ PathProfileInfo();
+ ~PathProfileInfo();
+
+ void setCurrentFunction(Function* F);
+ Function* getCurrentFunction() const;
+ BasicBlock* getCurrentFunctionEntry();
+
+ ProfilePath* getPath(unsigned int number);
+ unsigned int getPotentialPathCount();
+
+ ProfilePathIterator pathBegin();
+ ProfilePathIterator pathEnd();
+ unsigned int pathsRun();
+
+ static char ID; // Pass identification
+ std::string argList;
+
+protected:
+ FunctionPathMap _functionPaths;
+ FunctionPathCountMap _functionPathCounts;
+
+private:
+ BallLarusDag* _currentDag;
+ Function* _currentFunction;
+
+ friend class ProfilePath;
+};
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/PostDominators.h b/contrib/llvm/include/llvm/Analysis/PostDominators.h
new file mode 100644
index 000000000000..0eddb9105e60
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/PostDominators.h
@@ -0,0 +1,106 @@
+//=- llvm/Analysis/PostDominators.h - Post Dominator Calculation-*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
+#define LLVM_ANALYSIS_POST_DOMINATORS_H
+
+#include "llvm/Analysis/Dominators.h"
+
+namespace llvm {
+
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
+/// compute the a post-dominator tree.
+///
+struct PostDominatorTree : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ DominatorTreeBase<BasicBlock>* DT;
+
+ PostDominatorTree() : FunctionPass(ID) {
+ initializePostDominatorTreePass(*PassRegistry::getPassRegistry());
+ DT = new DominatorTreeBase<BasicBlock>(true);
+ }
+
+ ~PostDominatorTree();
+
+ virtual bool runOnFunction(Function &F);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ inline const std::vector<BasicBlock*> &getRoots() const {
+ return DT->getRoots();
+ }
+
+ inline DomTreeNode *getRootNode() const {
+ return DT->getRootNode();
+ }
+
+ inline DomTreeNode *operator[](BasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ inline DomTreeNode *getNode(BasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ inline bool dominates(DomTreeNode* A, DomTreeNode* B) const {
+ return DT->dominates(A, B);
+ }
+
+ inline bool dominates(const BasicBlock* A, const BasicBlock* B) const {
+ return DT->dominates(A, B);
+ }
+
+ inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
+ return DT->findNearestCommonDominator(A, B);
+ }
+
+ virtual void releaseMemory() {
+ DT->releaseMemory();
+ }
+
+ virtual void print(raw_ostream &OS, const Module*) const;
+};
+
+FunctionPass* createPostDomTree();
+
+template <> struct GraphTraits<PostDominatorTree*>
+ : public GraphTraits<DomTreeNode*> {
+ static NodeType *getEntryNode(PostDominatorTree *DT) {
+ return DT->getRootNode();
+ }
+
+ static nodes_iterator nodes_begin(PostDominatorTree *N) {
+ if (getEntryNode(N))
+ return df_begin(getEntryNode(N));
+ else
+ return df_end(getEntryNode(N));
+ }
+
+ static nodes_iterator nodes_end(PostDominatorTree *N) {
+ return df_end(getEntryNode(N));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ProfileInfo.h b/contrib/llvm/include/llvm/Analysis/ProfileInfo.h
new file mode 100644
index 000000000000..6c2e2732d344
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ProfileInfo.h
@@ -0,0 +1,247 @@
+//===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the generic ProfileInfo interface, which is used as the
+// common interface used by all clients of profiling information, and
+// implemented either by making static guestimations, or by actually reading in
+// profiling information gathered by running the program.
+//
+// Note that to be useful, all profile-based optimizations should preserve
+// ProfileInfo, which requires that they notify it when changes to the CFG are
+// made. (This is not implemented yet.)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PROFILEINFO_H
+#define LLVM_ANALYSIS_PROFILEINFO_H
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <string>
+#include <map>
+#include <set>
+
+namespace llvm {
+ class Pass;
+ class raw_ostream;
+
+ class BasicBlock;
+ class Function;
+ class MachineBasicBlock;
+ class MachineFunction;
+
+ // Helper for dumping edges to dbgs().
+ raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E);
+ raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E);
+
+ raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB);
+ raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB);
+
+ raw_ostream& operator<<(raw_ostream &O, const Function *F);
+ raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF);
+
+ /// ProfileInfo Class - This class holds and maintains profiling
+ /// information for some unit of code.
+ template<class FType, class BType>
+ class ProfileInfoT {
+ public:
+ // Types for handling profiling information.
+ typedef std::pair<const BType*, const BType*> Edge;
+ typedef std::pair<Edge, double> EdgeWeight;
+ typedef std::map<Edge, double> EdgeWeights;
+ typedef std::map<const BType*, double> BlockCounts;
+ typedef std::map<const BType*, const BType*> Path;
+
+ protected:
+ // EdgeInformation - Count the number of times a transition between two
+ // blocks is executed. As a special case, we also hold an edge from the
+ // null BasicBlock to the entry block to indicate how many times the
+ // function was entered.
+ std::map<const FType*, EdgeWeights> EdgeInformation;
+
+ // BlockInformation - Count the number of times a block is executed.
+ std::map<const FType*, BlockCounts> BlockInformation;
+
+ // FunctionInformation - Count the number of times a function is executed.
+ std::map<const FType*, double> FunctionInformation;
+
+ ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile;
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ ProfileInfoT();
+ ~ProfileInfoT(); // We want to be subclassed
+
+ // MissingValue - The value that is returned for execution counts in case
+ // no value is available.
+ static const double MissingValue;
+
+ // getFunction() - Returns the Function for an Edge, checking for validity.
+ static const FType* getFunction(Edge e) {
+ if (e.first)
+ return e.first->getParent();
+ if (e.second)
+ return e.second->getParent();
+ llvm_unreachable("Invalid ProfileInfo::Edge");
+ }
+
+ // getEdge() - Creates an Edge from two BasicBlocks.
+ static Edge getEdge(const BType *Src, const BType *Dest) {
+ return std::make_pair(Src, Dest);
+ }
+
+ //===------------------------------------------------------------------===//
+ /// Profile Information Queries
+ ///
+ double getExecutionCount(const FType *F);
+
+ double getExecutionCount(const BType *BB);
+
+ void setExecutionCount(const BType *BB, double w);
+
+ void addExecutionCount(const BType *BB, double w);
+
+ double getEdgeWeight(Edge e) const {
+ typename std::map<const FType*, EdgeWeights>::const_iterator J =
+ EdgeInformation.find(getFunction(e));
+ if (J == EdgeInformation.end()) return MissingValue;
+
+ typename EdgeWeights::const_iterator I = J->second.find(e);
+ if (I == J->second.end()) return MissingValue;
+
+ return I->second;
+ }
+
+ void setEdgeWeight(Edge e, double w) {
+ DEBUG_WITH_TYPE("profile-info",
+ dbgs() << "Creating Edge " << e
+ << " (weight: " << format("%.20g",w) << ")\n");
+ EdgeInformation[getFunction(e)][e] = w;
+ }
+
+ void addEdgeWeight(Edge e, double w);
+
+ EdgeWeights &getEdgeWeights (const FType *F) {
+ return EdgeInformation[F];
+ }
+
+ //===------------------------------------------------------------------===//
+ /// Analysis Update Methods
+ ///
+ void removeBlock(const BType *BB);
+
+ void removeEdge(Edge e);
+
+ void replaceEdge(const Edge &, const Edge &);
+
+ enum GetPathMode {
+ GetPathToExit = 1,
+ GetPathToValue = 2,
+ GetPathToDest = 4,
+ GetPathWithNewEdges = 8
+ };
+
+ const BType *GetPath(const BType *Src, const BType *Dest,
+ Path &P, unsigned Mode);
+
+ void divertFlow(const Edge &, const Edge &);
+
+ void splitEdge(const BType *FirstBB, const BType *SecondBB,
+ const BType *NewBB, bool MergeIdenticalEdges = false);
+
+ void splitBlock(const BType *Old, const BType* New);
+
+ void splitBlock(const BType *BB, const BType* NewBB,
+ BType *const *Preds, unsigned NumPreds);
+
+ void replaceAllUses(const BType *RmBB, const BType *DestBB);
+
+ void transfer(const FType *Old, const FType *New);
+
+ void repair(const FType *F);
+
+ void dump(FType *F = 0, bool real = true) {
+ dbgs() << "**** This is ProfileInfo " << this << " speaking:\n";
+ if (!real) {
+ typename std::set<const FType*> Functions;
+
+ dbgs() << "Functions: \n";
+ if (F) {
+ dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
+ Functions.insert(F);
+ } else {
+ for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(),
+ fe = FunctionInformation.end(); fi != fe; ++fi) {
+ dbgs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n";
+ Functions.insert(fi->first);
+ }
+ }
+
+ for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
+ FI != FE; ++FI) {
+ const FType *F = *FI;
+ typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F);
+ dbgs() << "BasicBlocks for Function " << F << ":\n";
+ for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) {
+ dbgs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n";
+ }
+ }
+
+ for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
+ FI != FE; ++FI) {
+ typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI);
+ dbgs() << "Edges for Function " << ei->first << ":\n";
+ for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end();
+ ewi != ewe; ++ewi) {
+ dbgs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n";
+ }
+ }
+ } else {
+ assert(F && "No function given, this is not supported!");
+ dbgs() << "Functions: \n";
+ dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
+
+ dbgs() << "BasicBlocks for Function " << F << ":\n";
+ for (typename FType::const_iterator BI = F->begin(), BE = F->end();
+ BI != BE; ++BI) {
+ const BType *BB = &(*BI);
+ dbgs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n";
+ }
+ }
+ dbgs() << "**** ProfileInfo " << this << ", over and out.\n";
+ }
+
+ bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false);
+
+ bool EstimateMissingEdges(const BType *BB);
+
+ ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() {
+ if (MachineProfile == 0)
+ MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>();
+ return MachineProfile;
+ }
+
+ bool hasMI() const {
+ return (MachineProfile != 0);
+ }
+ };
+
+ typedef ProfileInfoT<Function, BasicBlock> ProfileInfo;
+ typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo;
+
+ /// createProfileLoaderPass - This function returns a Pass that loads the
+ /// profiling information for the module from the specified filename, making
+ /// it available to the optimizers.
+ Pass *createProfileLoaderPass(const std::string &Filename);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h b/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h
new file mode 100644
index 000000000000..9e0c393c428f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ProfileInfoLoader.h
@@ -0,0 +1,84 @@
+//===- ProfileInfoLoader.h - Load & convert profile information -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The ProfileInfoLoader class is used to load and represent profiling
+// information read in from the dump file. If conversions between formats are
+// needed, it can also do this.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
+#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
+
+#include <vector>
+#include <string>
+#include <utility>
+
+namespace llvm {
+
+class Module;
+class Function;
+class BasicBlock;
+
+class ProfileInfoLoader {
+ const std::string &Filename;
+ Module &M;
+ std::vector<std::string> CommandLines;
+ std::vector<unsigned> FunctionCounts;
+ std::vector<unsigned> BlockCounts;
+ std::vector<unsigned> EdgeCounts;
+ std::vector<unsigned> OptimalEdgeCounts;
+ std::vector<unsigned> BBTrace;
+ bool Warned;
+public:
+ // ProfileInfoLoader ctor - Read the specified profiling data file, exiting
+ // the program if the file is invalid or broken.
+ ProfileInfoLoader(const char *ToolName, const std::string &Filename,
+ Module &M);
+
+ static const unsigned Uncounted;
+
+ unsigned getNumExecutions() const { return CommandLines.size(); }
+ const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
+
+ const std::string &getFileName() const { return Filename; }
+
+ // getRawFunctionCounts - This method is used by consumers of function
+ // counting information.
+ //
+ const std::vector<unsigned> &getRawFunctionCounts() const {
+ return FunctionCounts;
+ }
+
+ // getRawBlockCounts - This method is used by consumers of block counting
+ // information.
+ //
+ const std::vector<unsigned> &getRawBlockCounts() const {
+ return BlockCounts;
+ }
+
+ // getEdgeCounts - This method is used by consumers of edge counting
+ // information.
+ //
+ const std::vector<unsigned> &getRawEdgeCounts() const {
+ return EdgeCounts;
+ }
+
+ // getEdgeOptimalCounts - This method is used by consumers of optimal edge
+ // counting information.
+ //
+ const std::vector<unsigned> &getRawOptimalEdgeCounts() const {
+ return OptimalEdgeCounts;
+ }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ProfileInfoTypes.h b/contrib/llvm/include/llvm/Analysis/ProfileInfoTypes.h
new file mode 100644
index 000000000000..6b4ac85082b0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ProfileInfoTypes.h
@@ -0,0 +1,60 @@
+/*===-- ProfileInfoTypes.h - Profiling info shared constants --------------===*\
+|*
+|* The LLVM Compiler Infrastructure
+|*
+|* This file is distributed under the University of Illinois Open Source
+|* License. See LICENSE.TXT for details.
+|*
+|*===----------------------------------------------------------------------===*|
+|*
+|* This file defines constants shared by the various different profiling
+|* runtime libraries and the LLVM C++ profile info loader. It must be a
+|* C header because, at present, the profiling runtimes are written in C.
+|*
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_ANALYSIS_PROFILEINFOTYPES_H
+#define LLVM_ANALYSIS_PROFILEINFOTYPES_H
+
+/* Included by libprofile. */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* IDs to distinguish between those path counters stored in hashses vs arrays */
+enum ProfilingStorageType {
+ ProfilingArray = 1,
+ ProfilingHash = 2
+};
+
+enum ProfilingType {
+ ArgumentInfo = 1, /* The command line argument block */
+ FunctionInfo = 2, /* Function profiling information */
+ BlockInfo = 3, /* Block profiling information */
+ EdgeInfo = 4, /* Edge profiling information */
+ PathInfo = 5, /* Path profiling information */
+ BBTraceInfo = 6, /* Basic block trace information */
+ OptEdgeInfo = 7 /* Edge profiling information, optimal version */
+};
+
+/*
+ * The header for tables that map path numbers to path counters.
+ */
+typedef struct {
+ unsigned fnNumber; /* function number for these counters */
+ unsigned numEntries; /* number of entries stored */
+} PathProfileHeader;
+
+/*
+ * Describes an entry in a tagged table for path counters.
+ */
+typedef struct {
+ unsigned pathNumber;
+ unsigned pathCounter;
+} PathProfileTableEntry;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* LLVM_ANALYSIS_PROFILEINFOTYPES_H */
diff --git a/contrib/llvm/include/llvm/Analysis/RegionInfo.h b/contrib/llvm/include/llvm/Analysis/RegionInfo.h
new file mode 100644
index 000000000000..b098eeaa3db8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/RegionInfo.h
@@ -0,0 +1,688 @@
+//===- RegionInfo.h - SESE region analysis ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate a program structure tree built out of single entry single exit
+// regions.
+// The basic ideas are taken from "The Program Structure Tree - Richard Johnson,
+// David Pearson, Keshav Pingali - 1994", however enriched with ideas from "The
+// Refined Process Structure Tree - Jussi Vanhatalo, Hagen Voelyer, Jana
+// Koehler - 2009".
+// The algorithm to calculate these data structures however is completely
+// different, as it takes advantage of existing information already available
+// in (Post)dominace tree and dominance frontier passes. This leads to a simpler
+// and in practice hopefully better performing algorithm. The runtime of the
+// algorithms described in the papers above are both linear in graph size,
+// O(V+E), whereas this algorithm is not, as the dominance frontier information
+// itself is not, but in practice runtime seems to be in the order of magnitude
+// of dominance tree calculation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGION_INFO_H
+#define LLVM_ANALYSIS_REGION_INFO_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Support/Allocator.h"
+#include <map>
+
+namespace llvm {
+
+class Region;
+class RegionInfo;
+class raw_ostream;
+class Loop;
+class LoopInfo;
+
+/// @brief Marker class to iterate over the elements of a Region in flat mode.
+///
+/// The class is used to either iterate in Flat mode or by not using it to not
+/// iterate in Flat mode. During a Flat mode iteration all Regions are entered
+/// and the iteration returns every BasicBlock. If the Flat mode is not
+/// selected for SubRegions just one RegionNode containing the subregion is
+/// returned.
+template <class GraphType>
+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 &);
+
+protected:
+ /// This is the entry basic block that starts this region node. If this is a
+ /// BasicBlock RegionNode, then entry is just the basic block, that this
+ /// RegionNode represents. Otherwise it is the entry of this (Sub)RegionNode.
+ ///
+ /// In the BBtoRegionNode map of the parent of this node, BB will always map
+ /// to this node no matter which kind of node this one is.
+ ///
+ /// The node can hold either a Region or a BasicBlock.
+ /// Use one bit to save, if this RegionNode is a subregion or BasicBlock
+ /// RegionNode.
+ PointerIntPair<BasicBlock*, 1, bool> entry;
+
+ /// @brief The parent Region of this RegionNode.
+ /// @see getParent()
+ Region* parent;
+
+public:
+ /// @brief Create a RegionNode.
+ ///
+ /// @param Parent The parent of this RegionNode.
+ /// @param Entry The entry BasicBlock of the RegionNode. If this
+ /// RegionNode represents a BasicBlock, this is the
+ /// BasicBlock itself. If it represents a subregion, this
+ /// is the entry BasicBlock of the subregion.
+ /// @param isSubRegion If this RegionNode represents a SubRegion.
+ inline RegionNode(Region* Parent, BasicBlock* Entry, bool isSubRegion = 0)
+ : entry(Entry, isSubRegion), parent(Parent) {}
+
+ /// @brief Get the parent Region of this RegionNode.
+ ///
+ /// The parent Region is the Region this RegionNode belongs to. If for
+ /// example a BasicBlock is element of two Regions, there exist two
+ /// RegionNodes for this BasicBlock. Each with the getParent() function
+ /// pointing to the Region this RegionNode belongs to.
+ ///
+ /// @return Get the parent Region of this RegionNode.
+ inline Region* getParent() const { return parent; }
+
+ /// @brief Get the entry BasicBlock of this RegionNode.
+ ///
+ /// If this RegionNode represents a BasicBlock this is just the BasicBlock
+ /// itself, otherwise we return the entry BasicBlock of the Subregion
+ ///
+ /// @return The entry BasicBlock of this RegionNode.
+ inline BasicBlock* getEntry() const { return entry.getPointer(); }
+
+ /// @brief Get the content of this RegionNode.
+ ///
+ /// This can be either a BasicBlock or a subregion. Before calling getNodeAs()
+ /// check the type of the content with the isSubRegion() function call.
+ ///
+ /// @return The content of this RegionNode.
+ template<class T>
+ inline T* getNodeAs() const;
+
+ /// @brief Is this RegionNode a subregion?
+ ///
+ /// @return True if it contains a subregion. False if it contains a
+ /// BasicBlock.
+ inline bool isSubRegion() const {
+ return entry.getInt();
+ }
+};
+
+/// Print a RegionNode.
+inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node);
+
+template<>
+inline BasicBlock* RegionNode::getNodeAs<BasicBlock>() const {
+ assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
+ return getEntry();
+}
+
+template<>
+inline Region* RegionNode::getNodeAs<Region>() const {
+ assert(isSubRegion() && "This is not a subregion RegionNode!");
+ return reinterpret_cast<Region*>(const_cast<RegionNode*>(this));
+}
+
+//===----------------------------------------------------------------------===//
+/// @brief A single entry single exit Region.
+///
+/// A Region is a connected subgraph of a control flow graph that has exactly
+/// two connections to the remaining graph. It can be used to analyze or
+/// optimize parts of the control flow graph.
+///
+/// A <em> simple Region </em> is connected to the remaining graph by just two
+/// edges. One edge entering the Region and another one leaving the Region.
+///
+/// An <em> extended Region </em> (or just Region) is a subgraph that can be
+/// transform into a simple Region. The transformation is done by adding
+/// BasicBlocks that merge several entry or exit edges so that after the merge
+/// just one entry and one exit edge exists.
+///
+/// The \e Entry of a Region is the first BasicBlock that is passed after
+/// entering the Region. It is an element of the Region. The entry BasicBlock
+/// dominates all BasicBlocks in the Region.
+///
+/// The \e Exit of a Region is the first BasicBlock that is passed after
+/// leaving the Region. It is not an element of the Region. The exit BasicBlock,
+/// postdominates all BasicBlocks in the Region.
+///
+/// A <em> canonical Region </em> cannot be constructed by combining smaller
+/// Regions.
+///
+/// Region A is the \e parent of Region B, if B is completely contained in A.
+///
+/// Two canonical Regions either do not intersect at all or one is
+/// the parent of the other.
+///
+/// The <em> Program Structure Tree</em> is a graph (V, E) where V is the set of
+/// Regions in the control flow graph and E is the \e parent relation of these
+/// Regions.
+///
+/// Example:
+///
+/// \verbatim
+/// A simple control flow graph, that contains two regions.
+///
+/// 1
+/// / |
+/// 2 |
+/// / \ 3
+/// 4 5 |
+/// | | |
+/// 6 7 8
+/// \ | /
+/// \ |/ Region A: 1 -> 9 {1,2,3,4,5,6,7,8}
+/// 9 Region B: 2 -> 9 {2,4,5,6,7}
+/// \endverbatim
+///
+/// You can obtain more examples by either calling
+///
+/// <tt> "opt -regions -analyze anyprogram.ll" </tt>
+/// or
+/// <tt> "opt -view-regions-only anyprogram.ll" </tt>
+///
+/// on any LLVM file you are interested in.
+///
+/// The first call returns a textual representation of the program structure
+/// 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 &);
+
+ // Information necessary to manage this Region.
+ RegionInfo* RI;
+ DominatorTree *DT;
+
+ // The exit BasicBlock of this region.
+ // (The entry BasicBlock is part of RegionNode)
+ BasicBlock *exit;
+
+ typedef std::vector<Region*> RegionSet;
+
+ // The subregions of this region.
+ RegionSet children;
+
+ typedef std::map<BasicBlock*, RegionNode*> BBNodeMapT;
+
+ // Save the BasicBlock RegionNodes that are element of this Region.
+ mutable BBNodeMapT BBNodeMap;
+
+ /// verifyBBInRegion - Check if a BB is in this Region. This check also works
+ /// if the region is incorrectly built. (EXPENSIVE!)
+ void verifyBBInRegion(BasicBlock* BB) const;
+
+ /// verifyWalk - Walk over all the BBs of the region starting from BB and
+ /// verify that all reachable basic blocks are elements of the region.
+ /// (EXPENSIVE!)
+ void verifyWalk(BasicBlock* BB, std::set<BasicBlock*>* visitedBB) const;
+
+ /// verifyRegionNest - Verify if the region and its children are valid
+ /// regions (EXPENSIVE!)
+ void verifyRegionNest() const;
+
+public:
+ /// @brief Create a new region.
+ ///
+ /// @param Entry The entry basic block of the region.
+ /// @param Exit The exit basic block of the region.
+ /// @param RI The region info object that is managing this region.
+ /// @param DT The dominator tree of the current function.
+ /// @param Parent The surrounding region or NULL if this is a top level
+ /// region.
+ Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RI,
+ DominatorTree *DT, Region *Parent = 0);
+
+ /// Delete the Region and all its subregions.
+ ~Region();
+
+ /// @brief Get the entry BasicBlock of the Region.
+ /// @return The entry BasicBlock of the region.
+ BasicBlock *getEntry() const { return RegionNode::getEntry(); }
+
+ /// @brief Replace the entry basic block of the region with the new basic
+ /// block.
+ ///
+ /// @param BB The new entry basic block of the region.
+ void replaceEntry(BasicBlock *BB);
+
+ /// @brief Replace the exit basic block of the region with the new basic
+ /// block.
+ ///
+ /// @param BB The new exit basic block of the region.
+ void replaceExit(BasicBlock *BB);
+
+ /// @brief Get the exit BasicBlock of the Region.
+ /// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
+ /// Region.
+ BasicBlock *getExit() const { return exit; }
+
+ /// @brief Get the parent of the Region.
+ /// @return The parent of the Region or NULL if this is a top level
+ /// Region.
+ Region *getParent() const { return RegionNode::getParent(); }
+
+ /// @brief Get the RegionNode representing the current Region.
+ /// @return The RegionNode representing the current Region.
+ RegionNode* getNode() const {
+ return const_cast<RegionNode*>(reinterpret_cast<const RegionNode*>(this));
+ }
+
+ /// @brief Get the nesting level of this Region.
+ ///
+ /// An toplevel Region has depth 0.
+ ///
+ /// @return The depth of the region.
+ unsigned getDepth() const;
+
+ /// @brief Check if a Region is the TopLevel region.
+ ///
+ /// The toplevel region represents the whole function.
+ bool isTopLevelRegion() const { return exit == NULL; }
+
+ /// @brief Return a new (non canonical) region, that is obtained by joining
+ /// this region with its predecessors.
+ ///
+ /// @return A region also starting at getEntry(), but reaching to the next
+ /// basic block that forms with getEntry() a (non canonical) region.
+ /// NULL if such a basic block does not exist.
+ Region *getExpandedRegion() const;
+
+ /// @brief Return the first block of this region's single entry edge,
+ /// if existing.
+ ///
+ /// @return The BasicBlock starting this region's single entry edge,
+ /// else NULL.
+ BasicBlock *getEnteringBlock() const;
+
+ /// @brief Return the first block of this region's single exit edge,
+ /// if existing.
+ ///
+ /// @return The BasicBlock starting this region's single exit edge,
+ /// else NULL.
+ BasicBlock *getExitingBlock() const;
+
+ /// @brief Is this a simple region?
+ ///
+ /// A region is simple if it has exactly one exit and one entry edge.
+ ///
+ /// @return True if the Region is simple.
+ bool isSimple() const;
+
+ /// @brief Returns the name of the Region.
+ /// @return The Name of the Region.
+ std::string getNameStr() const;
+
+ /// @brief Return the RegionInfo object, that belongs to this Region.
+ RegionInfo *getRegionInfo() const {
+ return RI;
+ }
+
+ /// PrintStyle - Print region in difference ways.
+ enum PrintStyle { PrintNone, PrintBB, PrintRN };
+
+ /// @brief Print the region.
+ ///
+ /// @param OS The output stream the Region is printed to.
+ /// @param printTree Print also the tree of subregions.
+ /// @param level The indentation level used for printing.
+ void print(raw_ostream& OS, bool printTree = true, unsigned level = 0,
+ enum PrintStyle Style = PrintNone) const;
+
+ /// @brief Print the region to stderr.
+ void dump() const;
+
+ /// @brief Check if the region contains a BasicBlock.
+ ///
+ /// @param BB The BasicBlock that might be contained in this Region.
+ /// @return True if the block is contained in the region otherwise false.
+ bool contains(const BasicBlock *BB) const;
+
+ /// @brief Check if the region contains another region.
+ ///
+ /// @param SubRegion The region that might be contained in this Region.
+ /// @return True if SubRegion is contained in the region otherwise false.
+ bool contains(const Region *SubRegion) const {
+ // Toplevel Region.
+ if (!getExit())
+ return true;
+
+ return contains(SubRegion->getEntry())
+ && (contains(SubRegion->getExit()) || SubRegion->getExit() == getExit());
+ }
+
+ /// @brief Check if the region contains an Instruction.
+ ///
+ /// @param Inst The Instruction that might be contained in this region.
+ /// @return True if the Instruction is contained in the region otherwise false.
+ bool contains(const Instruction *Inst) const {
+ return contains(Inst->getParent());
+ }
+
+ /// @brief Check if the region contains a loop.
+ ///
+ /// @param L The loop that might be contained in this region.
+ /// @return True if the loop is contained in the region otherwise false.
+ /// In case a NULL pointer is passed to this function the result
+ /// is false, except for the region that describes the whole function.
+ /// In that case true is returned.
+ bool contains(const Loop *L) const;
+
+ /// @brief Get the outermost loop in the region that contains a loop.
+ ///
+ /// Find for a Loop L the outermost loop OuterL that is a parent loop of L
+ /// and is itself contained in the region.
+ ///
+ /// @param L The loop the lookup is started.
+ /// @return The outermost loop in the region, NULL if such a loop does not
+ /// exist or if the region describes the whole function.
+ Loop *outermostLoopInRegion(Loop *L) const;
+
+ /// @brief Get the outermost loop in the region that contains a basic block.
+ ///
+ /// Find for a basic block BB the outermost loop L that contains BB and is
+ /// itself contained in the region.
+ ///
+ /// @param LI A pointer to a LoopInfo analysis.
+ /// @param BB The basic block surrounded by the loop.
+ /// @return The outermost loop in the region, NULL if such a loop does not
+ /// exist or if the region describes the whole function.
+ Loop *outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const;
+
+ /// @brief Get the subregion that starts at a BasicBlock
+ ///
+ /// @param BB The BasicBlock the subregion should start.
+ /// @return The Subregion if available, otherwise NULL.
+ Region* getSubRegionNode(BasicBlock *BB) const;
+
+ /// @brief Get the RegionNode for a BasicBlock
+ ///
+ /// @param BB The BasicBlock at which the RegionNode should start.
+ /// @return If available, the RegionNode that represents the subregion
+ /// starting at BB. If no subregion starts at BB, the RegionNode
+ /// representing BB.
+ RegionNode* getNode(BasicBlock *BB) const;
+
+ /// @brief Get the BasicBlock RegionNode for a BasicBlock
+ ///
+ /// @param BB The BasicBlock for which the RegionNode is requested.
+ /// @return The RegionNode representing the BB.
+ RegionNode* getBBNode(BasicBlock *BB) const;
+
+ /// @brief Add a new subregion to this Region.
+ ///
+ /// @param SubRegion The new subregion that will be added.
+ /// @param moveChildren Move the children of this region, that are also
+ /// contained in SubRegion into SubRegion.
+ void addSubRegion(Region *SubRegion, bool moveChildren = false);
+
+ /// @brief Remove a subregion from this Region.
+ ///
+ /// The subregion is not deleted, as it will probably be inserted into another
+ /// region.
+ /// @param SubRegion The SubRegion that will be removed.
+ Region *removeSubRegion(Region *SubRegion);
+
+ /// @brief Move all direct child nodes of this Region to another Region.
+ ///
+ /// @param To The Region the child nodes will be transferred to.
+ void transferChildrenTo(Region *To);
+
+ /// @brief Verify if the region is a correct region.
+ ///
+ /// Check if this is a correctly build Region. This is an expensive check, as
+ /// the complete CFG of the Region will be walked.
+ void verifyRegion() const;
+
+ /// @brief Clear the cache for BB RegionNodes.
+ ///
+ /// After calling this function the BasicBlock RegionNodes will be stored at
+ /// different memory locations. RegionNodes obtained before this function is
+ /// called are therefore not comparable to RegionNodes abtained afterwords.
+ void clearNodeCache();
+
+ /// @name Subregion Iterators
+ ///
+ /// These iterators iterator over all subregions of this Region.
+ //@{
+ typedef RegionSet::iterator iterator;
+ typedef RegionSet::const_iterator const_iterator;
+
+ iterator begin() { return children.begin(); }
+ iterator end() { return children.end(); }
+
+ const_iterator begin() const { return children.begin(); }
+ const_iterator end() const { return children.end(); }
+ //@}
+
+ /// @name BasicBlock Iterators
+ ///
+ /// These iterators iterate over all BasicBlock RegionNodes that are
+ /// contained in this Region. The iterator also iterates over BasicBlocks
+ /// that are elements of a subregion of this Region. It is therefore called a
+ /// flat iterator.
+ //@{
+ typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
+ GraphTraits<FlatIt<RegionNode*> > > block_iterator;
+
+ typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
+ false, GraphTraits<FlatIt<const RegionNode*> > >
+ const_block_iterator;
+
+ block_iterator block_begin();
+ block_iterator block_end();
+
+ const_block_iterator block_begin() const;
+ const_block_iterator block_end() const;
+ //@}
+
+ /// @name Element Iterators
+ ///
+ /// These iterators iterate over all BasicBlock and subregion RegionNodes that
+ /// are direct children of this Region. It does not iterate over any
+ /// RegionNodes that are also element of a subregion of this Region.
+ //@{
+ typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
+ GraphTraits<RegionNode*> > element_iterator;
+
+ typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
+ false, GraphTraits<const RegionNode*> >
+ const_element_iterator;
+
+ element_iterator element_begin();
+ element_iterator element_end();
+
+ const_element_iterator element_begin() const;
+ const_element_iterator element_end() const;
+ //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Analysis that detects all canonical Regions.
+///
+/// The RegionInfo pass detects all canonical regions in a function. The Regions
+/// are connected using the parent relation. This builds a Program Structure
+/// Tree.
+class RegionInfo : public FunctionPass {
+ typedef DenseMap<BasicBlock*,BasicBlock*> BBtoBBMap;
+ typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
+ typedef SmallPtrSet<Region*, 4> RegionSet;
+
+ // DO NOT IMPLEMENT
+ RegionInfo(const RegionInfo &);
+ // DO NOT IMPLEMENT
+ const RegionInfo &operator=(const RegionInfo &);
+
+ DominatorTree *DT;
+ PostDominatorTree *PDT;
+ DominanceFrontier *DF;
+
+ /// The top level region.
+ Region *TopLevelRegion;
+
+ /// Map every BB to the smallest region, that contains BB.
+ BBtoRegionMap BBtoRegion;
+
+ // isCommonDomFrontier - Returns true if BB is in the dominance frontier of
+ // entry, because it was inherited from exit. In the other case there is an
+ // edge going from entry to BB without passing exit.
+ bool isCommonDomFrontier(BasicBlock* BB, BasicBlock* entry,
+ BasicBlock* exit) const;
+
+ // isRegion - Check if entry and exit surround a valid region, based on
+ // dominance tree and dominance frontier.
+ bool isRegion(BasicBlock* entry, BasicBlock* exit) const;
+
+ // insertShortCut - Saves a shortcut pointing from entry to exit.
+ // This function may extend this shortcut if possible.
+ void insertShortCut(BasicBlock* entry, BasicBlock* exit,
+ BBtoBBMap* ShortCut) const;
+
+ // getNextPostDom - Returns the next BB that postdominates N, while skipping
+ // all post dominators that cannot finish a canonical region.
+ DomTreeNode *getNextPostDom(DomTreeNode* N, BBtoBBMap *ShortCut) const;
+
+ // isTrivialRegion - A region is trivial, if it contains only one BB.
+ bool isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const;
+
+ // createRegion - Creates a single entry single exit region.
+ Region *createRegion(BasicBlock *entry, BasicBlock *exit);
+
+ // findRegionsWithEntry - Detect all regions starting with bb 'entry'.
+ void findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut);
+
+ // scanForRegions - Detects regions in F.
+ void scanForRegions(Function &F, BBtoBBMap *ShortCut);
+
+ // getTopMostParent - Get the top most parent with the same entry block.
+ Region *getTopMostParent(Region *region);
+
+ // buildRegionsTree - build the region hierarchy after all region detected.
+ void buildRegionsTree(DomTreeNode *N, Region *region);
+
+ // Calculate - detecte all regions in function and build the region tree.
+ void Calculate(Function& F);
+
+ void releaseMemory();
+
+ // updateStatistics - Update statistic about created regions.
+ void updateStatistics(Region *R);
+
+ // isSimple - Check if a region is a simple region with exactly one entry
+ // edge and exactly one exit edge.
+ bool isSimple(Region* R) const;
+
+public:
+ static char ID;
+ explicit RegionInfo();
+
+ ~RegionInfo();
+
+ /// @name FunctionPass interface
+ //@{
+ virtual bool runOnFunction(Function &F);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void print(raw_ostream &OS, const Module *) const;
+ virtual void verifyAnalysis() const;
+ //@}
+
+ /// @brief Get the smallest region that contains a BasicBlock.
+ ///
+ /// @param BB The basic block.
+ /// @return The smallest region, that contains BB or NULL, if there is no
+ /// region containing BB.
+ Region *getRegionFor(BasicBlock *BB) const;
+
+ /// @brief Set the smallest region that surrounds a basic block.
+ ///
+ /// @param BB The basic block surrounded by a region.
+ /// @param R The smallest region that surrounds BB.
+ void setRegionFor(BasicBlock *BB, Region *R);
+
+ /// @brief A shortcut for getRegionFor().
+ ///
+ /// @param BB The basic block.
+ /// @return The smallest region, that contains BB or NULL, if there is no
+ /// region containing BB.
+ Region *operator[](BasicBlock *BB) const;
+
+ /// @brief Return the exit of the maximal refined region, that starts at a
+ /// BasicBlock.
+ ///
+ /// @param BB The BasicBlock the refined region starts.
+ BasicBlock *getMaxRegionExit(BasicBlock *BB) const;
+
+ /// @brief Find the smallest region that contains two regions.
+ ///
+ /// @param A The first region.
+ /// @param B The second region.
+ /// @return The smallest region containing A and B.
+ Region *getCommonRegion(Region* A, Region *B) const;
+
+ /// @brief Find the smallest region that contains two basic blocks.
+ ///
+ /// @param A The first basic block.
+ /// @param B The second basic block.
+ /// @return The smallest region that contains A and B.
+ Region* getCommonRegion(BasicBlock* A, BasicBlock *B) const {
+ return getCommonRegion(getRegionFor(A), getRegionFor(B));
+ }
+
+ /// @brief Find the smallest region that contains a set of regions.
+ ///
+ /// @param Regions A vector of regions.
+ /// @return The smallest region that contains all regions in Regions.
+ Region* getCommonRegion(SmallVectorImpl<Region*> &Regions) const;
+
+ /// @brief Find the smallest region that contains a set of basic blocks.
+ ///
+ /// @param BBs A vector of basic blocks.
+ /// @return The smallest region that contains all basic blocks in BBS.
+ Region* getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const;
+
+ Region *getTopLevelRegion() const {
+ return TopLevelRegion;
+ }
+
+ /// @brief Update RegionInfo after a basic block was split.
+ ///
+ /// @param NewBB The basic block that was created before OldBB.
+ /// @param OldBB The old basic block.
+ void splitBlock(BasicBlock* NewBB, BasicBlock *OldBB);
+
+ /// @brief Clear the Node Cache for all Regions.
+ ///
+ /// @see Region::clearNodeCache()
+ void clearNodeCache() {
+ if (TopLevelRegion)
+ TopLevelRegion->clearNodeCache();
+ }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node) {
+ if (Node.isSubRegion())
+ return OS << Node.getNodeAs<Region>()->getNameStr();
+ else
+ return OS << Node.getNodeAs<BasicBlock>()->getName();
+}
+} // End llvm namespace
+#endif
+
diff --git a/contrib/llvm/include/llvm/Analysis/RegionIterator.h b/contrib/llvm/include/llvm/Analysis/RegionIterator.h
new file mode 100644
index 000000000000..7adc71ca82ac
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/RegionIterator.h
@@ -0,0 +1,342 @@
+//===- RegionIterator.h - Iterators to iteratate over Regions ---*- 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 iterators to iterate over the elements of a Region.
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
+#define LLVM_ANALYSIS_REGION_ITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+//===----------------------------------------------------------------------===//
+/// @brief Hierarchical RegionNode successor iterator.
+///
+/// This iterator iterates over all successors of a RegionNode.
+///
+/// For a BasicBlock RegionNode it skips all BasicBlocks that are not part of
+/// the parent Region. Furthermore for BasicBlocks that start a subregion, a
+/// RegionNode representing the subregion is returned.
+///
+/// For a subregion RegionNode there is just one successor. The RegionNode
+/// representing the exit of the subregion.
+template<class NodeType>
+class RNSuccIterator : public std::iterator<std::forward_iterator_tag,
+ NodeType, ptrdiff_t>
+{
+ typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
+ // The iterator works in two modes, bb mode or region mode.
+ enum ItMode{
+ // In BB mode it returns all successors of this BasicBlock as its
+ // successors.
+ ItBB,
+ // In region mode there is only one successor, thats the regionnode mapping
+ // to the exit block of the regionnode
+ ItRgBegin, // At the beginning of the regionnode successor.
+ ItRgEnd // At the end of the regionnode successor.
+ };
+
+ // Use two bit to represent the mode iterator.
+ PointerIntPair<NodeType*, 2, enum ItMode> Node;
+
+ // The block successor iterator.
+ succ_iterator BItor;
+
+ // advanceRegionSucc - A region node has only one successor. It reaches end
+ // once we advance it.
+ void advanceRegionSucc() {
+ assert(Node.getInt() == ItRgBegin && "Cannot advance region successor!");
+ Node.setInt(ItRgEnd);
+ }
+
+ NodeType* getNode() const{ return Node.getPointer(); }
+
+ // isRegionMode - Is the current iterator in region mode?
+ bool isRegionMode() const { return Node.getInt() != ItBB; }
+
+ // Get the immediate successor. This function may return a Basic Block
+ // RegionNode or a subregion RegionNode.
+ RegionNode* getISucc(BasicBlock* BB) const {
+ RegionNode *succ;
+ succ = getNode()->getParent()->getNode(BB);
+ assert(succ && "BB not in Region or entered subregion!");
+ return succ;
+ }
+
+ // getRegionSucc - Return the successor basic block of a SubRegion RegionNode.
+ inline BasicBlock* getRegionSucc() const {
+ assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");
+ return getNode()->template getNodeAs<Region>()->getExit();
+ }
+
+ // isExit - Is this the exit BB of the Region?
+ inline bool isExit(BasicBlock* BB) const {
+ return getNode()->getParent()->getExit() == BB;
+ }
+public:
+ typedef RNSuccIterator<NodeType> Self;
+
+ typedef typename super::pointer pointer;
+
+ /// @brief Create begin iterator of a RegionNode.
+ inline RNSuccIterator(NodeType* node)
+ : Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
+ BItor(succ_begin(node->getEntry())) {
+
+
+ // Skip the exit block
+ if (!isRegionMode())
+ while (succ_end(node->getEntry()) != BItor && isExit(*BItor))
+ ++BItor;
+
+ if (isRegionMode() && isExit(getRegionSucc()))
+ advanceRegionSucc();
+ }
+
+ /// @brief Create an end iterator.
+ inline RNSuccIterator(NodeType* node, bool)
+ : Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
+ BItor(succ_end(node->getEntry())) {}
+
+ inline bool operator==(const Self& x) const {
+ assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");
+ if (isRegionMode())
+ return Node.getInt() == x.Node.getInt();
+ else
+ return BItor == x.BItor;
+ }
+
+ inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ BasicBlock* BB = isRegionMode() ? getRegionSucc() : *BItor;
+ assert(!isExit(BB) && "Iterator out of range!");
+ return getISucc(BB);
+ }
+
+ inline Self& operator++() {
+ if(isRegionMode()) {
+ // The Region only has 1 successor.
+ advanceRegionSucc();
+ } else {
+ // Skip the exit.
+ do
+ ++BItor;
+ while (BItor != succ_end(getNode()->getEntry())
+ && isExit(*BItor));
+ }
+ return *this;
+ }
+
+ inline Self operator++(int) {
+ Self tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ inline const Self &operator=(const Self &I) {
+ if (this != &I) {
+ assert(getNode()->getParent() == I.getNode()->getParent()
+ && "Cannot assign iterators of two different regions!");
+ Node = I.Node;
+ BItor = I.BItor;
+ }
+ return *this;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// @brief Flat RegionNode iterator.
+///
+/// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
+/// are contained in the Region and its subregions. This is close to a virtual
+/// control flow graph of the Region.
+template<class NodeType>
+class RNSuccIterator<FlatIt<NodeType> >
+ : public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t>
+{
+ typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
+ NodeType* Node;
+ succ_iterator Itor;
+
+public:
+ typedef RNSuccIterator<FlatIt<NodeType> > Self;
+ typedef typename super::pointer pointer;
+
+ /// @brief Create the iterator from a RegionNode.
+ ///
+ /// Note that the incoming node must be a bb node, otherwise it will trigger
+ /// an assertion when we try to get a BasicBlock.
+ inline RNSuccIterator(NodeType* node) : Node(node),
+ Itor(succ_begin(node->getEntry())) {
+ assert(!Node->isSubRegion()
+ && "Subregion node not allowed in flat iterating mode!");
+ assert(Node->getParent() && "A BB node must have a parent!");
+
+ // Skip the exit block of the iterating region.
+ while (succ_end(Node->getEntry()) != Itor
+ && Node->getParent()->getExit() == *Itor)
+ ++Itor;
+ }
+ /// @brief Create an end iterator
+ inline RNSuccIterator(NodeType* node, bool) : Node(node),
+ Itor(succ_end(node->getEntry())) {
+ assert(!Node->isSubRegion()
+ && "Subregion node not allowed in flat iterating mode!");
+ }
+
+ inline bool operator==(const Self& x) const {
+ assert(Node->getParent() == x.Node->getParent()
+ && "Cannot compare iterators of different regions!");
+
+ return Itor == x.Itor && Node == x.Node;
+ }
+
+ inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ BasicBlock* BB = *Itor;
+
+ // Get the iterating region.
+ Region* Parent = Node->getParent();
+
+ // The only case that the successor reaches out of the region is it reaches
+ // the exit of the region.
+ assert(Parent->getExit() != BB && "iterator out of range!");
+
+ return Parent->getBBNode(BB);
+ }
+
+ inline Self& operator++() {
+ // Skip the exit block of the iterating region.
+ do
+ ++Itor;
+ while (Itor != succ_end(Node->getEntry())
+ && Node->getParent()->getExit() == *Itor);
+
+ return *this;
+ }
+
+ inline Self operator++(int) {
+ Self tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ inline const Self &operator=(const Self &I) {
+ if (this != &I) {
+ assert(Node->getParent() == I.Node->getParent()
+ && "Cannot assign iterators to two different regions!");
+ Node = I.Node;
+ Itor = I.Itor;
+ }
+ return *this;
+ }
+};
+
+template<class NodeType>
+inline RNSuccIterator<NodeType> succ_begin(NodeType* Node) {
+ return RNSuccIterator<NodeType>(Node);
+}
+
+template<class NodeType>
+inline RNSuccIterator<NodeType> succ_end(NodeType* Node) {
+ return RNSuccIterator<NodeType>(Node, true);
+}
+
+//===--------------------------------------------------------------------===//
+// RegionNode GraphTraits specialization so the bbs in the region can be
+// iterate by generic graph iterators.
+//
+// NodeT can either be region node or const region node, otherwise child_begin
+// and child_end fail.
+
+#define RegionNodeGraphTraits(NodeT) \
+ template<> struct GraphTraits<NodeT*> { \
+ typedef NodeT NodeType; \
+ typedef RNSuccIterator<NodeType> ChildIteratorType; \
+ static NodeType *getEntryNode(NodeType* N) { return N; } \
+ static inline ChildIteratorType child_begin(NodeType *N) { \
+ return RNSuccIterator<NodeType>(N); \
+ } \
+ static inline ChildIteratorType child_end(NodeType *N) { \
+ return RNSuccIterator<NodeType>(N, true); \
+ } \
+}; \
+template<> struct GraphTraits<FlatIt<NodeT*> > { \
+ typedef NodeT NodeType; \
+ typedef RNSuccIterator<FlatIt<NodeT> > ChildIteratorType; \
+ static NodeType *getEntryNode(NodeType* N) { return N; } \
+ static inline ChildIteratorType child_begin(NodeType *N) { \
+ return RNSuccIterator<FlatIt<NodeType> >(N); \
+ } \
+ static inline ChildIteratorType child_end(NodeType *N) { \
+ return RNSuccIterator<FlatIt<NodeType> >(N, true); \
+ } \
+}
+
+#define RegionGraphTraits(RegionT, NodeT) \
+template<> struct GraphTraits<RegionT*> \
+ : public GraphTraits<NodeT*> { \
+ typedef df_iterator<NodeType*> nodes_iterator; \
+ static NodeType *getEntryNode(RegionT* R) { \
+ return R->getNode(R->getEntry()); \
+ } \
+ static nodes_iterator nodes_begin(RegionT* R) { \
+ return nodes_iterator::begin(getEntryNode(R)); \
+ } \
+ static nodes_iterator nodes_end(RegionT* R) { \
+ return nodes_iterator::end(getEntryNode(R)); \
+ } \
+}; \
+template<> struct GraphTraits<FlatIt<RegionT*> > \
+ : public GraphTraits<FlatIt<NodeT*> > { \
+ typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, \
+ GraphTraits<FlatIt<NodeType*> > > nodes_iterator; \
+ static NodeType *getEntryNode(RegionT* R) { \
+ return R->getBBNode(R->getEntry()); \
+ } \
+ static nodes_iterator nodes_begin(RegionT* R) { \
+ return nodes_iterator::begin(getEntryNode(R)); \
+ } \
+ static nodes_iterator nodes_end(RegionT* R) { \
+ return nodes_iterator::end(getEntryNode(R)); \
+ } \
+}
+
+RegionNodeGraphTraits(RegionNode);
+RegionNodeGraphTraits(const RegionNode);
+
+RegionGraphTraits(Region, RegionNode);
+RegionGraphTraits(const Region, const RegionNode);
+
+template <> struct GraphTraits<RegionInfo*>
+ : public GraphTraits<FlatIt<RegionNode*> > {
+ typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
+ GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
+
+ static NodeType *getEntryNode(RegionInfo *RI) {
+ return GraphTraits<FlatIt<Region*> >::getEntryNode(RI->getTopLevelRegion());
+ }
+ static nodes_iterator nodes_begin(RegionInfo* RI) {
+ return nodes_iterator::begin(getEntryNode(RI));
+ }
+ static nodes_iterator nodes_end(RegionInfo *RI) {
+ return nodes_iterator::end(getEntryNode(RI));
+ }
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/RegionPass.h b/contrib/llvm/include/llvm/Analysis/RegionPass.h
new file mode 100644
index 000000000000..68f12012bcd1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/RegionPass.h
@@ -0,0 +1,126 @@
+//===- RegionPass.h - RegionPass class ------------------------------------===//
+//
+// 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 RegionPass class. All region based analysis,
+// optimization and transformation passes are derived from RegionPass.
+// This class is implemented following the some ideas of the LoopPass.h class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REGION_PASS_H
+#define LLVM_REGION_PASS_H
+
+#include "llvm/Analysis/RegionInfo.h"
+
+#include "llvm/Pass.h"
+#include "llvm/PassManagers.h"
+#include "llvm/Function.h"
+
+#include <deque>
+
+namespace llvm {
+
+class RGPassManager;
+class Function;
+
+//===----------------------------------------------------------------------===//
+/// @brief A pass that runs on each Region in a function.
+///
+/// RegionPass is managed by RGPassManager.
+class RegionPass : public Pass {
+public:
+ explicit RegionPass(char &pid) : Pass(PT_Region, pid) {}
+
+ //===--------------------------------------------------------------------===//
+ /// @name To be implemented by every RegionPass
+ ///
+ //@{
+ /// @brief Run the pass on a specific Region
+ ///
+ /// Accessing regions not contained in the current region is not allowed.
+ ///
+ /// @param R The region this pass is run on.
+ /// @param RGM The RegionPassManager that manages this Pass.
+ ///
+ /// @return True if the pass modifies this Region.
+ virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0;
+
+ /// @brief Get a pass to print the LLVM IR in the region.
+ ///
+ /// @param O The ouput stream to print the Region.
+ /// @param Banner The banner to separate different printed passes.
+ ///
+ /// @return The pass to print the LLVM IR in the region.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
+ virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
+ virtual bool doFinalization() { return false; }
+ //@}
+
+ //===--------------------------------------------------------------------===//
+ /// @name PassManager API
+ ///
+ //@{
+ void preparePassManager(PMStack &PMS);
+
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType PMT = PMT_RegionPassManager);
+
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_RegionPassManager;
+ }
+ //@}
+};
+
+/// @brief The pass manager to schedule RegionPasses.
+class RGPassManager : public FunctionPass, public PMDataManager {
+ std::deque<Region*> RQ;
+ bool skipThisRegion;
+ bool redoThisRegion;
+ RegionInfo *RI;
+ Region *CurrentRegion;
+
+public:
+ static char ID;
+ explicit RGPassManager();
+
+ /// @brief Execute all of the passes scheduled for execution.
+ ///
+ /// @return True if any of the passes modifies the function.
+ bool runOnFunction(Function &F);
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ /// RGPassManager needs RegionInfo.
+ void getAnalysisUsage(AnalysisUsage &Info) const;
+
+ virtual const char *getPassName() const {
+ return "Region Pass Manager";
+ }
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
+ /// @brief Print passes managed by this manager.
+ void dumpPassStructure(unsigned Offset);
+
+ /// @brief Get passes contained by this manager.
+ Pass *getContainedPass(unsigned N) {
+ assert(N < PassVector.size() && "Pass number out of range!");
+ Pass *FP = static_cast<Pass *>(PassVector[N]);
+ return FP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_RegionPassManager;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/RegionPrinter.h b/contrib/llvm/include/llvm/Analysis/RegionPrinter.h
new file mode 100644
index 000000000000..758748aad9e6
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/RegionPrinter.h
@@ -0,0 +1,26 @@
+//===-- RegionPrinter.h - Region printer external interface -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines external functions that can be called to explicitly
+// instantiate the region printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_REGIONPRINTER_H
+#define LLVM_ANALYSIS_REGIONPRINTER_H
+
+namespace llvm {
+ class FunctionPass;
+ FunctionPass *createRegionViewerPass();
+ FunctionPass *createRegionOnlyViewerPass();
+ FunctionPass *createRegionPrinterPass();
+ FunctionPass *createRegionOnlyPrinterPass();
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h
new file mode 100644
index 000000000000..72408f773840
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -0,0 +1,885 @@
+//===- llvm/Analysis/ScalarEvolution.h - Scalar Evolution -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The ScalarEvolution class is an LLVM pass which can be used to analyze and
+// categorize scalar expressions in loops. It specializes in recognizing
+// general induction variables, representing them with the abstract and opaque
+// SCEV class. Given this analysis, trip counts of loops and other important
+// properties can be obtained.
+//
+// This analysis is primarily useful for induction variable substitution and
+// strength reduction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_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/DenseMap.h"
+#include <map>
+
+namespace llvm {
+ class APInt;
+ class Constant;
+ class ConstantInt;
+ class DominatorTree;
+ class Type;
+ class ScalarEvolution;
+ class TargetData;
+ class TargetLibraryInfo;
+ class LLVMContext;
+ class Loop;
+ class LoopInfo;
+ class Operator;
+ class SCEVUnknown;
+ class SCEV;
+ template<> struct FoldingSetTrait<SCEV>;
+
+ /// SCEV - This class represents an analyzed expression in the program. These
+ /// are opaque objects that the client is not allowed to do much with
+ /// directly.
+ ///
+ class SCEV : public FoldingSetNode {
+ friend struct FoldingSetTrait<SCEV>;
+
+ /// FastID - A reference to an Interned FoldingSetNodeID for this node.
+ /// The ScalarEvolution's BumpPtrAllocator holds the data.
+ FoldingSetNodeIDRef FastID;
+
+ // The SCEV baseclass this node corresponds to
+ const unsigned short SCEVType;
+
+ protected:
+ /// SubclassData - This field is initialized to zero and may be used in
+ /// subclasses to store miscellaneous information.
+ unsigned short SubclassData;
+
+ private:
+ SCEV(const SCEV &); // DO NOT IMPLEMENT
+ void operator=(const SCEV &); // DO NOT IMPLEMENT
+
+ public:
+ /// NoWrapFlags are bitfield indices into SubclassData.
+ ///
+ /// Add and Mul expressions may have no-unsigned-wrap <NUW> or
+ /// no-signed-wrap <NSW> properties, which are derived from the IR
+ /// operator. NSW is a misnomer that we use to mean no signed overflow or
+ /// underflow.
+ ///
+ /// AddRec expression may have a no-self-wraparound <NW> property if the
+ /// result can never reach the start value. This property is independent of
+ /// the actual start value and step direction. Self-wraparound is defined
+ /// purely in terms of the recurrence's loop, step size, and
+ /// bitwidth. Formally, a recurrence with no self-wraparound satisfies:
+ /// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth).
+ ///
+ /// Note that NUW and NSW are also valid properties of a recurrence, and
+ /// either implies NW. For convenience, NW will be set for a recurrence
+ /// whenever either NUW or NSW are set.
+ enum NoWrapFlags { FlagAnyWrap = 0, // No guarantee.
+ FlagNW = (1 << 0), // No self-wrap.
+ FlagNUW = (1 << 1), // No unsigned wrap.
+ FlagNSW = (1 << 2), // No signed wrap.
+ NoWrapMask = (1 << 3) -1 };
+
+ explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
+ FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
+
+ unsigned getSCEVType() const { return SCEVType; }
+
+ /// getType - Return the LLVM type of this SCEV expression.
+ ///
+ Type *getType() const;
+
+ /// isZero - Return true if the expression is a constant zero.
+ ///
+ bool isZero() const;
+
+ /// isOne - Return true if the expression is a constant one.
+ ///
+ bool isOne() const;
+
+ /// isAllOnesValue - Return true if the expression is a constant
+ /// all-ones value.
+ ///
+ bool isAllOnesValue() const;
+
+ /// isNonConstantNegative - Return true if the specified scev is negated,
+ /// but not a constant.
+ bool isNonConstantNegative() const;
+
+ /// print - Print out the internal representation of this scalar to the
+ /// specified stream. This should really only be used for debugging
+ /// purposes.
+ void print(raw_ostream &OS) const;
+
+ /// dump - This method is used for debugging.
+ ///
+ void dump() const;
+ };
+
+ // Specialize FoldingSetTrait for SCEV to avoid needing to compute
+ // temporary FoldingSetNodeID values.
+ template<> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> {
+ static void Profile(const SCEV &X, FoldingSetNodeID& ID) {
+ ID = X.FastID;
+ }
+ static bool Equals(const SCEV &X, const FoldingSetNodeID &ID,
+ unsigned IDHash, FoldingSetNodeID &TempID) {
+ return ID == X.FastID;
+ }
+ static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) {
+ return X.FastID.ComputeHash();
+ }
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) {
+ S.print(OS);
+ return OS;
+ }
+
+ /// SCEVCouldNotCompute - An object of this class is returned by queries that
+ /// could not be answered. For example, if you ask for the number of
+ /// iterations of a linked-list traversal loop, you will get one of these.
+ /// None of the standard SCEV operations are valid on this class, it is just a
+ /// marker.
+ struct SCEVCouldNotCompute : public SCEV {
+ 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);
+ };
+
+ /// ScalarEvolution - This class is the main scalar evolution driver. Because
+ /// client code (intentionally) can't do much with the SCEV objects directly,
+ /// they must ask this class for services.
+ ///
+ class ScalarEvolution : public FunctionPass {
+ public:
+ /// LoopDisposition - An enum describing the relationship between a
+ /// SCEV and a loop.
+ enum LoopDisposition {
+ LoopVariant, ///< The SCEV is loop-variant (unknown).
+ LoopInvariant, ///< The SCEV is loop-invariant.
+ LoopComputable ///< The SCEV varies predictably with the loop.
+ };
+
+ /// BlockDisposition - An enum describing the relationship between a
+ /// SCEV and a basic block.
+ enum BlockDisposition {
+ DoesNotDominateBlock, ///< The SCEV does not dominate the block.
+ DominatesBlock, ///< The SCEV dominates the block.
+ ProperlyDominatesBlock ///< The SCEV properly dominates the block.
+ };
+
+ /// Convenient NoWrapFlags manipulation that hides enum casts and is
+ /// visible in the ScalarEvolution name space.
+ static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask) {
+ return (SCEV::NoWrapFlags)(Flags & Mask);
+ }
+ static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags,
+ SCEV::NoWrapFlags OnFlags) {
+ return (SCEV::NoWrapFlags)(Flags | OnFlags);
+ }
+ static SCEV::NoWrapFlags clearFlags(SCEV::NoWrapFlags Flags,
+ SCEV::NoWrapFlags OffFlags) {
+ return (SCEV::NoWrapFlags)(Flags & ~OffFlags);
+ }
+
+ private:
+ /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
+ /// notified whenever a Value is deleted.
+ class SCEVCallbackVH : public CallbackVH {
+ ScalarEvolution *SE;
+ virtual void deleted();
+ virtual void allUsesReplacedWith(Value *New);
+ public:
+ SCEVCallbackVH(Value *V, ScalarEvolution *SE = 0);
+ };
+
+ friend class SCEVCallbackVH;
+ friend class SCEVExpander;
+ friend class SCEVUnknown;
+
+ /// F - The function we are analyzing.
+ ///
+ Function *F;
+
+ /// LI - The loop information for the function we are currently analyzing.
+ ///
+ LoopInfo *LI;
+
+ /// TD - The target data information for the target we are targeting.
+ ///
+ TargetData *TD;
+
+ /// TLI - The target library information for the target we are targeting.
+ ///
+ TargetLibraryInfo *TLI;
+
+ /// DT - The dominator tree.
+ ///
+ DominatorTree *DT;
+
+ /// CouldNotCompute - This SCEV is used to represent unknown trip
+ /// counts and things.
+ SCEVCouldNotCompute CouldNotCompute;
+
+ /// ValueExprMapType - The typedef for ValueExprMap.
+ ///
+ typedef DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *> >
+ ValueExprMapType;
+
+ /// ValueExprMap - This is a cache of the values we have analyzed so far.
+ ///
+ ValueExprMapType ValueExprMap;
+
+ /// ExitLimit - Information about the number of loop iterations for
+ /// which a loop exit's branch condition evaluates to the not-taken path.
+ /// This is a temporary pair of exact and max expressions that are
+ /// eventually summarized in ExitNotTakenInfo and BackedgeTakenInfo.
+ struct ExitLimit {
+ const SCEV *Exact;
+ const SCEV *Max;
+
+ /*implicit*/ ExitLimit(const SCEV *E) : Exact(E), Max(E) {}
+
+ ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {}
+
+ /// hasAnyInfo - Test whether this ExitLimit contains any computed
+ /// information, or whether it's all SCEVCouldNotCompute values.
+ bool hasAnyInfo() const {
+ return !isa<SCEVCouldNotCompute>(Exact) ||
+ !isa<SCEVCouldNotCompute>(Max);
+ }
+ };
+
+ /// ExitNotTakenInfo - Information about the number of times a particular
+ /// loop exit may be reached before exiting the loop.
+ struct ExitNotTakenInfo {
+ AssertingVH<BasicBlock> ExitingBlock;
+ const SCEV *ExactNotTaken;
+ PointerIntPair<ExitNotTakenInfo*, 1> NextExit;
+
+ ExitNotTakenInfo() : ExitingBlock(0), ExactNotTaken(0) {}
+
+ /// isCompleteList - Return true if all loop exits are computable.
+ bool isCompleteList() const {
+ return NextExit.getInt() == 0;
+ }
+
+ void setIncomplete() { NextExit.setInt(1); }
+
+ /// getNextExit - Return a pointer to the next exit's not-taken info.
+ ExitNotTakenInfo *getNextExit() const {
+ return NextExit.getPointer();
+ }
+
+ void setNextExit(ExitNotTakenInfo *ENT) { NextExit.setPointer(ENT); }
+ };
+
+ /// BackedgeTakenInfo - Information about the backedge-taken count
+ /// of a loop. This currently includes an exact count and a maximum count.
+ ///
+ class BackedgeTakenInfo {
+ /// ExitNotTaken - A list of computable exits and their not-taken counts.
+ /// Loops almost never have more than one computable exit.
+ ExitNotTakenInfo ExitNotTaken;
+
+ /// Max - An expression indicating the least maximum backedge-taken
+ /// count of the loop that is known, or a SCEVCouldNotCompute.
+ const SCEV *Max;
+
+ public:
+ BackedgeTakenInfo() : Max(0) {}
+
+ /// Initialize BackedgeTakenInfo from a list of exact exit counts.
+ BackedgeTakenInfo(
+ SmallVectorImpl< std::pair<BasicBlock *, const SCEV *> > &ExitCounts,
+ bool Complete, const SCEV *MaxCount);
+
+ /// hasAnyInfo - Test whether this BackedgeTakenInfo contains any
+ /// computed information, or whether it's all SCEVCouldNotCompute
+ /// values.
+ bool hasAnyInfo() const {
+ return ExitNotTaken.ExitingBlock || !isa<SCEVCouldNotCompute>(Max);
+ }
+
+ /// getExact - Return an expression indicating the exact backedge-taken
+ /// count of the loop if it is known, or SCEVCouldNotCompute
+ /// otherwise. This is the number of times the loop header can be
+ /// guaranteed to execute, minus one.
+ const SCEV *getExact(ScalarEvolution *SE) const;
+
+ /// getExact - Return the number of times this loop exit may fall through
+ /// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not
+ /// to exit via this block before this number of iterations, but may exit
+ /// via another block.
+ const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const;
+
+ /// getMax - Get the max backedge taken count for the loop.
+ const SCEV *getMax(ScalarEvolution *SE) const;
+
+ /// clear - Invalidate this result and free associated memory.
+ void clear();
+ };
+
+ /// BackedgeTakenCounts - Cache the backedge-taken count of the loops for
+ /// this function as they are computed.
+ DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts;
+
+ /// ConstantEvolutionLoopExitValue - This map contains entries for all of
+ /// the PHI instructions that we attempt to compute constant evolutions for.
+ /// This allows us to avoid potentially expensive recomputation of these
+ /// properties. An instruction maps to null if we are unable to compute its
+ /// exit value.
+ DenseMap<PHINode*, Constant*> ConstantEvolutionLoopExitValue;
+
+ /// ValuesAtScopes - This map contains entries for all the expressions
+ /// that we attempt to compute getSCEVAtScope information for, which can
+ /// be expensive in extreme cases.
+ DenseMap<const SCEV *,
+ std::map<const Loop *, const SCEV *> > ValuesAtScopes;
+
+ /// LoopDispositions - Memoized computeLoopDisposition results.
+ DenseMap<const SCEV *,
+ std::map<const Loop *, LoopDisposition> > LoopDispositions;
+
+ /// computeLoopDisposition - Compute a LoopDisposition value.
+ LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L);
+
+ /// BlockDispositions - Memoized computeBlockDisposition results.
+ DenseMap<const SCEV *,
+ std::map<const BasicBlock *, BlockDisposition> > BlockDispositions;
+
+ /// computeBlockDisposition - Compute a BlockDisposition value.
+ BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB);
+
+ /// UnsignedRanges - Memoized results from getUnsignedRange
+ DenseMap<const SCEV *, ConstantRange> UnsignedRanges;
+
+ /// SignedRanges - Memoized results from getSignedRange
+ DenseMap<const SCEV *, ConstantRange> SignedRanges;
+
+ /// setUnsignedRange - Set the memoized unsigned range for the given SCEV.
+ const ConstantRange &setUnsignedRange(const SCEV *S,
+ const ConstantRange &CR) {
+ std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
+ UnsignedRanges.insert(std::make_pair(S, CR));
+ if (!Pair.second)
+ Pair.first->second = CR;
+ return Pair.first->second;
+ }
+
+ /// setUnsignedRange - Set the memoized signed range for the given SCEV.
+ const ConstantRange &setSignedRange(const SCEV *S,
+ const ConstantRange &CR) {
+ std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
+ SignedRanges.insert(std::make_pair(S, CR));
+ if (!Pair.second)
+ Pair.first->second = CR;
+ return Pair.first->second;
+ }
+
+ /// createSCEV - We know that there is no SCEV for the specified value.
+ /// Analyze the expression.
+ const SCEV *createSCEV(Value *V);
+
+ /// createNodeForPHI - Provide the special handling we need to analyze PHI
+ /// SCEVs.
+ const SCEV *createNodeForPHI(PHINode *PN);
+
+ /// createNodeForGEP - Provide the special handling we need to analyze GEP
+ /// SCEVs.
+ const SCEV *createNodeForGEP(GEPOperator *GEP);
+
+ /// computeSCEVAtScope - Implementation code for getSCEVAtScope; called
+ /// at most once for each SCEV+Loop pair.
+ ///
+ const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L);
+
+ /// ForgetSymbolicValue - This looks up computed SCEV values for all
+ /// instructions that depend on the given instruction and removes them from
+ /// the ValueExprMap map if they reference SymName. This is used during PHI
+ /// resolution.
+ void ForgetSymbolicName(Instruction *I, const SCEV *SymName);
+
+ /// getBECount - Subtract the end and start values and divide by the step,
+ /// rounding up, to get the number of times the backedge is executed. Return
+ /// CouldNotCompute if an intermediate computation overflows.
+ const SCEV *getBECount(const SCEV *Start,
+ const SCEV *End,
+ const SCEV *Step,
+ bool NoWrap);
+
+ /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
+ /// loop, lazily computing new values if the loop hasn't been analyzed
+ /// yet.
+ const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
+
+ /// ComputeBackedgeTakenCount - Compute the number of times the specified
+ /// loop will iterate.
+ BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L);
+
+ /// ComputeExitLimit - Compute the number of times the backedge of the
+ /// specified loop will execute if it exits via the specified block.
+ ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock);
+
+ /// ComputeExitLimitFromCond - Compute the number of times the backedge of
+ /// the specified loop will execute if its exit condition were a conditional
+ /// branch of ExitCond, TBB, and FBB.
+ ExitLimit ComputeExitLimitFromCond(const Loop *L,
+ Value *ExitCond,
+ BasicBlock *TBB,
+ BasicBlock *FBB);
+
+ /// ComputeExitLimitFromICmp - Compute the number of times the backedge of
+ /// the specified loop will execute if its exit condition were a conditional
+ /// branch of the ICmpInst ExitCond, TBB, and FBB.
+ ExitLimit ComputeExitLimitFromICmp(const Loop *L,
+ ICmpInst *ExitCond,
+ BasicBlock *TBB,
+ BasicBlock *FBB);
+
+ /// ComputeLoadConstantCompareExitLimit - Given an exit condition
+ /// of 'icmp op load X, cst', try to see if we can compute the
+ /// backedge-taken count.
+ ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI,
+ Constant *RHS,
+ const Loop *L,
+ ICmpInst::Predicate p);
+
+ /// ComputeExitCountExhaustively - If the loop is known to execute a
+ /// constant number of times (the condition evolves only from constants),
+ /// try to evaluate a few iterations of the loop until we get the exit
+ /// condition gets a value of ExitWhen (true or false). If we cannot
+ /// evaluate the exit count of the loop, return CouldNotCompute.
+ const SCEV *ComputeExitCountExhaustively(const Loop *L,
+ Value *Cond,
+ bool ExitWhen);
+
+ /// HowFarToZero - Return the number of times an exit condition comparing
+ /// the specified value to zero will execute. If not computable, return
+ /// CouldNotCompute.
+ ExitLimit HowFarToZero(const SCEV *V, const Loop *L);
+
+ /// HowFarToNonZero - Return the number of times an exit condition checking
+ /// the specified value for nonzero will execute. If not computable, return
+ /// CouldNotCompute.
+ ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L);
+
+ /// HowManyLessThans - Return the number of times an exit condition
+ /// containing the specified less-than comparison will execute. If not
+ /// computable, return CouldNotCompute. isSigned specifies whether the
+ /// less-than is signed.
+ ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
+ const Loop *L, bool isSigned);
+
+ /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB
+ /// (which may not be an immediate predecessor) which has exactly one
+ /// successor from which BB is reachable, or null if no such block is
+ /// found.
+ std::pair<BasicBlock *, BasicBlock *>
+ getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
+
+ /// isImpliedCond - Test whether the condition described by Pred, LHS, and
+ /// RHS is true whenever the given FoundCondValue value evaluates to true.
+ bool isImpliedCond(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ Value *FoundCondValue,
+ bool Inverse);
+
+ /// isImpliedCondOperands - Test whether the condition described by Pred,
+ /// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
+ /// and FoundRHS is true.
+ bool isImpliedCondOperands(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const SCEV *FoundLHS, const SCEV *FoundRHS);
+
+ /// isImpliedCondOperandsHelper - Test whether the condition described by
+ /// Pred, LHS, and RHS is true whenever the condition described by Pred,
+ /// FoundLHS, and FoundRHS is true.
+ bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const SCEV *FoundLHS,
+ const SCEV *FoundRHS);
+
+ /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
+ /// in the header of its containing loop, we know the loop executes a
+ /// constant number of times, and the PHI node is just a recurrence
+ /// involving constants, fold it.
+ Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
+ const Loop *L);
+
+ /// isKnownPredicateWithRanges - Test if the given expression is known to
+ /// satisfy the condition described by Pred and the known constant ranges
+ /// of LHS and RHS.
+ ///
+ bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS);
+
+ /// forgetMemoizedResults - Drop memoized information computed for S.
+ void forgetMemoizedResults(const SCEV *S);
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ ScalarEvolution();
+
+ LLVMContext &getContext() const { return F->getContext(); }
+
+ /// isSCEVable - Test if values of the given type are analyzable within
+ /// the SCEV framework. This primarily includes integer types, and it
+ /// can optionally include pointer types if the ScalarEvolution class
+ /// has access to target-specific information.
+ bool isSCEVable(Type *Ty) const;
+
+ /// getTypeSizeInBits - Return the size in bits of the specified type,
+ /// for which isSCEVable must return true.
+ uint64_t getTypeSizeInBits(Type *Ty) const;
+
+ /// getEffectiveSCEVType - Return a type with the same bitwidth as
+ /// the given type and which represents how SCEV will treat the given
+ /// type, for which isSCEVable must return true. For pointer types,
+ /// this is the pointer-sized integer type.
+ Type *getEffectiveSCEVType(Type *Ty) const;
+
+ /// getSCEV - Return a SCEV expression for the full generality of the
+ /// specified expression.
+ const SCEV *getSCEV(Value *V);
+
+ const SCEV *getConstant(ConstantInt *V);
+ const SCEV *getConstant(const APInt& Val);
+ const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
+ const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
+ const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty);
+ const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty);
+ const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
+ const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+ const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SmallVector<const SCEV *, 2> Ops;
+ Ops.push_back(LHS);
+ Ops.push_back(RHS);
+ return getAddExpr(Ops, Flags);
+ }
+ const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SmallVector<const SCEV *, 3> Ops;
+ Ops.push_back(Op0);
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ return getAddExpr(Ops, Flags);
+ }
+ const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+ const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap)
+ {
+ SmallVector<const SCEV *, 2> Ops;
+ Ops.push_back(LHS);
+ Ops.push_back(RHS);
+ return getMulExpr(Ops, Flags);
+ }
+ const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
+ SmallVector<const SCEV *, 3> Ops;
+ Ops.push_back(Op0);
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ return getMulExpr(Ops, Flags);
+ }
+ const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step,
+ const Loop *L, SCEV::NoWrapFlags Flags);
+ const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
+ const Loop *L, SCEV::NoWrapFlags Flags);
+ const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands,
+ const Loop *L, SCEV::NoWrapFlags Flags) {
+ SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
+ return getAddRecExpr(NewOp, L, Flags);
+ }
+ const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
+ const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
+ const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getUnknown(Value *V);
+ const SCEV *getCouldNotCompute();
+
+ /// getSizeOfExpr - Return an expression for sizeof on the given type.
+ ///
+ const SCEV *getSizeOfExpr(Type *AllocTy);
+
+ /// getAlignOfExpr - Return an expression for alignof on the given type.
+ ///
+ const SCEV *getAlignOfExpr(Type *AllocTy);
+
+ /// getOffsetOfExpr - Return an expression for offsetof on the given field.
+ ///
+ const SCEV *getOffsetOfExpr(StructType *STy, unsigned FieldNo);
+
+ /// getOffsetOfExpr - Return an expression for offsetof on the given field.
+ ///
+ const SCEV *getOffsetOfExpr(Type *CTy, Constant *FieldNo);
+
+ /// getNegativeSCEV - Return the SCEV object corresponding to -V.
+ ///
+ const SCEV *getNegativeSCEV(const SCEV *V);
+
+ /// getNotSCEV - Return the SCEV object corresponding to ~V.
+ ///
+ const SCEV *getNotSCEV(const SCEV *V);
+
+ /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
+ const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
+ SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+
+ /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
+ /// of the input value to the specified type. If the type must be
+ /// extended, it is zero extended.
+ const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty);
+
+ /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
+ /// of the input value to the specified type. If the type must be
+ /// extended, it is sign extended.
+ const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty);
+
+ /// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of
+ /// the input value to the specified type. If the type must be extended,
+ /// it is zero extended. The conversion must not be narrowing.
+ const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty);
+
+ /// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of
+ /// the input value to the specified type. If the type must be extended,
+ /// it is sign extended. The conversion must not be narrowing.
+ const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty);
+
+ /// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
+ /// the input value to the specified type. If the type must be extended,
+ /// it is extended with unspecified bits. The conversion must not be
+ /// narrowing.
+ const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty);
+
+ /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
+ /// input value to the specified type. The conversion must not be
+ /// widening.
+ const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty);
+
+ /// getUMaxFromMismatchedTypes - Promote the operands to the wider of
+ /// the types using zero-extension, and then perform a umax operation
+ /// with them.
+ const SCEV *getUMaxFromMismatchedTypes(const SCEV *LHS,
+ const SCEV *RHS);
+
+ /// getUMinFromMismatchedTypes - Promote the operands to the wider of
+ /// the types using zero-extension, and then perform a umin operation
+ /// with them.
+ const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS,
+ const SCEV *RHS);
+
+ /// getPointerBase - Transitively follow the chain of pointer-type operands
+ /// until reaching a SCEV that does not have a single pointer operand. This
+ /// returns a SCEVUnknown pointer for well-formed pointer-type expressions,
+ /// but corner cases do exist.
+ const SCEV *getPointerBase(const SCEV *V);
+
+ /// getSCEVAtScope - Return a SCEV expression for the specified value
+ /// at the specified scope in the program. The L value specifies a loop
+ /// nest to evaluate the expression at, where null is the top-level or a
+ /// specified loop is immediately inside of the loop.
+ ///
+ /// This method can be used to compute the exit value for a variable defined
+ /// in a loop by querying what the value will hold in the parent loop.
+ ///
+ /// In the case that a relevant loop exit value cannot be computed, the
+ /// original value V is returned.
+ const SCEV *getSCEVAtScope(const SCEV *S, const Loop *L);
+
+ /// getSCEVAtScope - This is a convenience function which does
+ /// getSCEVAtScope(getSCEV(V), L).
+ const SCEV *getSCEVAtScope(Value *V, const Loop *L);
+
+ /// isLoopEntryGuardedByCond - Test whether entry to the loop is protected
+ /// by a conditional between LHS and RHS. This is used to help avoid max
+ /// expressions in loop trip counts, and to eliminate casts.
+ bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS);
+
+ /// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is
+ /// protected by a conditional between LHS and RHS. This is used to
+ /// to eliminate casts.
+ bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS);
+
+ /// getSmallConstantTripCount - Returns the maximum trip count of this loop
+ /// as a normal unsigned value. Returns 0 if the trip count is unknown or
+ /// not constant. This "trip count" assumes that control exits via
+ /// ExitingBlock. More precisely, it is the number of times that control may
+ /// reach ExitingBlock before taking the branch. For loops with multiple
+ /// exits, it may not be the number times that the loop header executes if
+ /// the loop exits prematurely via another branch.
+ unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitingBlock);
+
+ /// getSmallConstantTripMultiple - Returns the largest constant divisor of
+ /// the trip count of this loop as a normal unsigned value, if
+ /// possible. This means that the actual trip count is always a multiple of
+ /// the returned value (don't forget the trip count could very well be zero
+ /// as well!). As explained in the comments for getSmallConstantTripCount,
+ /// this assumes that control exits the loop via ExitingBlock.
+ unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitingBlock);
+
+ // getExitCount - Get the expression for the number of loop iterations for
+ // which this loop is guaranteed not to exit via ExitingBlock. Otherwise
+ // return SCEVCouldNotCompute.
+ const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock);
+
+ /// getBackedgeTakenCount - If the specified loop has a predictable
+ /// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute
+ /// object. The backedge-taken count is the number of times the loop header
+ /// will be branched to from within the loop. This is one less than the
+ /// trip count of the loop, since it doesn't count the first iteration,
+ /// when the header is branched to from outside the loop.
+ ///
+ /// Note that it is not valid to call this method on a loop without a
+ /// loop-invariant backedge-taken count (see
+ /// hasLoopInvariantBackedgeTakenCount).
+ ///
+ const SCEV *getBackedgeTakenCount(const Loop *L);
+
+ /// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except
+ /// return the least SCEV value that is known never to be less than the
+ /// actual backedge taken count.
+ const SCEV *getMaxBackedgeTakenCount(const Loop *L);
+
+ /// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop
+ /// has an analyzable loop-invariant backedge-taken count.
+ bool hasLoopInvariantBackedgeTakenCount(const Loop *L);
+
+ /// forgetLoop - This method should be called by the client when it has
+ /// changed a loop in a way that may effect ScalarEvolution's ability to
+ /// compute a trip count, or if the loop is deleted.
+ void forgetLoop(const Loop *L);
+
+ /// forgetValue - This method should be called by the client when it has
+ /// changed a value in a way that may effect its value, or which may
+ /// disconnect it from a def-use chain linking it to a loop.
+ void forgetValue(Value *V);
+
+ /// GetMinTrailingZeros - Determine the minimum number of zero bits that S
+ /// is guaranteed to end in (at every loop iteration). It is, at the same
+ /// time, the minimum number of times S is divisible by 2. For example,
+ /// given {4,+,8} it returns 2. If S is guaranteed to be 0, it returns the
+ /// bitwidth of S.
+ uint32_t GetMinTrailingZeros(const SCEV *S);
+
+ /// getUnsignedRange - Determine the unsigned range for a particular SCEV.
+ ///
+ ConstantRange getUnsignedRange(const SCEV *S);
+
+ /// getSignedRange - Determine the signed range for a particular SCEV.
+ ///
+ ConstantRange getSignedRange(const SCEV *S);
+
+ /// isKnownNegative - Test if the given expression is known to be negative.
+ ///
+ bool isKnownNegative(const SCEV *S);
+
+ /// isKnownPositive - Test if the given expression is known to be positive.
+ ///
+ bool isKnownPositive(const SCEV *S);
+
+ /// isKnownNonNegative - Test if the given expression is known to be
+ /// non-negative.
+ ///
+ bool isKnownNonNegative(const SCEV *S);
+
+ /// isKnownNonPositive - Test if the given expression is known to be
+ /// non-positive.
+ ///
+ bool isKnownNonPositive(const SCEV *S);
+
+ /// isKnownNonZero - Test if the given expression is known to be
+ /// non-zero.
+ ///
+ bool isKnownNonZero(const SCEV *S);
+
+ /// isKnownPredicate - Test if the given expression is known to satisfy
+ /// the condition described by Pred, LHS, and RHS.
+ ///
+ bool isKnownPredicate(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS);
+
+ /// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
+ /// predicate Pred. Return true iff any changes were made. If the
+ /// operands are provably equal or inequal, LHS and RHS are set to
+ /// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
+ ///
+ bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
+ const SCEV *&LHS,
+ const SCEV *&RHS);
+
+ /// getLoopDisposition - Return the "disposition" of the given SCEV with
+ /// respect to the given loop.
+ LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L);
+
+ /// isLoopInvariant - Return true if the value of the given SCEV is
+ /// unchanging in the specified loop.
+ bool isLoopInvariant(const SCEV *S, const Loop *L);
+
+ /// hasComputableLoopEvolution - Return true if the given SCEV changes value
+ /// in a known way in the specified loop. This property being true implies
+ /// that the value is variant in the loop AND that we can emit an expression
+ /// to compute the value of the expression at any particular loop iteration.
+ bool hasComputableLoopEvolution(const SCEV *S, const Loop *L);
+
+ /// getLoopDisposition - Return the "disposition" of the given SCEV with
+ /// respect to the given block.
+ BlockDisposition getBlockDisposition(const SCEV *S, const BasicBlock *BB);
+
+ /// dominates - Return true if elements that makes up the given SCEV
+ /// dominate the specified basic block.
+ bool dominates(const SCEV *S, const BasicBlock *BB);
+
+ /// properlyDominates - Return true if elements that makes up the given SCEV
+ /// properly dominate the specified basic block.
+ bool properlyDominates(const SCEV *S, const BasicBlock *BB);
+
+ /// hasOperand - Test whether the given SCEV has Op as a direct or
+ /// indirect operand.
+ bool hasOperand(const SCEV *S, const SCEV *Op) const;
+
+ virtual bool runOnFunction(Function &F);
+ virtual void releaseMemory();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void print(raw_ostream &OS, const Module* = 0) const;
+
+ private:
+ FoldingSet<SCEV> UniqueSCEVs;
+ BumpPtrAllocator SCEVAllocator;
+
+ /// FirstUnknown - The head of a linked list of all SCEVUnknown
+ /// values that have been allocated. This is used by releaseMemory
+ /// to locate them all and call their destructors.
+ SCEVUnknown *FirstUnknown;
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
new file mode 100644
index 000000000000..c22fc3ab74b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -0,0 +1,265 @@
+//===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- 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 classes used to generate code from scalar expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/ScalarEvolutionNormalization.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/TargetFolder.h"
+#include "llvm/Support/ValueHandle.h"
+#include <set>
+
+namespace llvm {
+ class TargetLowering;
+
+ /// SCEVExpander - This class uses information about analyze scalars to
+ /// rewrite expressions in canonical form.
+ ///
+ /// Clients should create an instance of this class when rewriting is needed,
+ /// and destroy it when finished to allow the release of the associated
+ /// memory.
+ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
+ ScalarEvolution &SE;
+
+ // New instructions receive a name to identifies them with the current pass.
+ const char* IVName;
+
+ std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
+ InsertedExpressions;
+ std::set<AssertingVH<Value> > InsertedValues;
+ std::set<AssertingVH<Value> > InsertedPostIncValues;
+
+ /// RelevantLoops - A memoization of the "relevant" loop for a given SCEV.
+ DenseMap<const SCEV *, const Loop *> RelevantLoops;
+
+ /// PostIncLoops - Addrecs referring to any of the given loops are expanded
+ /// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
+ /// returns the add instruction that adds one to the phi for {0,+,1}<L>,
+ /// as opposed to a new phi starting at 1. This is only supported in
+ /// non-canonical mode.
+ PostIncLoopSet PostIncLoops;
+
+ /// IVIncInsertPos - When this is non-null, addrecs expanded in the
+ /// loop it indicates should be inserted with increments at
+ /// IVIncInsertPos.
+ const Loop *IVIncInsertLoop;
+
+ /// IVIncInsertPos - When expanding addrecs in the IVIncInsertLoop loop,
+ /// insert the IV increment at this position.
+ Instruction *IVIncInsertPos;
+
+ /// Phis that complete an IV chain. Reuse
+ std::set<AssertingVH<PHINode> > ChainedPhis;
+
+ /// CanonicalMode - When true, expressions are expanded in "canonical"
+ /// form. In particular, addrecs are expanded as arithmetic based on
+ /// a canonical induction variable. When false, expression are expanded
+ /// in a more literal form.
+ bool CanonicalMode;
+
+ /// When invoked from LSR, the expander is in "strength reduction" mode. The
+ /// only difference is that phi's are only reused if they are already in
+ /// "expanded" form.
+ bool LSRMode;
+
+ typedef IRBuilder<true, TargetFolder> BuilderType;
+ BuilderType Builder;
+
+#ifndef NDEBUG
+ const char *DebugType;
+#endif
+
+ friend struct SCEVVisitor<SCEVExpander, Value*>;
+
+ public:
+ /// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
+ explicit SCEVExpander(ScalarEvolution &se, const char *name)
+ : SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0),
+ CanonicalMode(true), LSRMode(false),
+ Builder(se.getContext(), TargetFolder(se.TD)) {
+#ifndef NDEBUG
+ DebugType = "";
+#endif
+ }
+
+#ifndef NDEBUG
+ void setDebugType(const char* s) { DebugType = s; }
+#endif
+
+ /// clear - Erase the contents of the InsertedExpressions map so that users
+ /// trying to expand the same expression into multiple BasicBlocks or
+ /// different places within the same BasicBlock can do so.
+ void clear() {
+ InsertedExpressions.clear();
+ InsertedValues.clear();
+ InsertedPostIncValues.clear();
+ ChainedPhis.clear();
+ }
+
+ /// getOrInsertCanonicalInductionVariable - This method returns the
+ /// canonical induction variable of the specified type for the specified
+ /// loop (inserting one if there is none). A canonical induction variable
+ /// starts at zero and steps by one on each iteration.
+ PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
+
+ /// getIVIncOperand - Return the induction variable increment's IV operand.
+ Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
+ bool allowScale);
+
+ /// hoistIVInc - Utility for hoisting an IV increment.
+ bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
+
+ /// replaceCongruentIVs - replace congruent phis with their most canonical
+ /// representative. Return the number of phis eliminated.
+ unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
+ SmallVectorImpl<WeakVH> &DeadInsts,
+ const TargetLowering *TLI = NULL);
+
+ /// expandCodeFor - Insert code to directly compute the specified SCEV
+ /// expression into the program. The inserted code is inserted into the
+ /// specified block.
+ Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
+
+ /// setIVIncInsertPos - Set the current IV increment loop and position.
+ void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
+ assert(!CanonicalMode &&
+ "IV increment positions are not supported in CanonicalMode");
+ IVIncInsertLoop = L;
+ IVIncInsertPos = Pos;
+ }
+
+ /// setPostInc - Enable post-inc expansion for addrecs referring to the
+ /// given loops. Post-inc expansion is only supported in non-canonical
+ /// mode.
+ void setPostInc(const PostIncLoopSet &L) {
+ assert(!CanonicalMode &&
+ "Post-inc expansion is not supported in CanonicalMode");
+ PostIncLoops = L;
+ }
+
+ /// clearPostInc - Disable all post-inc expansion.
+ void clearPostInc() {
+ PostIncLoops.clear();
+
+ // When we change the post-inc loop set, cached expansions may no
+ // longer be valid.
+ InsertedPostIncValues.clear();
+ }
+
+ /// disableCanonicalMode - Disable the behavior of expanding expressions in
+ /// canonical form rather than in a more literal form. Non-canonical mode
+ /// is useful for late optimization passes.
+ void disableCanonicalMode() { CanonicalMode = false; }
+
+ void enableLSRMode() { LSRMode = true; }
+
+ /// clearInsertPoint - Clear the current insertion point. This is useful
+ /// if the instruction that had been serving as the insertion point may
+ /// have been deleted.
+ void clearInsertPoint() {
+ Builder.ClearInsertionPoint();
+ }
+
+ /// isInsertedInstruction - Return true if the specified instruction was
+ /// inserted by the code rewriter. If so, the client should not modify the
+ /// instruction.
+ bool isInsertedInstruction(Instruction *I) const {
+ return InsertedValues.count(I) || InsertedPostIncValues.count(I);
+ }
+
+ void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
+
+ private:
+ LLVMContext &getContext() const { return SE.getContext(); }
+
+ /// InsertBinop - Insert the specified binary operator, doing a small amount
+ /// of work to avoid inserting an obviously redundant operation.
+ Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
+
+ /// ReuseOrCreateCast - Arange for there to be a cast of V to Ty at IP,
+ /// reusing an existing cast if a suitable one exists, moving an existing
+ /// cast if a suitable one exists but isn't in the right place, or
+ /// or creating a new one.
+ Value *ReuseOrCreateCast(Value *V, Type *Ty,
+ Instruction::CastOps Op,
+ BasicBlock::iterator IP);
+
+ /// InsertNoopCastOfTo - Insert a cast of V to the specified type,
+ /// which must be possible with a noop cast, doing what we can to
+ /// share the casts.
+ Value *InsertNoopCastOfTo(Value *V, Type *Ty);
+
+ /// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
+ /// instead of using ptrtoint+arithmetic+inttoptr.
+ Value *expandAddToGEP(const SCEV *const *op_begin,
+ const SCEV *const *op_end,
+ PointerType *PTy, Type *Ty, Value *V);
+
+ Value *expand(const SCEV *S);
+
+ /// expandCodeFor - Insert code to directly compute the specified SCEV
+ /// expression into the program. The inserted code is inserted into the
+ /// SCEVExpander's current insertion point. If a type is specified, the
+ /// result will be expanded to have that type, with a cast if necessary.
+ Value *expandCodeFor(const SCEV *SH, Type *Ty = 0);
+
+ /// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
+ const Loop *getRelevantLoop(const SCEV *);
+
+ Value *visitConstant(const SCEVConstant *S) {
+ return S->getValue();
+ }
+
+ Value *visitTruncateExpr(const SCEVTruncateExpr *S);
+
+ Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S);
+
+ Value *visitSignExtendExpr(const SCEVSignExtendExpr *S);
+
+ Value *visitAddExpr(const SCEVAddExpr *S);
+
+ Value *visitMulExpr(const SCEVMulExpr *S);
+
+ Value *visitUDivExpr(const SCEVUDivExpr *S);
+
+ Value *visitAddRecExpr(const SCEVAddRecExpr *S);
+
+ Value *visitSMaxExpr(const SCEVSMaxExpr *S);
+
+ Value *visitUMaxExpr(const SCEVUMaxExpr *S);
+
+ Value *visitUnknown(const SCEVUnknown *S) {
+ return S->getValue();
+ }
+
+ void rememberInstruction(Value *I);
+
+ void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
+
+ bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
+
+ bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
+
+ Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
+ PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
+ const Loop *L,
+ Type *ExpandTy,
+ Type *IntTy);
+ Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
+ Type *ExpandTy, Type *IntTy, bool useSubtract);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
new file mode 100644
index 000000000000..47b371029186
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -0,0 +1,498 @@
+//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- 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 classes used to represent and build scalar expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
+
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+ class ConstantInt;
+ class ConstantRange;
+ class DominatorTree;
+
+ enum SCEVTypes {
+ // These should be ordered in terms of increasing complexity to make the
+ // folders simpler.
+ scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
+ scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
+ scUnknown, scCouldNotCompute
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVConstant - This class represents a constant integer value.
+ ///
+ class SCEVConstant : public SCEV {
+ friend class ScalarEvolution;
+
+ ConstantInt *V;
+ SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) :
+ SCEV(ID, scConstant), V(v) {}
+ public:
+ ConstantInt *getValue() const { return V; }
+
+ 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;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVCastExpr - This is the base class for unary cast operator classes.
+ ///
+ class SCEVCastExpr : public SCEV {
+ protected:
+ const SCEV *Op;
+ Type *Ty;
+
+ SCEVCastExpr(const FoldingSetNodeIDRef ID,
+ unsigned SCEVTy, const SCEV *op, Type *ty);
+
+ public:
+ const SCEV *getOperand() const { return Op; }
+ 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 ||
+ S->getSCEVType() == scSignExtend;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVTruncateExpr - This class represents a truncation of an integer value
+ /// to a smaller integer value.
+ ///
+ class SCEVTruncateExpr : public SCEVCastExpr {
+ friend class ScalarEvolution;
+
+ SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *op, Type *ty);
+
+ 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;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVZeroExtendExpr - This class represents a zero extension of a small
+ /// integer value to a larger integer value.
+ ///
+ class SCEVZeroExtendExpr : public SCEVCastExpr {
+ friend class ScalarEvolution;
+
+ SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *op, Type *ty);
+
+ 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;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVSignExtendExpr - This class represents a sign extension of a small
+ /// integer value to a larger integer value.
+ ///
+ class SCEVSignExtendExpr : public SCEVCastExpr {
+ friend class ScalarEvolution;
+
+ SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *op, Type *ty);
+
+ 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;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVNAryExpr - This node is a base class providing common
+ /// functionality for n'ary operators.
+ ///
+ class SCEVNAryExpr : public SCEV {
+ protected:
+ // Since SCEVs are immutable, ScalarEvolution allocates operand
+ // arrays with its SCEVAllocator, so this class just needs a simple
+ // pointer rather than a more elaborate vector-like data structure.
+ // This also avoids the need for a non-trivial destructor.
+ const SCEV *const *Operands;
+ size_t NumOperands;
+
+ SCEVNAryExpr(const FoldingSetNodeIDRef ID,
+ enum SCEVTypes T, const SCEV *const *O, size_t N)
+ : SCEV(ID, T), Operands(O), NumOperands(N) {}
+
+ public:
+ size_t getNumOperands() const { return NumOperands; }
+ const SCEV *getOperand(unsigned i) const {
+ assert(i < NumOperands && "Operand index out of range!");
+ return Operands[i];
+ }
+
+ typedef const SCEV *const *op_iterator;
+ op_iterator op_begin() const { return Operands; }
+ op_iterator op_end() const { return Operands + NumOperands; }
+
+ Type *getType() const { return getOperand(0)->getType(); }
+
+ NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
+ return (NoWrapFlags)(SubclassData & Mask);
+ }
+
+ /// 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 ||
+ S->getSCEVType() == scSMaxExpr ||
+ S->getSCEVType() == scUMaxExpr ||
+ S->getSCEVType() == scAddRecExpr;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVCommutativeExpr - This node is the base class for n'ary commutative
+ /// operators.
+ ///
+ class SCEVCommutativeExpr : public SCEVNAryExpr {
+ protected:
+ SCEVCommutativeExpr(const FoldingSetNodeIDRef ID,
+ enum SCEVTypes T, const SCEV *const *O, size_t N)
+ : SCEVNAryExpr(ID, T, O, N) {}
+
+ 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 ||
+ S->getSCEVType() == scSMaxExpr ||
+ S->getSCEVType() == scUMaxExpr;
+ }
+
+ /// Set flags for a non-recurrence without clearing previously set flags.
+ void setNoWrapFlags(NoWrapFlags Flags) {
+ SubclassData |= Flags;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVAddExpr - This node represents an addition of some number of SCEVs.
+ ///
+ class SCEVAddExpr : public SCEVCommutativeExpr {
+ friend class ScalarEvolution;
+
+ SCEVAddExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *const *O, size_t N)
+ : SCEVCommutativeExpr(ID, scAddExpr, O, N) {
+ }
+
+ public:
+ Type *getType() const {
+ // Use the type of the last operand, which is likely to be a pointer
+ // type, if there is one. This doesn't usually matter, but it can help
+ // reduce casts when the expressions are expanded.
+ return getOperand(getNumOperands() - 1)->getType();
+ }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVAddExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scAddExpr;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
+ ///
+ class SCEVMulExpr : public SCEVCommutativeExpr {
+ friend class ScalarEvolution;
+
+ SCEVMulExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *const *O, size_t N)
+ : SCEVCommutativeExpr(ID, scMulExpr, O, N) {
+ }
+
+ 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;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVUDivExpr - This class represents a binary unsigned division operation.
+ ///
+ class SCEVUDivExpr : public SCEV {
+ friend class ScalarEvolution;
+
+ const SCEV *LHS;
+ const SCEV *RHS;
+ SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
+ : SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
+
+ public:
+ const SCEV *getLHS() const { return LHS; }
+ const SCEV *getRHS() const { return RHS; }
+
+ Type *getType() const {
+ // In most cases the types of LHS and RHS will be the same, but in some
+ // crazy cases one or the other may be a pointer. ScalarEvolution doesn't
+ // depend on the type for correctness, but handling types carefully can
+ // avoid extra casts in the SCEVExpander. The LHS is more likely to be
+ // a pointer type than the RHS, so use the RHS' type here.
+ return getRHS()->getType();
+ }
+
+ /// 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;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
+ /// count of the specified loop. This is the primary focus of the
+ /// ScalarEvolution framework; all the other SCEV subclasses are mostly just
+ /// supporting infrastructure to allow SCEVAddRecExpr expressions to be
+ /// created and analyzed.
+ ///
+ /// All operands of an AddRec are required to be loop invariant.
+ ///
+ class SCEVAddRecExpr : public SCEVNAryExpr {
+ friend class ScalarEvolution;
+
+ const Loop *L;
+
+ SCEVAddRecExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *const *O, size_t N, const Loop *l)
+ : SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {}
+
+ public:
+ const SCEV *getStart() const { return Operands[0]; }
+ const Loop *getLoop() const { return L; }
+
+ /// getStepRecurrence - This method constructs and returns the recurrence
+ /// indicating how much this expression steps by. If this is a polynomial
+ /// of degree N, it returns a chrec of degree N-1.
+ /// We cannot determine whether the step recurrence has self-wraparound.
+ const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
+ if (isAffine()) return getOperand(1);
+ return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
+ op_end()),
+ getLoop(), FlagAnyWrap);
+ }
+
+ /// isAffine - Return true if this is an affine AddRec (i.e., it represents
+ /// an expressions A+B*x where A and B are loop invariant values.
+ bool isAffine() const {
+ // We know that the start value is invariant. This expression is thus
+ // affine iff the step is also invariant.
+ return getNumOperands() == 2;
+ }
+
+ /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it
+ /// represents an expressions A+B*x+C*x^2 where A, B and C are loop
+ /// invariant values. This corresponds to an addrec of the form {L,+,M,+,N}
+ bool isQuadratic() const {
+ return getNumOperands() == 3;
+ }
+
+ /// Set flags for a recurrence without clearing any previously set flags.
+ /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
+ /// to make it easier to propagate flags.
+ void setNoWrapFlags(NoWrapFlags Flags) {
+ if (Flags & (FlagNUW | FlagNSW))
+ Flags = ScalarEvolution::setFlags(Flags, FlagNW);
+ SubclassData |= Flags;
+ }
+
+ /// evaluateAtIteration - Return the value of this chain of recurrences at
+ /// the specified iteration number.
+ const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
+
+ /// getNumIterationsInRange - Return the number of iterations of this loop
+ /// that produce values in the specified constant range. Another way of
+ /// looking at this is that it returns the first iteration number where the
+ /// value is not in the condition, thus computing the exit count. If the
+ /// iteration count can't be computed, an instance of SCEVCouldNotCompute is
+ /// returned.
+ const SCEV *getNumIterationsInRange(ConstantRange Range,
+ ScalarEvolution &SE) const;
+
+ /// getPostIncExpr - Return an expression representing the value of
+ /// this expression one iteration of the loop ahead.
+ const SCEVAddRecExpr *getPostIncExpr(ScalarEvolution &SE) const {
+ return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
+ }
+
+ /// 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;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVSMaxExpr - This class represents a signed maximum selection.
+ ///
+ class SCEVSMaxExpr : public SCEVCommutativeExpr {
+ friend class ScalarEvolution;
+
+ SCEVSMaxExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *const *O, size_t N)
+ : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
+ // Max never overflows.
+ setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
+ }
+
+ 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;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVUMaxExpr - This class represents an unsigned maximum selection.
+ ///
+ class SCEVUMaxExpr : public SCEVCommutativeExpr {
+ friend class ScalarEvolution;
+
+ SCEVUMaxExpr(const FoldingSetNodeIDRef ID,
+ const SCEV *const *O, size_t N)
+ : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
+ // Max never overflows.
+ setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
+ }
+
+ 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;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
+ /// value, and only represent it as its LLVM Value. This is the "bottom"
+ /// value for the analysis.
+ ///
+ class SCEVUnknown : public SCEV, private CallbackVH {
+ friend class ScalarEvolution;
+
+ // Implement CallbackVH.
+ virtual void deleted();
+ virtual void allUsesReplacedWith(Value *New);
+
+ /// SE - The parent ScalarEvolution value. This is used to update
+ /// the parent's maps when the value associated with a SCEVUnknown
+ /// is deleted or RAUW'd.
+ ScalarEvolution *SE;
+
+ /// Next - The next pointer in the linked list of all
+ /// SCEVUnknown instances owned by a ScalarEvolution.
+ SCEVUnknown *Next;
+
+ SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V,
+ ScalarEvolution *se, SCEVUnknown *next) :
+ SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {}
+
+ public:
+ Value *getValue() const { return getValPtr(); }
+
+ /// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
+ /// constant representing a type size, alignment, or field offset in
+ /// a target-independent manner, and hasn't happened to have been
+ /// folded with other operations into something unrecognizable. This
+ /// is mainly only useful for pretty-printing and other situations
+ /// where it isn't absolutely required for these to succeed.
+ bool isSizeOf(Type *&AllocTy) const;
+ bool isAlignOf(Type *&AllocTy) const;
+ bool isOffsetOf(Type *&STy, Constant *&FieldNo) const;
+
+ 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;
+ }
+ };
+
+ /// SCEVVisitor - This class defines a simple visitor class that may be used
+ /// for various SCEV analysis purposes.
+ template<typename SC, typename RetVal=void>
+ struct SCEVVisitor {
+ RetVal visit(const SCEV *S) {
+ switch (S->getSCEVType()) {
+ case scConstant:
+ return ((SC*)this)->visitConstant((const SCEVConstant*)S);
+ case scTruncate:
+ return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S);
+ case scZeroExtend:
+ return ((SC*)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr*)S);
+ case scSignExtend:
+ return ((SC*)this)->visitSignExtendExpr((const SCEVSignExtendExpr*)S);
+ case scAddExpr:
+ return ((SC*)this)->visitAddExpr((const SCEVAddExpr*)S);
+ case scMulExpr:
+ return ((SC*)this)->visitMulExpr((const SCEVMulExpr*)S);
+ case scUDivExpr:
+ return ((SC*)this)->visitUDivExpr((const SCEVUDivExpr*)S);
+ case scAddRecExpr:
+ return ((SC*)this)->visitAddRecExpr((const SCEVAddRecExpr*)S);
+ case scSMaxExpr:
+ return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
+ case scUMaxExpr:
+ return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
+ case scUnknown:
+ return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
+ case scCouldNotCompute:
+ return ((SC*)this)->visitCouldNotCompute((const SCEVCouldNotCompute*)S);
+ default:
+ llvm_unreachable("Unknown SCEV type!");
+ }
+ }
+
+ RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
+ llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
+ }
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
new file mode 100644
index 000000000000..342e5937891a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
@@ -0,0 +1,78 @@
+//===- llvm/Analysis/ScalarEvolutionNormalization.h - See below -*- 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 utilities for working with "normalized" ScalarEvolution
+// expressions.
+//
+// The following example illustrates post-increment uses and how normalized
+// expressions help.
+//
+// for (i=0; i!=n; ++i) {
+// ...
+// }
+// use(i);
+//
+// While the expression for most uses of i inside the loop is {0,+,1}<%L>, the
+// expression for the use of i outside the loop is {1,+,1}<%L>, since i is
+// incremented at the end of the loop body. This is inconveient, since it
+// suggests that we need two different induction variables, one that starts
+// at 0 and one that starts at 1. We'd prefer to be able to think of these as
+// the same induction variable, with uses inside the loop using the
+// "pre-incremented" value, and uses after the loop using the
+// "post-incremented" value.
+//
+// Expressions for post-incremented uses are represented as an expression
+// paired with a set of loops for which the expression is in "post-increment"
+// mode (there may be multiple loops).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace llvm {
+
+class Instruction;
+class DominatorTree;
+class Loop;
+class ScalarEvolution;
+class SCEV;
+class Value;
+
+/// TransformKind - Different types of transformations that
+/// TransformForPostIncUse can do.
+enum TransformKind {
+ /// Normalize - Normalize according to the given loops.
+ Normalize,
+ /// NormalizeAutodetect - Detect post-inc opportunities on new expressions,
+ /// update the given loop set, and normalize.
+ NormalizeAutodetect,
+ /// Denormalize - Perform the inverse transform on the expression with the
+ /// given loop set.
+ Denormalize
+};
+
+/// PostIncLoopSet - A set of loops.
+typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
+
+/// TransformForPostIncUse - Transform the given expression according to the
+/// given transformation kind.
+const SCEV *TransformForPostIncUse(TransformKind Kind,
+ const SCEV *S,
+ Instruction *User,
+ Value *OperandValToReplace,
+ PostIncLoopSet &Loops,
+ ScalarEvolution &SE,
+ DominatorTree &DT);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/SparsePropagation.h b/contrib/llvm/include/llvm/Analysis/SparsePropagation.h
new file mode 100644
index 000000000000..c3c2f4b0668c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/SparsePropagation.h
@@ -0,0 +1,206 @@
+//===- SparsePropagation.h - Sparse Conditional Property Propagation ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an abstract sparse conditional propagation algorithm,
+// modeled after SCCP, but with a customizable lattice function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SPARSE_PROPAGATION_H
+#define LLVM_ANALYSIS_SPARSE_PROPAGATION_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
+#include <set>
+
+namespace llvm {
+ class Value;
+ class Constant;
+ class Argument;
+ class Instruction;
+ class PHINode;
+ class TerminatorInst;
+ class BasicBlock;
+ class Function;
+ class SparseSolver;
+ class raw_ostream;
+
+ template<typename T> class SmallVectorImpl;
+
+/// AbstractLatticeFunction - This class is implemented by the dataflow instance
+/// to specify what the lattice values are and how they handle merges etc.
+/// This gives the client the power to compute lattice values from instructions,
+/// constants, etc. The requirement is that lattice values must all fit into
+/// a void*. If a void* is not sufficient, the implementation should use this
+/// pointer to be a pointer into a uniquing set or something.
+///
+class AbstractLatticeFunction {
+public:
+ typedef void *LatticeVal;
+private:
+ LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
+public:
+ AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal,
+ LatticeVal untrackedVal) {
+ UndefVal = undefVal;
+ OverdefinedVal = overdefinedVal;
+ UntrackedVal = untrackedVal;
+ }
+ virtual ~AbstractLatticeFunction();
+
+ LatticeVal getUndefVal() const { return UndefVal; }
+ LatticeVal getOverdefinedVal() const { return OverdefinedVal; }
+ LatticeVal getUntrackedVal() const { return UntrackedVal; }
+
+ /// IsUntrackedValue - If the specified Value is something that is obviously
+ /// uninteresting to the analysis (and would always return UntrackedVal),
+ /// this function can return true to avoid pointless work.
+ virtual bool IsUntrackedValue(Value *V) {
+ return false;
+ }
+
+ /// ComputeConstant - Given a constant value, compute and return a lattice
+ /// value corresponding to the specified constant.
+ virtual LatticeVal ComputeConstant(Constant *C) {
+ return getOverdefinedVal(); // always safe
+ }
+
+ /// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is
+ /// one that the we want to handle through ComputeInstructionState.
+ virtual bool IsSpecialCasedPHI(PHINode *PN) {
+ return false;
+ }
+
+ /// GetConstant - If the specified lattice value is representable as an LLVM
+ /// constant value, return it. Otherwise return null. The returned value
+ /// must be in the same LLVM type as Val.
+ virtual Constant *GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS) {
+ return 0;
+ }
+
+ /// ComputeArgument - Given a formal argument value, compute and return a
+ /// lattice value corresponding to the specified argument.
+ virtual LatticeVal ComputeArgument(Argument *I) {
+ return getOverdefinedVal(); // always safe
+ }
+
+ /// MergeValues - Compute and return the merge of the two specified lattice
+ /// values. Merging should only move one direction down the lattice to
+ /// guarantee convergence (toward overdefined).
+ virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) {
+ return getOverdefinedVal(); // always safe, never useful.
+ }
+
+ /// ComputeInstructionState - Given an instruction and a vector of its operand
+ /// values, compute the result value of the instruction.
+ virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) {
+ return getOverdefinedVal(); // always safe, never useful.
+ }
+
+ /// PrintValue - Render the specified lattice value to the specified stream.
+ virtual void PrintValue(LatticeVal V, raw_ostream &OS);
+};
+
+
+/// SparseSolver - This class is a general purpose solver for Sparse Conditional
+/// Propagation with a programmable lattice function.
+///
+class SparseSolver {
+ typedef AbstractLatticeFunction::LatticeVal LatticeVal;
+
+ /// LatticeFunc - This is the object that knows the lattice and how to do
+ /// compute transfer functions.
+ AbstractLatticeFunction *LatticeFunc;
+
+ DenseMap<Value*, LatticeVal> ValueState; // The state each value is in.
+ SmallPtrSet<BasicBlock*, 16> BBExecutable; // The bbs that are executable.
+
+ std::vector<Instruction*> InstWorkList; // Worklist of insts to process.
+
+ std::vector<BasicBlock*> BBWorkList; // The BasicBlock work list
+
+ /// KnownFeasibleEdges - Entries in this set are edges which have already had
+ /// 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
+public:
+ explicit SparseSolver(AbstractLatticeFunction *Lattice)
+ : LatticeFunc(Lattice) {}
+ ~SparseSolver() {
+ delete LatticeFunc;
+ }
+
+ /// Solve - Solve for constants and executable blocks.
+ ///
+ void Solve(Function &F);
+
+ void Print(Function &F, raw_ostream &OS) const;
+
+ /// getLatticeState - Return the LatticeVal object that corresponds to the
+ /// value. If an value is not in the map, it is returned as untracked,
+ /// unlike the getOrInitValueState method.
+ LatticeVal getLatticeState(Value *V) const {
+ DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V);
+ return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal();
+ }
+
+ /// getOrInitValueState - Return the LatticeVal object that corresponds to the
+ /// value, initializing the value's state if it hasn't been entered into the
+ /// map yet. This function is necessary because not all values should start
+ /// out in the underdefined state... Arguments should be overdefined, and
+ /// constants should be marked as constants.
+ ///
+ LatticeVal getOrInitValueState(Value *V);
+
+ /// isEdgeFeasible - Return true if the control flow edge from the 'From'
+ /// basic block to the 'To' basic block is currently feasible. If
+ /// AggressiveUndef is true, then this treats values with unknown lattice
+ /// values as undefined. This is generally only useful when solving the
+ /// lattice, not when querying it.
+ bool isEdgeFeasible(BasicBlock *From, BasicBlock *To,
+ bool AggressiveUndef = false);
+
+ /// isBlockExecutable - Return true if there are any known feasible
+ /// edges into the basic block. This is generally only useful when
+ /// querying the lattice.
+ bool isBlockExecutable(BasicBlock *BB) const {
+ return BBExecutable.count(BB);
+ }
+
+private:
+ /// UpdateState - When the state for some instruction is potentially updated,
+ /// this function notices and adds I to the worklist if needed.
+ void UpdateState(Instruction &Inst, LatticeVal V);
+
+ /// MarkBlockExecutable - This method can be used by clients to mark all of
+ /// the blocks that are known to be intrinsically live in the processed unit.
+ void MarkBlockExecutable(BasicBlock *BB);
+
+ /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
+ /// work list if it is not already executable.
+ void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
+
+ /// getFeasibleSuccessors - Return a vector of booleans to indicate which
+ /// successors are reachable from a given terminator instruction.
+ void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs,
+ bool AggressiveUndef);
+
+ void visitInst(Instruction &I);
+ void visitPHINode(PHINode &I);
+ void visitTerminatorInst(TerminatorInst &TI);
+
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_SPARSE_PROPAGATION_H
diff --git a/contrib/llvm/include/llvm/Analysis/Trace.h b/contrib/llvm/include/llvm/Analysis/Trace.h
new file mode 100644
index 000000000000..99651e192d3b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Trace.h
@@ -0,0 +1,119 @@
+//===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents a single trace of LLVM basic blocks. A trace is a
+// single entry, multiple exit, region of code that is often hot. Trace-based
+// optimizations treat traces almost like they are a large, strange, basic
+// block: because the trace path is assumed to be hot, optimizations for the
+// fall-through path are made at the expense of the non-fall-through paths.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_TRACE_H
+#define LLVM_ANALYSIS_TRACE_H
+
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class BasicBlock;
+ class Function;
+ class Module;
+ class raw_ostream;
+
+class Trace {
+ typedef std::vector<BasicBlock *> BasicBlockListType;
+ BasicBlockListType BasicBlocks;
+
+public:
+ /// Trace ctor - Make a new trace from a vector of basic blocks,
+ /// residing in the function which is the parent of the first
+ /// basic block in the vector.
+ ///
+ Trace(const std::vector<BasicBlock *> &vBB) : BasicBlocks (vBB) {}
+
+ /// getEntryBasicBlock - Return the entry basic block (first block)
+ /// of the trace.
+ ///
+ BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; }
+
+ /// operator[]/getBlock - Return basic block N in the trace.
+ ///
+ BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; }
+ BasicBlock *getBlock(unsigned i) const { return BasicBlocks[i]; }
+
+ /// getFunction - Return this trace's parent function.
+ ///
+ Function *getFunction () const;
+
+ /// getModule - Return this Module that contains this trace's parent
+ /// function.
+ ///
+ Module *getModule () const;
+
+ /// getBlockIndex - Return the index of the specified basic block in the
+ /// trace, or -1 if it is not in the trace.
+ int getBlockIndex(const BasicBlock *X) const {
+ for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+ if (BasicBlocks[i] == X)
+ return i;
+ return -1;
+ }
+
+ /// contains - Returns true if this trace contains the given basic
+ /// block.
+ ///
+ bool contains(const BasicBlock *X) const {
+ return getBlockIndex(X) != -1;
+ }
+
+ /// Returns true if B1 occurs before B2 in the trace, or if it is the same
+ /// block as B2.. Both blocks must be in the trace.
+ ///
+ bool dominates(const BasicBlock *B1, const BasicBlock *B2) const {
+ int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2);
+ assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!");
+ return B1Idx <= B2Idx;
+ }
+
+ // BasicBlock iterators...
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
+ const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
+ reverse_iterator rend () { return BasicBlocks.rend(); }
+ const_reverse_iterator rend () const { return BasicBlocks.rend(); }
+
+ unsigned size() const { return BasicBlocks.size(); }
+ bool empty() const { return BasicBlocks.empty(); }
+
+ iterator erase(iterator q) { return BasicBlocks.erase (q); }
+ iterator erase(iterator q1, iterator q2) { return BasicBlocks.erase (q1, q2); }
+
+ /// print - Write trace to output stream.
+ ///
+ void print(raw_ostream &O) const;
+
+ /// dump - Debugger convenience method; writes trace to standard error
+ /// output stream.
+ ///
+ void dump() const;
+};
+
+} // end namespace llvm
+
+#endif // TRACE_H
diff --git a/contrib/llvm/include/llvm/Analysis/ValueTracking.h b/contrib/llvm/include/llvm/Analysis/ValueTracking.h
new file mode 100644
index 000000000000..f2f9db4ce4e8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/ValueTracking.h
@@ -0,0 +1,181 @@
+//===- llvm/Analysis/ValueTracking.h - Walk computations --------*- 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 routines that help analyze properties that chains of
+// computations have.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_VALUETRACKING_H
+#define LLVM_ANALYSIS_VALUETRACKING_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class Value;
+ class Instruction;
+ class APInt;
+ class TargetData;
+ class StringRef;
+ class MDNode;
+
+ /// ComputeMaskedBits - Determine which of the bits specified in Mask are
+ /// known to be either zero or one and return them in the KnownZero/KnownOne
+ /// bit sets. This code only analyzes bits in Mask, in order to short-circuit
+ /// processing.
+ ///
+ /// This function is defined on values with integer type, values with pointer
+ /// type (but only if TD is non-null), and vectors of integers. In the case
+ /// where V is a vector, the mask, known zero, and known one values are the
+ /// 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);
+ 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);
+
+ /// 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);
+
+ /// 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);
+
+ /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
+ /// this predicate to simplify operations downstream. Mask is known to be
+ /// zero for bits that V cannot have.
+ ///
+ /// This function is defined on values with integer type, values with pointer
+ /// type (but only if TD is non-null), and vectors of integers. In the case
+ /// where V is a vector, the mask, known zero, and known one values are the
+ /// 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);
+
+
+ /// ComputeNumSignBits - Return the number of times the sign bit of the
+ /// register is replicated into the other bits. We know that at least 1 bit
+ /// is always equal to the sign bit (itself), but other cases can give us
+ /// information. For example, immediately after an "ashr X, 2", we know that
+ /// the top 3 bits are all equal to each other, so we return 3.
+ ///
+ /// 'Op' must have a scalar integer type.
+ ///
+ unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0,
+ unsigned Depth = 0);
+
+ /// ComputeMultiple - This function computes the integer multiple of Base that
+ /// equals V. If successful, it returns true and returns the multiple in
+ /// Multiple. If unsuccessful, it returns false. Also, if V can be
+ /// simplified to an integer, then the simplified V is returned in Val. Look
+ /// through sext only if LookThroughSExt=true.
+ bool ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
+ bool LookThroughSExt = false,
+ unsigned Depth = 0);
+
+ /// CannotBeNegativeZero - Return true if we can prove that the specified FP
+ /// value is never equal to -0.0.
+ ///
+ bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
+
+ /// isBytewiseValue - If the specified value can be set by repeating the same
+ /// byte in memory, return the i8 value that it is represented with. This is
+ /// true for all i8 values obviously, but is also true for i32 0, i32 -1,
+ /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated
+ /// byte store (e.g. i16 0x1234), return null.
+ Value *isBytewiseValue(Value *V);
+
+ /// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
+ /// the scalar value indexed is already around as a register, for example if
+ /// it were inserted directly into the aggregrate.
+ ///
+ /// If InsertBefore is not null, this function will duplicate (modified)
+ /// insertvalues when a part of a nested struct is extracted.
+ Value *FindInsertedValue(Value *V,
+ ArrayRef<unsigned> idx_range,
+ Instruction *InsertBefore = 0);
+
+ /// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if
+ /// 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);
+ static inline const Value *
+ GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
+ const TargetData &TD) {
+ return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
+ }
+
+ /// getConstantStringInfo - This function computes the length of a
+ /// null-terminated C string pointed to by V. If successful, it returns true
+ /// and returns the string in Str. If unsuccessful, it returns false. This
+ /// does not include the trailing nul character by default. If TrimAtNul is
+ /// set to false, then this returns any trailing nul characters as well as any
+ /// other characters that come after it.
+ bool getConstantStringInfo(const Value *V, StringRef &Str,
+ uint64_t Offset = 0, bool TrimAtNul = true);
+
+ /// GetStringLength - If we can compute the length of the string pointed to by
+ /// the specified pointer, return 'len+1'. If we can't, return 0.
+ uint64_t GetStringLength(Value *V);
+
+ /// GetUnderlyingObject - This method strips off any GEP address adjustments
+ /// and pointer casts from the specified value, returning the original object
+ /// 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,
+ unsigned MaxLookup = 6);
+ static inline const Value *
+ GetUnderlyingObject(const Value *V, const TargetData *TD = 0,
+ unsigned MaxLookup = 6) {
+ return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
+ }
+
+ /// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
+ /// are lifetime markers.
+ bool onlyUsedByLifetimeMarkers(const Value *V);
+
+ /// isSafeToSpeculativelyExecute - Return true if the instruction does not
+ /// have any effects besides calculating the result and does not have
+ /// undefined behavior.
+ ///
+ /// This method never returns true for an instruction that returns true for
+ /// mayHaveSideEffects; however, this method also does some other checks in
+ /// addition. It checks for undefined behavior, like dividing by zero or
+ /// loading from an invalid pointer (but not for undefined results, like a
+ /// shift with a shift amount larger than the width of the result). It checks
+ /// for malloc and alloca because speculatively executing them might cause a
+ /// memory leak. It also returns false for instructions related to control
+ /// flow, specifically terminators and PHI nodes.
+ ///
+ /// This method only looks at the instruction itself and its operands, so if
+ /// this method returns true, it is safe to move the instruction as long as
+ /// the correct dominance relationships for the operands and users hold.
+ /// 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);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Analysis/Verifier.h b/contrib/llvm/include/llvm/Analysis/Verifier.h
new file mode 100644
index 000000000000..ce8aeef07645
--- /dev/null
+++ b/contrib/llvm/include/llvm/Analysis/Verifier.h
@@ -0,0 +1,75 @@
+//===-- llvm/Analysis/Verifier.h - LLVM IR Verifier -------------*- 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 function verifier interface, that can be used for some
+// sanity checking of input to the system, and for checking that transformations
+// haven't done something bad.
+//
+// Note that this does not provide full 'java style' security and verifications,
+// instead it just tries to ensure that code is well formed.
+//
+// To see what specifically is checked, look at the top of Verifier.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_VERIFIER_H
+#define LLVM_ANALYSIS_VERIFIER_H
+
+#include <string>
+
+namespace llvm {
+
+class FunctionPass;
+class Module;
+class Function;
+
+/// @brief An enumeration to specify the action to be taken if errors found.
+///
+/// This enumeration is used in the functions below to indicate what should
+/// happen if the verifier finds errors. Each of the functions that uses
+/// this enumeration as an argument provides a default value for it. The
+/// actions are listed below.
+enum VerifierFailureAction {
+ AbortProcessAction, ///< verifyModule will print to stderr and abort()
+ PrintMessageAction, ///< verifyModule will print to stderr and return true
+ ReturnStatusAction ///< verifyModule will just return true
+};
+
+/// @brief Create a verifier pass.
+///
+/// Check a module or function for validity. When the pass is used, the
+/// action indicated by the \p action argument will be used if errors are
+/// found.
+FunctionPass *createVerifierPass(
+ VerifierFailureAction action = AbortProcessAction ///< Action to take
+);
+
+/// @brief Check a module for errors.
+///
+/// If there are no errors, the function returns false. If an error is found,
+/// the action taken depends on the \p action parameter.
+/// This should only be used for debugging, because it plays games with
+/// PassManagers and stuff.
+
+bool verifyModule(
+ const Module &M, ///< The module to be verified
+ VerifierFailureAction action = AbortProcessAction, ///< Action to take
+ std::string *ErrorInfo = 0 ///< Information about failures.
+);
+
+// verifyFunction - Check a function for errors, useful for use when debugging a
+// pass.
+bool verifyFunction(
+ const Function &F, ///< The function to be verified
+ VerifierFailureAction action = AbortProcessAction ///< Action to take
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Argument.h b/contrib/llvm/include/llvm/Argument.h
new file mode 100644
index 000000000000..e66075c1f235
--- /dev/null
+++ b/contrib/llvm/include/llvm/Argument.h
@@ -0,0 +1,92 @@
+//===-- llvm/Argument.h - Definition of the Argument class ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Argument class.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+/// A class to represent an incoming formal argument to a Function. An argument
+/// is a very simple Value. It is essentially a named (optional) type. When used
+/// in the body of a function, it represents the value of the actual argument
+/// the function was called with.
+/// @brief LLVM Argument representation
+class Argument : public Value, public ilist_node<Argument> {
+ virtual void anchor();
+ Function *Parent;
+
+ friend class SymbolTableListTraits<Argument, Function>;
+ void setParent(Function *parent);
+
+public:
+ /// Argument ctor - If Function argument is specified, this argument is
+ /// inserted at the end of the argument list for the function.
+ ///
+ explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0);
+
+ inline const Function *getParent() const { return Parent; }
+ inline Function *getParent() { return Parent; }
+
+ /// getArgNo - Return the index of this formal argument in its containing
+ /// function. For example in "void foo(int a, float b)" a is 0 and b is 1.
+ unsigned getArgNo() const;
+
+ /// hasByValAttr - Return true if this argument has the byval attribute on it
+ /// in its containing function.
+ bool hasByValAttr() const;
+
+ /// getParamAlignment - If this is a byval argument, return its alignment.
+ unsigned getParamAlignment() const;
+
+ /// hasNestAttr - Return true if this argument has the nest attribute on
+ /// it in its containing function.
+ bool hasNestAttr() const;
+
+ /// hasNoAliasAttr - Return true if this argument has the noalias attribute on
+ /// it in its containing function.
+ bool hasNoAliasAttr() const;
+
+ /// hasNoCaptureAttr - Return true if this argument has the nocapture
+ /// 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.
+ bool hasStructRetAttr() const;
+
+ /// addAttr - Add a Attribute to an argument
+ void addAttr(Attributes);
+
+ /// removeAttr - Remove a Attribute from an argument
+ void removeAttr(Attributes);
+
+ /// 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;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Assembly/AssemblyAnnotationWriter.h b/contrib/llvm/include/llvm/Assembly/AssemblyAnnotationWriter.h
new file mode 100644
index 000000000000..37b47c31e8c7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Assembly/AssemblyAnnotationWriter.h
@@ -0,0 +1,63 @@
+//===-- AssemblyAnnotationWriter.h - Annotation .ll files -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Clients of the assembly writer can use this interface to add their own
+// special-purpose annotations to LLVM assembly language printouts. Note that
+// the assembly parser won't be able to parse these, in general, so
+// implementations are advised to print stuff as LLVM comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_ASMANNOTATIONWRITER_H
+#define LLVM_ASSEMBLY_ASMANNOTATIONWRITER_H
+
+namespace llvm {
+
+class Function;
+class BasicBlock;
+class Instruction;
+class Value;
+class formatted_raw_ostream;
+
+class AssemblyAnnotationWriter {
+public:
+
+ virtual ~AssemblyAnnotationWriter();
+
+ /// emitFunctionAnnot - This may be implemented to emit a string right before
+ /// the start of a function.
+ virtual void emitFunctionAnnot(const Function *,
+ formatted_raw_ostream &) {}
+
+ /// emitBasicBlockStartAnnot - This may be implemented to emit a string right
+ /// after the basic block label, but before the first instruction in the
+ /// block.
+ virtual void emitBasicBlockStartAnnot(const BasicBlock *,
+ formatted_raw_ostream &) {
+ }
+
+ /// emitBasicBlockEndAnnot - This may be implemented to emit a string right
+ /// after the basic block.
+ virtual void emitBasicBlockEndAnnot(const BasicBlock *,
+ formatted_raw_ostream &) {
+ }
+
+ /// emitInstructionAnnot - This may be implemented to emit a string right
+ /// before an instruction is emitted.
+ virtual void emitInstructionAnnot(const Instruction *,
+ formatted_raw_ostream &) {}
+
+ /// printInfoComment - This may be implemented to emit a comment to the
+ /// right of an instruction or global value.
+ virtual void printInfoComment(const Value &, formatted_raw_ostream &) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Assembly/Parser.h b/contrib/llvm/include/llvm/Assembly/Parser.h
new file mode 100644
index 000000000000..b971c531ae05
--- /dev/null
+++ b/contrib/llvm/include/llvm/Assembly/Parser.h
@@ -0,0 +1,64 @@
+//===-- llvm/Assembly/Parser.h - Parser for VM assembly files ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes are implemented by the lib/AsmParser library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_PARSER_H
+#define LLVM_ASSEMBLY_PARSER_H
+
+#include <string>
+
+namespace llvm {
+
+class Module;
+class MemoryBuffer;
+class SMDiagnostic;
+class LLVMContext;
+
+/// This function is the main interface to the LLVM Assembly Parser. It parses
+/// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
+/// Module (intermediate representation) with the corresponding features. Note
+/// that this does not verify that the generated Module is valid, so you should
+/// run the verifier after parsing the file to check that it is okay.
+/// @brief Parse LLVM Assembly from a file
+Module *ParseAssemblyFile(
+ const std::string &Filename, ///< The name of the file to parse
+ SMDiagnostic &Error, ///< Error result info.
+ LLVMContext &Context ///< Context in which to allocate globals info.
+);
+
+/// The function is a secondary interface to the LLVM Assembly Parser. It parses
+/// an ASCII string that (presumably) contains LLVM Assembly code. It returns a
+/// Module (intermediate representation) with the corresponding features. Note
+/// that this does not verify that the generated Module is valid, so you should
+/// run the verifier after parsing the file to check that it is okay.
+/// @brief Parse LLVM Assembly from a string
+Module *ParseAssemblyString(
+ const char *AsmString, ///< The string containing assembly
+ Module *M, ///< A module to add the assembly too.
+ SMDiagnostic &Error, ///< Error result info.
+ LLVMContext &Context
+);
+
+/// This function is the low-level interface to the LLVM Assembly Parser.
+/// ParseAssemblyFile and ParseAssemblyString are wrappers around this function.
+/// @brief Parse LLVM Assembly from a MemoryBuffer. This function *always*
+/// takes ownership of the MemoryBuffer.
+Module *ParseAssembly(
+ MemoryBuffer *F, ///< The MemoryBuffer containing assembly
+ Module *M, ///< A module to add the assembly too.
+ SMDiagnostic &Err, ///< Error result info.
+ LLVMContext &Context
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Assembly/PrintModulePass.h b/contrib/llvm/include/llvm/Assembly/PrintModulePass.h
new file mode 100644
index 000000000000..239fbcc0c8ca
--- /dev/null
+++ b/contrib/llvm/include/llvm/Assembly/PrintModulePass.h
@@ -0,0 +1,42 @@
+//===- llvm/Assembly/PrintModulePass.h - Printing Pass ----------*- 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 two passes to print out a module. The PrintModulePass pass
+// simply prints out the entire module when it is executed. The
+// PrintFunctionPass class is designed to be pipelined with other
+// FunctionPass's, and prints out the functions of the module as they are
+// processed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_PRINTMODULEPASS_H
+#define LLVM_ASSEMBLY_PRINTMODULEPASS_H
+
+#include <string>
+
+namespace llvm {
+ class FunctionPass;
+ class ModulePass;
+ class raw_ostream;
+
+ /// createPrintModulePass - Create and return a pass that writes the
+ /// module to the specified raw_ostream.
+ ModulePass *createPrintModulePass(raw_ostream *OS,
+ bool DeleteStream=false,
+ const std::string &Banner = "");
+
+ /// createPrintFunctionPass - Create and return a pass that prints
+ /// functions to the specified raw_ostream as they are processed.
+ FunctionPass *createPrintFunctionPass(const std::string &Banner,
+ raw_ostream *OS,
+ bool DeleteStream=false);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Assembly/Writer.h b/contrib/llvm/include/llvm/Assembly/Writer.h
new file mode 100644
index 000000000000..6b89ae022da3
--- /dev/null
+++ b/contrib/llvm/include/llvm/Assembly/Writer.h
@@ -0,0 +1,37 @@
+//===-- llvm/Assembly/Writer.h - Printer for LLVM assembly files --*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This functionality is implemented by lib/VMCore/AsmWriter.cpp.
+// This library is used to print LLVM assembly language files to an iostream. It
+// can print LLVM code at a variety of granularities, including Modules,
+// BasicBlocks, and Instructions. This makes it useful for debugging.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_WRITER_H
+#define LLVM_ASSEMBLY_WRITER_H
+
+namespace llvm {
+
+class Module;
+class Value;
+class raw_ostream;
+
+// WriteAsOperand - Write the name of the specified value out to the specified
+// ostream. This can be useful when you just want to print int %reg126, not the
+// whole instruction that generated it. If you specify a Module for context,
+// then even constants get pretty-printed; for example, the type of a null
+// pointer is printed symbolically.
+//
+void WriteAsOperand(raw_ostream &, const Value *, bool PrintTy = true,
+ const Module *Context = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Attributes.h b/contrib/llvm/include/llvm/Attributes.h
new file mode 100644
index 000000000000..0099f173b626
--- /dev/null
+++ b/contrib/llvm/include/llvm/Attributes.h
@@ -0,0 +1,377 @@
+//===-- 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 <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) { }
+ Attributes(const Attributes &Attrs) : Bits(Attrs.Bits) { }
+ // This is a "safe bool() operator".
+ operator const void *() const { return Bits ? this : 0; }
+ bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
+ Attributes &operator = (const Attributes &Attrs) {
+ Bits = Attrs.Bits;
+ return *this;
+ }
+ 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[4] = {
+ {ByVal_i | InReg_i | Nest_i | StructRet_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);
+}
+
+
+/// 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 parameter in it.
+ static AttrListPtr get(const AttributeWithIndex *Attr, unsigned NumAttrs);
+
+ /// get - Return a Attribute list with the parameters specified by the
+ /// consecutive random access iterator range.
+ template <typename Iter>
+ static AttrListPtr get(const Iter &I, const Iter &E) {
+ if (I == E) return AttrListPtr(); // Empty list.
+ return get(&*I, static_cast<unsigned>(E-I));
+ }
+
+ /// 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/contrib/llvm/include/llvm/AutoUpgrade.h b/contrib/llvm/include/llvm/AutoUpgrade.h
new file mode 100644
index 000000000000..e13c4c12b0f4
--- /dev/null
+++ b/contrib/llvm/include/llvm/AutoUpgrade.h
@@ -0,0 +1,44 @@
+//===-- llvm/AutoUpgrade.h - AutoUpgrade Helpers ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These functions are implemented by lib/VMCore/AutoUpgrade.cpp.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_AUTOUPGRADE_H
+#define LLVM_AUTOUPGRADE_H
+
+namespace llvm {
+ class Module;
+ class GlobalVariable;
+ class Function;
+ class CallInst;
+
+ /// This is a more granular function that simply checks an intrinsic function
+ /// for upgrading, and returns true if it requires upgrading. It may return
+ /// null in NewFn if the all calls to the original intrinsic function
+ /// should be transformed to non-function-call instructions.
+ bool UpgradeIntrinsicFunction(Function *F, Function *&NewFn);
+
+ /// This is the complement to the above, replacing a specific call to an
+ /// intrinsic function with a call to the specified new function.
+ void UpgradeIntrinsicCall(CallInst *CI, Function *NewFn);
+
+ /// This is an auto-upgrade hook for any old intrinsic function syntaxes
+ /// which need to have both the function updated as well as all calls updated
+ /// to the new function. This should only be run in a post-processing fashion
+ /// so that it can update all calls to the old function.
+ void UpgradeCallsToIntrinsic(Function* F);
+
+ /// This checks for global variables which should be upgraded. It returns true
+ /// if it requires upgrading.
+ bool UpgradeGlobalVariable(GlobalVariable *GV);
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/BasicBlock.h b/contrib/llvm/include/llvm/BasicBlock.h
new file mode 100644
index 000000000000..d2aa1673d921
--- /dev/null
+++ b/contrib/llvm/include/llvm/BasicBlock.h
@@ -0,0 +1,291 @@
+//===-- llvm/BasicBlock.h - Represent a basic block in the VM ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the BasicBlock class.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/DataTypes.h"
+
+namespace llvm {
+
+class LandingPadInst;
+class TerminatorInst;
+class LLVMContext;
+class BlockAddress;
+
+template<> struct ilist_traits<Instruction>
+ : public SymbolTableListTraits<Instruction, BasicBlock> {
+ // createSentinel is used to get hold of a node that marks the end of
+ // the list...
+ // The sentinel is relative to this instance, so we use a non-static
+ // method.
+ Instruction *createSentinel() const {
+ // since i(p)lists always publicly derive from the corresponding
+ // traits, placing a data member in this class will augment i(p)list.
+ // But since the NodeTy is expected to publicly derive from
+ // ilist_node<NodeTy>, there is a legal viable downcast from it
+ // to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
+ // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
+ // forbidden (save the ilist_node<NodeTy>) so no one will ever notice
+ // the superposition.
+ return static_cast<Instruction*>(&Sentinel);
+ }
+ static void destroySentinel(Instruction*) {}
+
+ Instruction *provideInitialHead() const { return createSentinel(); }
+ Instruction *ensureHead(Instruction*) const { return createSentinel(); }
+ static void noteHead(Instruction*, Instruction*) {}
+private:
+ mutable ilist_half_node<Instruction> Sentinel;
+};
+
+/// This represents a single basic block in LLVM. A basic block is simply a
+/// container of instructions that execute sequentially. Basic blocks are Values
+/// because they are referenced by instructions such as branches and switch
+/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block
+/// represents a label to which a branch can jump.
+///
+/// A well formed basic block is formed of a list of non-terminating
+/// instructions followed by a single TerminatorInst instruction.
+/// TerminatorInst's may not occur in the middle of basic blocks, and must
+/// terminate the blocks. The BasicBlock class allows malformed basic blocks to
+/// occur because it may be useful in the intermediate stage of constructing or
+/// modifying a program. However, the verifier will ensure that basic blocks
+/// are "well formed".
+/// @brief LLVM Basic Block Representation
+class BasicBlock : public Value, // Basic blocks are data objects also
+ public ilist_node<BasicBlock> {
+ friend class BlockAddress;
+public:
+ typedef iplist<Instruction> InstListType;
+private:
+ InstListType InstList;
+ Function *Parent;
+
+ void setParent(Function *parent);
+ friend class SymbolTableListTraits<BasicBlock, Function>;
+
+ BasicBlock(const BasicBlock &); // Do not implement
+ void operator=(const BasicBlock &); // Do not implement
+
+ /// BasicBlock ctor - If the function parameter is specified, the basic block
+ /// is automatically inserted at either the end of the function (if
+ /// InsertBefore is null), or before the specified basic block.
+ ///
+ explicit BasicBlock(LLVMContext &C, const Twine &Name = "",
+ Function *Parent = 0, BasicBlock *InsertBefore = 0);
+public:
+ /// getContext - Get the context in which this basic block lives.
+ LLVMContext &getContext() const;
+
+ /// Instruction iterators...
+ typedef InstListType::iterator iterator;
+ typedef InstListType::const_iterator const_iterator;
+
+ /// Create - Creates a new BasicBlock. If the Parent parameter is specified,
+ /// the basic block is automatically inserted at either the end of the
+ /// function (if InsertBefore is 0), or before the specified basic block.
+ static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
+ Function *Parent = 0,BasicBlock *InsertBefore = 0) {
+ return new BasicBlock(Context, Name, Parent, InsertBefore);
+ }
+ ~BasicBlock();
+
+ /// getParent - Return the enclosing method, or null if none
+ ///
+ const Function *getParent() const { return Parent; }
+ Function *getParent() { return Parent; }
+
+ /// getTerminator() - If this is a well formed basic block, then this returns
+ /// a pointer to the terminator instruction. If it is not, then you get a
+ /// null pointer back.
+ ///
+ TerminatorInst *getTerminator();
+ const TerminatorInst *getTerminator() const;
+
+ /// Returns a pointer to the first instructon in this block that is not a
+ /// PHINode instruction. When adding instruction to the beginning of the
+ /// basic block, they should be added before the returned value, not before
+ /// the first instruction, which might be PHI.
+ /// Returns 0 is there's no non-PHI instruction.
+ Instruction* getFirstNonPHI();
+ const Instruction* getFirstNonPHI() const {
+ return const_cast<BasicBlock*>(this)->getFirstNonPHI();
+ }
+
+ // Same as above, but also skip debug intrinsics.
+ Instruction* getFirstNonPHIOrDbg();
+ const Instruction* getFirstNonPHIOrDbg() const {
+ return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
+ }
+
+ // Same as above, but also skip lifetime intrinsics.
+ Instruction* getFirstNonPHIOrDbgOrLifetime();
+ const Instruction* getFirstNonPHIOrDbgOrLifetime() const {
+ return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
+ }
+
+ /// getFirstInsertionPt - Returns an iterator to the first instruction in this
+ /// block that is suitable for inserting a non-PHI instruction. In particular,
+ /// it skips all PHIs and LandingPad instructions.
+ iterator getFirstInsertionPt();
+ const_iterator getFirstInsertionPt() const {
+ return const_cast<BasicBlock*>(this)->getFirstInsertionPt();
+ }
+
+ /// removeFromParent - This method unlinks 'this' from the containing
+ /// function, but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing function
+ /// and deletes it.
+ ///
+ void eraseFromParent();
+
+ /// moveBefore - Unlink this basic block from its current function and
+ /// insert it into the function that MovePos lives in, right before MovePos.
+ void moveBefore(BasicBlock *MovePos);
+
+ /// moveAfter - Unlink this basic block from its current function and
+ /// insert it into the function that MovePos lives in, right after MovePos.
+ void moveAfter(BasicBlock *MovePos);
+
+
+ /// getSinglePredecessor - If this basic block has a single predecessor block,
+ /// return the block, otherwise return a null pointer.
+ BasicBlock *getSinglePredecessor();
+ const BasicBlock *getSinglePredecessor() const {
+ return const_cast<BasicBlock*>(this)->getSinglePredecessor();
+ }
+
+ /// getUniquePredecessor - If this basic block has a unique predecessor block,
+ /// return the block, otherwise return a null pointer.
+ /// Note that unique predecessor doesn't mean single edge, there can be
+ /// multiple edges from the unique predecessor to this block (for example
+ /// a switch statement with multiple cases having the same destination).
+ BasicBlock *getUniquePredecessor();
+ const BasicBlock *getUniquePredecessor() const {
+ return const_cast<BasicBlock*>(this)->getUniquePredecessor();
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// Instruction iterator methods
+ ///
+ inline iterator begin() { return InstList.begin(); }
+ inline const_iterator begin() const { return InstList.begin(); }
+ inline iterator end () { return InstList.end(); }
+ inline const_iterator end () const { return InstList.end(); }
+
+ inline size_t size() const { return InstList.size(); }
+ inline bool empty() const { return InstList.empty(); }
+ inline const Instruction &front() const { return InstList.front(); }
+ inline Instruction &front() { return InstList.front(); }
+ inline const Instruction &back() const { return InstList.back(); }
+ inline Instruction &back() { return InstList.back(); }
+
+ /// getInstList() - Return the underlying instruction list container. You
+ /// need to access it directly if you want to modify it currently.
+ ///
+ const InstListType &getInstList() const { return InstList; }
+ InstListType &getInstList() { return InstList; }
+
+ /// getSublistAccess() - returns pointer to member of instruction list
+ static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) {
+ return &BasicBlock::InstList;
+ }
+
+ /// getValueSymbolTable() - returns pointer to symbol table (if any)
+ 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;
+ }
+
+ /// dropAllReferences() - This function causes all the subinstructions to "let
+ /// go" of all references that they are maintaining. This allows one to
+ /// 'delete' a whole class at a time, even though there may be circular
+ /// references... first all references are dropped, and all use counts go to
+ /// zero. Then everything is delete'd for real. Note that no operations are
+ /// valid on an object that has "dropped all references", except operator
+ /// delete.
+ ///
+ void dropAllReferences();
+
+ /// removePredecessor - This method is used to notify a BasicBlock that the
+ /// specified Predecessor of the block is no longer able to reach it. This is
+ /// actually not used to update the Predecessor list, but is actually used to
+ /// update the PHI nodes that reside in the block. Note that this should be
+ /// called while the predecessor still refers to this block.
+ ///
+ void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false);
+
+ /// splitBasicBlock - This splits a basic block into two at the specified
+ /// instruction. Note that all instructions BEFORE the specified iterator
+ /// stay as part of the original basic block, an unconditional branch is added
+ /// to the original BB, and the rest of the instructions in the BB are moved
+ /// to the new BB, including the old terminator. The newly formed BasicBlock
+ /// is returned. This function invalidates the specified iterator.
+ ///
+ /// Note that this only works on well formed basic blocks (must have a
+ /// terminator), and 'I' must not be the end of instruction list (which would
+ /// cause a degenerate basic block to be formed, having a terminator inside of
+ /// the basic block).
+ ///
+ /// Also note that this doesn't preserve any passes. To split blocks while
+ /// keeping loop information consistent, use the SplitBlock utility function.
+ ///
+ BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "");
+
+ /// hasAddressTaken - returns true if there are any uses of this basic block
+ /// other than direct branches, switches, etc. to it.
+ bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
+
+ /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors
+ /// to refer to basic block New instead of to us.
+ void replaceSuccessorsPhiUsesWith(BasicBlock *New);
+
+ /// isLandingPad - Return true if this basic block is a landing pad. I.e.,
+ /// it's the destination of the 'unwind' edge of an invoke instruction.
+ bool isLandingPad() const;
+
+ /// getLandingPadInst() - Return the landingpad instruction associated with
+ /// the landing pad.
+ LandingPadInst *getLandingPadInst();
+ const LandingPadInst *getLandingPadInst() const;
+
+private:
+ /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
+ /// objects using it. This is almost always 0, sometimes one, possibly but
+ /// almost never 2, and inconceivably 3 or more.
+ void AdjustBlockAddressRefCount(int Amt) {
+ setValueSubclassData(getSubclassDataFromValue()+Amt);
+ assert((int)(signed char)getSubclassDataFromValue() >= 0 &&
+ "Refcount wrap-around");
+ }
+ // Shadow Value::setValueSubclassData with a private forwarding method so that
+ // any future subclasses cannot accidentally use it.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Bitcode/Archive.h b/contrib/llvm/include/llvm/Bitcode/Archive.h
new file mode 100644
index 000000000000..86c44c7f150b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Bitcode/Archive.h
@@ -0,0 +1,546 @@
+//===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the Archive and ArchiveMember classes that provide
+// manipulation of LLVM Archive files. The implementation is provided by the
+// lib/Bitcode/Archive library. This library is used to read and write
+// archive (*.a) files that contain LLVM bitcode files (or others).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_ARCHIVE_H
+#define LLVM_BITCODE_ARCHIVE_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/Path.h"
+#include <map>
+#include <set>
+
+namespace llvm {
+ class MemoryBuffer;
+
+// Forward declare classes
+class Module; // From VMCore
+class Archive; // Declared below
+class ArchiveMemberHeader; // Internal implementation class
+class LLVMContext; // Global data
+
+/// This class is the main class manipulated by users of the Archive class. It
+/// holds information about one member of the Archive. It is also the element
+/// stored by the Archive's ilist, the Archive's main abstraction. Because of
+/// the special requirements of archive files, users are not permitted to
+/// construct ArchiveMember instances. You should obtain them from the methods
+/// of the Archive class instead.
+/// @brief This class represents a single archive member.
+class ArchiveMember : public ilist_node<ArchiveMember> {
+ /// @name Types
+ /// @{
+ public:
+ /// These flags are used internally by the archive member to specify various
+ /// characteristics of the member. The various "is" methods below provide
+ /// access to the flags. The flags are not user settable.
+ enum Flags {
+ CompressedFlag = 1, ///< Member is a normal compressed file
+ SVR4SymbolTableFlag = 2, ///< Member is a SVR4 symbol table
+ BSD4SymbolTableFlag = 4, ///< Member is a BSD4 symbol table
+ LLVMSymbolTableFlag = 8, ///< Member is an LLVM symbol table
+ BitcodeFlag = 16, ///< Member is bitcode
+ HasPathFlag = 64, ///< Member has a full or partial path
+ HasLongFilenameFlag = 128, ///< Member uses the long filename syntax
+ StringTableFlag = 256 ///< Member is an ar(1) format string table
+ };
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// @returns the parent Archive instance
+ /// @brief Get the archive associated with this member
+ Archive* getArchive() const { return parent; }
+
+ /// @returns the path to the Archive's file
+ /// @brief Get the path to the archive member
+ const sys::Path& getPath() const { return path; }
+
+ /// The "user" is the owner of the file per Unix security. This may not
+ /// have any applicability on non-Unix systems but is a required component
+ /// of the "ar" file format.
+ /// @brief Get the user associated with this archive member.
+ unsigned getUser() const { return info.getUser(); }
+
+ /// The "group" is the owning group of the file per Unix security. This
+ /// may not have any applicability on non-Unix systems but is a required
+ /// component of the "ar" file format.
+ /// @brief Get the group associated with this archive member.
+ unsigned getGroup() const { return info.getGroup(); }
+
+ /// The "mode" specifies the access permissions for the file per Unix
+ /// security. This may not have any applicability on non-Unix systems but is
+ /// a required component of the "ar" file format.
+ /// @brief Get the permission mode associated with this archive member.
+ unsigned getMode() const { return info.getMode(); }
+
+ /// This method returns the time at which the archive member was last
+ /// modified when it was not in the archive.
+ /// @brief Get the time of last modification of the archive member.
+ sys::TimeValue getModTime() const { return info.getTimestamp(); }
+
+ /// @returns the size of the archive member in bytes.
+ /// @brief Get the size of the archive member.
+ uint64_t getSize() const { return info.getSize(); }
+
+ /// This method returns the total size of the archive member as it
+ /// appears on disk. This includes the file content, the header, the
+ /// long file name if any, and the padding.
+ /// @brief Get total on-disk member size.
+ unsigned getMemberSize() const;
+
+ /// This method will return a pointer to the in-memory content of the
+ /// archive member, if it is available. If the data has not been loaded
+ /// into memory, the return value will be null.
+ /// @returns a pointer to the member's data.
+ /// @brief Get the data content of the archive member
+ const char* getData() const { return data; }
+
+ /// This method determines if the member is a regular compressed file.
+ /// @returns true iff the archive member is a compressed regular file.
+ /// @brief Determine if the member is a compressed regular file.
+ bool isCompressed() const { return flags&CompressedFlag; }
+
+ /// @returns true iff the member is a SVR4 (non-LLVM) symbol table
+ /// @brief Determine if this member is a SVR4 symbol table.
+ bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
+
+ /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
+ /// @brief Determine if this member is a BSD4.4 symbol table.
+ bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
+
+ /// @returns true iff the archive member is the LLVM symbol table
+ /// @brief Determine if this member is the LLVM symbol table.
+ bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; }
+
+ /// @returns true iff the archive member is the ar(1) string table
+ /// @brief Determine if this member is the ar(1) string table.
+ bool isStringTable() const { return flags&StringTableFlag; }
+
+ /// @returns true iff the archive member is a bitcode file.
+ /// @brief Determine if this member is a bitcode file.
+ bool isBitcode() const { return flags&BitcodeFlag; }
+
+ /// @returns true iff the file name contains a path (directory) component.
+ /// @brief Determine if the member has a path
+ bool hasPath() const { return flags&HasPathFlag; }
+
+ /// Long filenames are an artifact of the ar(1) file format which allows
+ /// up to sixteen characters in its header and doesn't allow a path
+ /// separator character (/). To avoid this, a "long format" member name is
+ /// allowed that doesn't have this restriction. This method determines if
+ /// that "long format" is used for this member.
+ /// @returns true iff the file name uses the long form
+ /// @brief Determine if the member has a long file name
+ bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
+
+ /// This method returns the status info (like Unix stat(2)) for the archive
+ /// member. The status info provides the file's size, permissions, and
+ /// modification time. The contents of the Path::StatusInfo structure, other
+ /// than the size and modification time, may not have utility on non-Unix
+ /// systems.
+ /// @returns the status info for the archive member
+ /// @brief Obtain the status info for the archive member
+ const sys::FileStatus &getFileStatus() const { return info; }
+
+ /// This method causes the archive member to be replaced with the contents
+ /// of the file specified by \p File. The contents of \p this will be
+ /// updated to reflect the new data from \p File. The \p File must exist and
+ /// be readable on entry to this method.
+ /// @returns true if an error occurred, false otherwise
+ /// @brief Replace contents of archive member with a new file.
+ bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ Archive* parent; ///< Pointer to parent archive
+ sys::PathWithStatus path; ///< Path of file containing the member
+ sys::FileStatus info; ///< Status info (size,mode,date)
+ unsigned flags; ///< Flags about the archive member
+ const char* data; ///< Data for the member
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// The default constructor is only used by the Archive's iplist when it
+ /// constructs the list's sentry node.
+ ArchiveMember();
+
+ private:
+ /// Used internally by the Archive class to construct an ArchiveMember.
+ /// The contents of the ArchiveMember are filled out by the Archive class.
+ explicit ArchiveMember(Archive *PAR);
+
+ // So Archive can construct an ArchiveMember
+ friend class llvm::Archive;
+ /// @}
+};
+
+/// This class defines the interface to LLVM Archive files. The Archive class
+/// presents the archive file as an ilist of ArchiveMember objects. The members
+/// can be rearranged in any fashion either by directly editing the ilist or by
+/// using editing methods on the Archive class (recommended). The Archive
+/// class also provides several ways of accessing the archive file for various
+/// purposes such as editing and linking. Full symbol table support is provided
+/// for loading only those files that resolve symbols. Note that read
+/// performance of this library is _crucial_ for performance of JIT type
+/// applications and the linkers. Consequently, the implementation of the class
+/// is optimized for reading.
+class Archive {
+
+ /// @name Types
+ /// @{
+ public:
+ /// This is the ilist type over which users may iterate to examine
+ /// the contents of the archive
+ /// @brief The ilist type of ArchiveMembers that Archive contains.
+ typedef iplist<ArchiveMember> MembersList;
+
+ /// @brief Forward mutable iterator over ArchiveMember
+ typedef MembersList::iterator iterator;
+
+ /// @brief Forward immutable iterator over ArchiveMember
+ typedef MembersList::const_iterator const_iterator;
+
+ /// @brief Reverse mutable iterator over ArchiveMember
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ /// @brief Reverse immutable iterator over ArchiveMember
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ /// @brief The in-memory version of the symbol table
+ typedef std::map<std::string,unsigned> SymTabType;
+
+ /// @}
+ /// @name ilist accessor methods
+ /// @{
+ public:
+ inline iterator begin() { return members.begin(); }
+ inline const_iterator begin() const { return members.begin(); }
+ inline iterator end () { return members.end(); }
+ inline const_iterator end () const { return members.end(); }
+
+ inline reverse_iterator rbegin() { return members.rbegin(); }
+ inline const_reverse_iterator rbegin() const { return members.rbegin(); }
+ inline reverse_iterator rend () { return members.rend(); }
+ inline const_reverse_iterator rend () const { return members.rend(); }
+
+ inline size_t size() const { return members.size(); }
+ inline bool empty() const { return members.empty(); }
+ inline const ArchiveMember& front() const { return members.front(); }
+ inline ArchiveMember& front() { return members.front(); }
+ inline const ArchiveMember& back() const { return members.back(); }
+ inline ArchiveMember& back() { return members.back(); }
+
+ /// @}
+ /// @name ilist mutator methods
+ /// @{
+ public:
+ /// This method splices a \p src member from an archive (possibly \p this),
+ /// to a position just before the member given by \p dest in \p this. When
+ /// the archive is written, \p src will be written in its new location.
+ /// @brief Move a member to a new location
+ inline void splice(iterator dest, Archive& arch, iterator src)
+ { return members.splice(dest,arch.members,src); }
+
+ /// This method erases a \p target member from the archive. When the
+ /// archive is written, it will no longer contain \p target. The associated
+ /// ArchiveMember is deleted.
+ /// @brief Erase a member.
+ inline iterator erase(iterator target) { return members.erase(target); }
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Create an empty archive file and associate it with the \p Filename. This
+ /// method does not actually create the archive disk file. It creates an
+ /// empty Archive object. If the writeToDisk method is called, the archive
+ /// file \p Filename will be created at that point, with whatever content
+ /// the returned Archive object has at that time.
+ /// @returns An Archive* that represents the new archive file.
+ /// @brief Create an empty Archive.
+ static Archive* CreateEmpty(
+ const sys::Path& Filename,///< Name of the archive to (eventually) create.
+ LLVMContext& C ///< Context to use for global information
+ );
+
+ /// Open an existing archive and load its contents in preparation for
+ /// editing. After this call, the member ilist is completely populated based
+ /// on the contents of the archive file. You should use this form of open if
+ /// you intend to modify the archive or traverse its contents (e.g. for
+ /// printing).
+ /// @brief Open and load an archive file
+ static Archive* OpenAndLoad(
+ const sys::Path& filePath, ///< The file path to open and load
+ LLVMContext& C, ///< The context to use for global information
+ std::string* ErrorMessage ///< An optional error string
+ );
+
+ /// This method opens an existing archive file from \p Filename and reads in
+ /// its symbol table without reading in any of the archive's members. This
+ /// reduces both I/O and cpu time in opening the archive if it is to be used
+ /// solely for symbol lookup (e.g. during linking). The \p Filename must
+ /// exist and be an archive file or an error will be returned. This form
+ /// of opening the archive is intended for read-only operations that need to
+ /// locate members via the symbol table for link editing. Since the archve
+ /// members are not read by this method, the archive will appear empty upon
+ /// return. If editing operations are performed on the archive, they will
+ /// completely replace the contents of the archive! It is recommended that
+ /// if this form of opening the archive is used that only the symbol table
+ /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
+ /// findModulesDefiningSymbols) be used.
+ /// @returns an Archive* that represents the archive file, or null on error.
+ /// @brief Open an existing archive and load its symbols.
+ static Archive* OpenAndLoadSymbols(
+ const sys::Path& Filename, ///< Name of the archive file to open
+ LLVMContext& C, ///< The context to use for global info
+ std::string* ErrorMessage=0 ///< An optional error string
+ );
+
+ /// This destructor cleans up the Archive object, releases all memory, and
+ /// closes files. It does nothing with the archive file on disk. If you
+ /// haven't used the writeToDisk method by the time the destructor is
+ /// called, all changes to the archive will be lost.
+ /// @brief Destruct in-memory archive
+ ~Archive();
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// @returns the path to the archive file.
+ /// @brief Get the archive path.
+ const sys::Path& getPath() { return archPath; }
+
+ /// This method is provided so that editing methods can be invoked directly
+ /// on the Archive's iplist of ArchiveMember. However, it is recommended
+ /// that the usual STL style iterator interface be used instead.
+ /// @returns the iplist of ArchiveMember
+ /// @brief Get the iplist of the members
+ MembersList& getMembers() { return members; }
+
+ /// This method allows direct query of the Archive's symbol table. The
+ /// symbol table is a std::map of std::string (the symbol) to unsigned (the
+ /// file offset). Note that for efficiency reasons, the offset stored in
+ /// the symbol table is not the actual offset. It is the offset from the
+ /// beginning of the first "real" file member (after the symbol table). Use
+ /// the getFirstFileOffset() to obtain that offset and add this value to the
+ /// offset in the symbol table to obtain the real file offset. Note that
+ /// there is purposefully no interface provided by Archive to look up
+ /// members by their offset. Use the findModulesDefiningSymbols and
+ /// findModuleDefiningSymbol methods instead.
+ /// @returns the Archive's symbol table.
+ /// @brief Get the archive's symbol table
+ const SymTabType& getSymbolTable() { return symTab; }
+
+ /// This method returns the offset in the archive file to the first "real"
+ /// file member. Archive files, on disk, have a signature and might have a
+ /// symbol table that precedes the first actual file member. This method
+ /// allows you to determine what the size of those fields are.
+ /// @returns the offset to the first "real" file member in the archive.
+ /// @brief Get the offset to the first "real" file member in the archive.
+ unsigned getFirstFileOffset() { return firstFileOffset; }
+
+ /// This method will scan the archive for bitcode modules, interpret them
+ /// and return a vector of the instantiated modules in \p Modules. If an
+ /// error occurs, this method will return true. If \p ErrMessage is not null
+ /// and an error occurs, \p *ErrMessage will be set to a string explaining
+ /// the error that occurred.
+ /// @returns true if an error occurred
+ /// @brief Instantiate all the bitcode modules located in the archive
+ bool getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage);
+
+ /// This accessor looks up the \p symbol in the archive's symbol table and
+ /// returns the associated module that defines that symbol. This method can
+ /// be called as many times as necessary. This is handy for linking the
+ /// archive into another module based on unresolved symbols. Note that the
+ /// Module returned by this accessor should not be deleted by the caller. It
+ /// is managed internally by the Archive class. It is possible that multiple
+ /// calls to this accessor will return the same Module instance because the
+ /// associated module defines multiple symbols.
+ /// @returns The Module* found or null if the archive does not contain a
+ /// module that defines the \p symbol.
+ /// @brief Look up a module by symbol name.
+ Module* findModuleDefiningSymbol(
+ const std::string& symbol, ///< Symbol to be sought
+ std::string* ErrMessage ///< Error message storage, if non-zero
+ );
+
+ /// This method is similar to findModuleDefiningSymbol but allows lookup of
+ /// more than one symbol at a time. If \p symbols contains a list of
+ /// undefined symbols in some module, then calling this method is like
+ /// making one complete pass through the archive to resolve symbols but is
+ /// more efficient than looking at the individual members. Note that on
+ /// exit, the symbols resolved by this method will be removed from \p
+ /// symbols to ensure they are not re-searched on a subsequent call. If
+ /// you need to retain the list of symbols, make a copy.
+ /// @brief Look up multiple symbols in the archive.
+ bool findModulesDefiningSymbols(
+ std::set<std::string>& symbols, ///< Symbols to be sought
+ SmallVectorImpl<Module*>& modules, ///< The modules matching \p symbols
+ std::string* ErrMessage ///< Error msg storage, if non-zero
+ );
+
+ /// This method determines whether the archive is a properly formed llvm
+ /// bitcode archive. It first makes sure the symbol table has been loaded
+ /// and has a non-zero size. If it does, then it is an archive. If not,
+ /// then it tries to load all the bitcode modules of the archive. Finally,
+ /// it returns whether it was successful.
+ /// @returns true if the archive is a proper llvm bitcode archive
+ /// @brief Determine whether the archive is a proper llvm bitcode archive.
+ bool isBitcodeArchive();
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// This method is the only way to get the archive written to disk. It
+ /// creates or overwrites the file specified when \p this was created
+ /// or opened. The arguments provide options for writing the archive. If
+ /// \p CreateSymbolTable is true, the archive is scanned for bitcode files
+ /// and a symbol table of the externally visible function and global
+ /// variable names is created. If \p TruncateNames is true, the names of the
+ /// archive members will have their path component stripped and the file
+ /// name will be truncated at 15 characters. If \p Compress is specified,
+ /// all archive members will be compressed before being written. If
+ /// \p PrintSymTab is true, the symbol table will be printed to std::cout.
+ /// @returns true if an error occurred, \p error set to error message
+ /// @returns false if the writing succeeded.
+ /// @brief Write (possibly modified) archive contents to disk
+ bool writeToDisk(
+ bool CreateSymbolTable=false, ///< Create Symbol table
+ bool TruncateNames=false, ///< Truncate the filename to 15 chars
+ bool Compress=false, ///< Compress files
+ std::string* ErrMessage=0 ///< If non-null, where error msg is set
+ );
+
+ /// This method adds a new file to the archive. The \p filename is examined
+ /// to determine just enough information to create an ArchiveMember object
+ /// which is then inserted into the Archive object's ilist at the location
+ /// given by \p where.
+ /// @returns true if an error occurred, false otherwise
+ /// @brief Add a file to the archive.
+ bool addFileBefore(
+ const sys::Path& filename, ///< The file to be added
+ iterator where, ///< Insertion point
+ std::string* ErrMsg ///< Optional error message location
+ );
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ protected:
+ /// @brief Construct an Archive for \p filename and optionally map it
+ /// into memory.
+ explicit Archive(const sys::Path& filename, LLVMContext& C);
+
+ /// @param data The symbol table data to be parsed
+ /// @param len The length of the symbol table data
+ /// @param error Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Parse the symbol table at \p data.
+ bool parseSymbolTable(const void* data,unsigned len,std::string* error);
+
+ /// @returns A fully populated ArchiveMember or 0 if an error occurred.
+ /// @brief Parse the header of a member starting at \p At
+ ArchiveMember* parseMemberHeader(
+ const char*&At, ///< The pointer to the location we're parsing
+ const char*End, ///< The pointer to the end of the archive
+ std::string* error ///< Optional error message catcher
+ );
+
+ /// @param ErrMessage Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Check that the archive signature is correct
+ bool checkSignature(std::string* ErrMessage);
+
+ /// @param ErrMessage Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Load the entire archive.
+ bool loadArchive(std::string* ErrMessage);
+
+ /// @param ErrMessage Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Load just the symbol table.
+ bool loadSymbolTable(std::string* ErrMessage);
+
+ /// @brief Write the symbol table to an ofstream.
+ void writeSymbolTable(std::ofstream& ARFile);
+
+ /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
+ /// false, otherwise true. If an error occurs and error is non-null then
+ /// it will be set to an error message.
+ /// @returns false Writing member succeeded
+ /// @returns true Writing member failed, \p error set to error message
+ bool writeMember(
+ const ArchiveMember& member, ///< The member to be written
+ std::ofstream& ARFile, ///< The file to write member onto
+ bool CreateSymbolTable, ///< Should symbol table be created?
+ bool TruncateNames, ///< Should names be truncated to 11 chars?
+ bool ShouldCompress, ///< Should the member be compressed?
+ std::string* ErrMessage ///< If non-null, place were error msg is set
+ );
+
+ /// @brief Fill in an ArchiveMemberHeader from ArchiveMember.
+ bool fillHeader(const ArchiveMember&mbr,
+ ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
+
+ /// @brief Maps archive into memory
+ bool mapToMemory(std::string* ErrMsg);
+
+ /// @brief Frees all the members and unmaps the archive file.
+ void cleanUpMemory();
+
+ /// This type is used to keep track of bitcode modules loaded from the
+ /// symbol table. It maps the file offset to a pair that consists of the
+ /// associated ArchiveMember and the Module.
+ /// @brief Module mapping type
+ typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> >
+ ModuleMap;
+
+
+ /// @}
+ /// @name Data
+ /// @{
+ protected:
+ sys::Path archPath; ///< Path to the archive file we read/write
+ MembersList members; ///< The ilist of ArchiveMember
+ MemoryBuffer *mapfile; ///< Raw Archive contents mapped into memory
+ const char* base; ///< Base of the memory mapped file data
+ SymTabType symTab; ///< The symbol table
+ std::string strtab; ///< The string table for long file names
+ unsigned symTabSize; ///< Size in bytes of symbol table
+ unsigned firstFileOffset; ///< Offset to first normal file.
+ ModuleMap modules; ///< The modules loaded via symbol lookup.
+ ArchiveMember* foreignST; ///< This holds the foreign symbol table.
+ LLVMContext& Context; ///< This holds global data.
+ /// @}
+ /// @name Hidden
+ /// @{
+ private:
+ Archive(); ///< Do not implement
+ Archive(const Archive&); ///< Do not implement
+ Archive& operator=(const Archive&); ///< Do not implement
+ /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Bitcode/BitCodes.h b/contrib/llvm/include/llvm/Bitcode/BitCodes.h
new file mode 100644
index 000000000000..28e1ab1c8711
--- /dev/null
+++ b/contrib/llvm/include/llvm/Bitcode/BitCodes.h
@@ -0,0 +1,186 @@
+//===- BitCodes.h - Enum values for the bitcode format ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header Bitcode enum values.
+//
+// The enum values defined in this file should be considered permanent. If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODES_H
+#define LLVM_BITCODE_BITCODES_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+namespace bitc {
+ enum StandardWidths {
+ 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.
+ };
+
+ // The standard abbrev namespace always has a way to exit a block, enter a
+ // nested block, define abbrevs, and define an unabbreviated record.
+ enum FixedAbbrevIDs {
+ END_BLOCK = 0, // Must be zero to guarantee termination for broken bitcode.
+ ENTER_SUBBLOCK = 1,
+
+ /// DEFINE_ABBREV - Defines an abbrev for the current block. It consists
+ /// of a vbr5 for # operand infos. Each operand info is emitted with a
+ /// single bit to indicate if it is a literal encoding. If so, the value is
+ /// emitted with a vbr8. If not, the encoding is emitted as 3 bits followed
+ /// by the info value as a vbr5 if needed.
+ DEFINE_ABBREV = 2,
+
+ // UNABBREV_RECORDs are emitted with a vbr6 for the record code, followed by
+ // a vbr6 for the # operands, followed by vbr6's for each operand.
+ UNABBREV_RECORD = 3,
+
+ // This is not a code, this is a marker for the first abbrev assignment.
+ FIRST_APPLICATION_ABBREV = 4
+ };
+
+ /// StandardBlockIDs - All bitcode files can optionally include a BLOCKINFO
+ /// block, which contains metadata about other blocks in the file.
+ enum StandardBlockIDs {
+ /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example,
+ /// standard abbrevs that should be available to all blocks of a specified
+ /// ID.
+ BLOCKINFO_BLOCK_ID = 0,
+
+ // Block IDs 1-7 are reserved for future expansion.
+ FIRST_APPLICATION_BLOCKID = 8
+ };
+
+ /// BlockInfoCodes - The blockinfo block contains metadata about user-defined
+ /// blocks.
+ 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]
+ };
+
+} // End bitc namespace
+
+/// BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
+/// This is actually a union of two different things:
+/// 1. It could be a literal integer value ("the operand is always 17").
+/// 2. It could be an encoding specification ("this operand encoded like so").
+///
+class BitCodeAbbrevOp {
+ uint64_t Val; // A literal value or data for an encoding.
+ bool IsLiteral : 1; // Indicate whether this is a literal value or not.
+ unsigned Enc : 3; // The encoding to use.
+public:
+ enum Encoding {
+ Fixed = 1, // A fixed width field, Val specifies number of bits.
+ VBR = 2, // A VBR field where Val specifies the width of each chunk.
+ Array = 3, // A sequence of fields, next field species elt encoding.
+ Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._].
+ Blob = 5 // 32-bit aligned array of 8-bit characters.
+ };
+
+ explicit BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {}
+ explicit BitCodeAbbrevOp(Encoding E, uint64_t Data = 0)
+ : Val(Data), IsLiteral(false), Enc(E) {}
+
+ bool isLiteral() const { return IsLiteral; }
+ bool isEncoding() const { return !IsLiteral; }
+
+ // Accessors for literals.
+ uint64_t getLiteralValue() const { assert(isLiteral()); return Val; }
+
+ // Accessors for encoding info.
+ Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc; }
+ uint64_t getEncodingData() const {
+ assert(isEncoding() && hasEncodingData());
+ return Val;
+ }
+
+ bool hasEncodingData() const { return hasEncodingData(getEncoding()); }
+ static bool hasEncodingData(Encoding E) {
+ switch (E) {
+ case Fixed:
+ case VBR:
+ return true;
+ case Array:
+ case Char6:
+ case Blob:
+ return false;
+ }
+ llvm_unreachable("Invalid encoding");
+ }
+
+ /// isChar6 - Return true if this character is legal in the Char6 encoding.
+ static bool isChar6(char C) {
+ if (C >= 'a' && C <= 'z') return true;
+ if (C >= 'A' && C <= 'Z') return true;
+ if (C >= '0' && C <= '9') return true;
+ if (C == '.' || C == '_') return true;
+ return false;
+ }
+ static unsigned EncodeChar6(char C) {
+ 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;
+ 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+26+10) return V-26-26+'0';
+ if (V == 62) return '.';
+ if (V == 63) return '_';
+ llvm_unreachable("Not a value Char6 character!");
+ }
+
+};
+
+template <> struct isPodLike<BitCodeAbbrevOp> { static const bool value=true; };
+
+/// BitCodeAbbrev - This class represents an abbreviation record. An
+/// abbreviation allows a complex record that has redundancy to be stored in a
+/// specialized format instead of the fully-general, fully-vbr, format.
+class BitCodeAbbrev {
+ SmallVector<BitCodeAbbrevOp, 32> OperandList;
+ unsigned char RefCount; // Number of things using this.
+ ~BitCodeAbbrev() {}
+public:
+ BitCodeAbbrev() : RefCount(1) {}
+
+ void addRef() { ++RefCount; }
+ void dropRef() { if (--RefCount == 0) delete this; }
+
+ unsigned getNumOperandInfos() const {
+ return static_cast<unsigned>(OperandList.size());
+ }
+ const BitCodeAbbrevOp &getOperandInfo(unsigned N) const {
+ return OperandList[N];
+ }
+
+ void Add(const BitCodeAbbrevOp &OpInfo) {
+ OperandList.push_back(OpInfo);
+ }
+};
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h b/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h
new file mode 100644
index 000000000000..65868294403c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Bitcode/BitstreamReader.h
@@ -0,0 +1,668 @@
+//===- BitstreamReader.h - Low-level bitstream reader 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 defines the BitstreamReader class. This class can be used to
+// read an arbitrary bitstream, regardless of its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BITSTREAM_READER_H
+#define BITSTREAM_READER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/StreamableMemoryObject.h"
+#include <climits>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+ class Deserializer;
+
+class BitstreamReader {
+public:
+ /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
+ /// These describe abbreviations that all blocks of the specified ID inherit.
+ struct BlockInfo {
+ 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
+public:
+ BitstreamReader() : IgnoreBlockInfoNames(true) {
+ }
+
+ BitstreamReader(const unsigned char *Start, const unsigned char *End) {
+ IgnoreBlockInfoNames = true;
+ init(Start, End);
+ }
+
+ BitstreamReader(StreamableMemoryObject *bytes) {
+ BitcodeBytes.reset(bytes);
+ }
+
+ void init(const unsigned char *Start, const unsigned char *End) {
+ assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
+ BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End));
+ }
+
+ StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; }
+
+ ~BitstreamReader() {
+ // Free the BlockInfoRecords.
+ while (!BlockInfoRecords.empty()) {
+ BlockInfo &Info = BlockInfoRecords.back();
+ // Free blockinfo abbrev info.
+ for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
+ i != e; ++i)
+ Info.Abbrevs[i]->dropRef();
+ BlockInfoRecords.pop_back();
+ }
+ }
+
+ /// CollectBlockInfoNames - This is called by clients that want block/record
+ /// name information.
+ void CollectBlockInfoNames() { IgnoreBlockInfoNames = false; }
+ bool isIgnoringBlockInfoNames() { return IgnoreBlockInfoNames; }
+
+ //===--------------------------------------------------------------------===//
+ // Block Manipulation
+ //===--------------------------------------------------------------------===//
+
+ /// hasBlockInfoRecords - Return true if we've already read and processed the
+ /// 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 {
+ // Common case, the most recent entry matches BlockID.
+ if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
+ return &BlockInfoRecords.back();
+
+ for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
+ i != e; ++i)
+ if (BlockInfoRecords[i].BlockID == BlockID)
+ return &BlockInfoRecords[i];
+ return 0;
+ }
+
+ BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
+ if (const BlockInfo *BI = getBlockInfo(BlockID))
+ return *const_cast<BlockInfo*>(BI);
+
+ // Otherwise, add a new record.
+ BlockInfoRecords.push_back(BlockInfo());
+ BlockInfoRecords.back().BlockID = BlockID;
+ return BlockInfoRecords.back();
+ }
+
+};
+
+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());
+ S != e; ++S) {
+ std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
+ for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size());
+ i != e; ++i)
+ 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) {
+ std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
+ for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size());
+ i != e; ++i)
+ Abbrevs[i]->dropRef();
+ }
+ 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));
+ }
+
+ bool canSkipToPos(size_t pos) const {
+ // pos can be skipped to if it is a valid address or one byte past the end.
+ return pos == 0 || BitStream->getBitcodeBytes().isValidAddress(
+ static_cast<uint64_t>(pos - 1));
+ }
+
+ unsigned char getByte(size_t pos) {
+ uint8_t byte = -1;
+ BitStream->getBitcodeBytes().readByte(pos, &byte);
+ return byte;
+ }
+
+ uint32_t getWord(size_t pos) {
+ uint8_t buf[sizeof(uint32_t)];
+ memset(buf, 0xFF, sizeof(buf));
+ BitStream->getBitcodeBytes().readBytes(pos,
+ sizeof(buf),
+ buf,
+ NULL);
+ return *reinterpret_cast<support::ulittle32_t *>(buf);
+ }
+
+ 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.
+ if (BitsInCurWord >= NumBits) {
+ uint32_t R = CurWord & ((1U << NumBits)-1);
+ CurWord >>= NumBits;
+ BitsInCurWord -= NumBits;
+ return R;
+ }
+
+ // If we run out of data, stop at the end of the stream.
+ if (isEndPos(NextChar)) {
+ CurWord = 0;
+ BitsInCurWord = 0;
+ return 0;
+ }
+
+ unsigned R = CurWord;
+
+ // Read the next word from the stream.
+ CurWord = getWord(NextChar);
+ NextChar += 4;
+
+ // Extract NumBits-BitsInCurWord from what we just read.
+ unsigned BitsLeft = NumBits-BitsInCurWord;
+
+ // Be careful here, BitsLeft is in the range [1..32] inclusive.
+ R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord;
+
+ // BitsLeft bits have just been used up from CurWord.
+ if (BitsLeft != 32)
+ CurWord >>= BitsLeft;
+ else
+ CurWord = 0;
+ BitsInCurWord = 32-BitsLeft;
+ return R;
+ }
+
+ uint64_t Read64(unsigned NumBits) {
+ if (NumBits <= 32) return Read(NumBits);
+
+ uint64_t V = Read(32);
+ return V | (uint64_t)Read(NumBits-32) << 32;
+ }
+
+ uint32_t ReadVBR(unsigned NumBits) {
+ uint32_t Piece = Read(NumBits);
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Piece;
+
+ uint32_t Result = 0;
+ unsigned NextBit = 0;
+ while (1) {
+ Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
+
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Result;
+
+ NextBit += NumBits-1;
+ Piece = Read(NumBits);
+ }
+ }
+
+ // ReadVBR64 - Read a VBR that may have a value up to 64-bits in size. The
+ // chunk size of the VBR must still be <= 32 bits though.
+ uint64_t ReadVBR64(unsigned NumBits) {
+ uint32_t Piece = Read(NumBits);
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return uint64_t(Piece);
+
+ uint64_t Result = 0;
+ unsigned NextBit = 0;
+ while (1) {
+ Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit;
+
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Result;
+
+ NextBit += NumBits-1;
+ Piece = Read(NumBits);
+ }
+ }
+
+ void SkipToWord() {
+ BitsInCurWord = 0;
+ CurWord = 0;
+ }
+
+ unsigned ReadCode() {
+ return Read(CurCodeSize);
+ }
+
+
+ // Block header:
+ // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
+
+ /// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockID for
+ /// the block.
+ unsigned ReadSubBlockID() {
+ return ReadVBR(bitc::BlockIDWidth);
+ }
+
+ /// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip
+ /// over the body of this block. If the block record is malformed, return
+ /// true.
+ bool SkipBlock() {
+ // Read and ignore the codelen value. Since we are skipping this block, we
+ // don't care what code widths are used inside of it.
+ ReadVBR(bitc::CodeLenWidth);
+ SkipToWord();
+ unsigned NumWords = Read(bitc::BlockSizeWidth);
+
+ // Check that the block wasn't partially defined, and that the offset isn't
+ // bogus.
+ size_t SkipTo = NextChar + NumWords*4;
+ if (AtEndOfStream() || !canSkipToPos(SkipTo))
+ return true;
+
+ NextChar = SkipTo;
+ return false;
+ }
+
+ /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
+ /// the block, and return true if the block is valid.
+ bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
+ // Save the current block's state on BlockScope.
+ BlockScope.push_back(Block(CurCodeSize));
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+
+ // Add the abbrevs specific to this block to the CurAbbrevs list.
+ if (const BitstreamReader::BlockInfo *Info =
+ BitStream->getBlockInfo(BlockID)) {
+ for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
+ i != e; ++i) {
+ CurAbbrevs.push_back(Info->Abbrevs[i]);
+ CurAbbrevs.back()->addRef();
+ }
+ }
+
+ // Get the codesize of this block.
+ CurCodeSize = ReadVBR(bitc::CodeLenWidth);
+ SkipToWord();
+ unsigned NumWords = Read(bitc::BlockSizeWidth);
+ if (NumWordsP) *NumWordsP = NumWords;
+
+ // Validate that this block is sane.
+ if (CurCodeSize == 0 || AtEndOfStream())
+ return true;
+
+ return false;
+ }
+
+ bool ReadBlockEnd() {
+ if (BlockScope.empty()) return true;
+
+ // Block tail:
+ // [END_BLOCK, <align4bytes>]
+ SkipToWord();
+
+ PopBlockScope();
+ return false;
+ }
+
+private:
+ void PopBlockScope() {
+ CurCodeSize = BlockScope.back().PrevCodeSize;
+
+ // Delete abbrevs from popped scope.
+ for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
+ i != e; ++i)
+ CurAbbrevs[i]->dropRef();
+
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+ BlockScope.pop_back();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Record Processing
+ //===--------------------------------------------------------------------===//
+
+private:
+ void ReadAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
+ SmallVectorImpl<uint64_t> &Vals) {
+ assert(Op.isLiteral() && "Not a literal");
+ // 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!");
+
+ // Decode the value as we are commanded.
+ switch (Op.getEncoding()) {
+ default: llvm_unreachable("Unknown encoding!");
+ case BitCodeAbbrevOp::Fixed:
+ Vals.push_back(Read((unsigned)Op.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::VBR:
+ Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::Char6:
+ Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
+ break;
+ }
+ }
+public:
+
+ /// 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) {
+ unsigned Code = ReadVBR(6);
+ unsigned NumElts = ReadVBR(6);
+ for (unsigned i = 0; i != NumElts; ++i)
+ Vals.push_back(ReadVBR64(6));
+ return Code;
+ }
+
+ const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
+
+ for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ if (Op.isLiteral()) {
+ ReadAbbreviatedLiteral(Op, Vals);
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
+ // Array case. Read the number of elements as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+
+ // Get the element encoding.
+ assert(i+2 == e && "array op not second to last?");
+ const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+ // Read all the elements.
+ for (; NumElts; --NumElts)
+ ReadAbbreviatedField(EltEnc, Vals);
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
+ // Blob case. Read the number of bytes as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+ SkipToWord(); // 32-bit alignment
+
+ // 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)) {
+ Vals.append(NumElts, 0);
+ 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) {
+ *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer(
+ NextChar, NumElts);
+ *BlobLen = NumElts;
+ } else {
+ for (; NumElts; ++NextChar, --NumElts)
+ Vals.push_back(getByte(NextChar));
+ }
+ // Skip over tail padding.
+ NextChar = NewEnd;
+ } else {
+ ReadAbbreviatedField(Op, Vals);
+ }
+ }
+
+ unsigned Code = (unsigned)Vals[0];
+ Vals.erase(Vals.begin());
+ return Code;
+ }
+
+ unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
+ const char *&BlobStart, unsigned &BlobLen) {
+ return ReadRecord(AbbrevID, Vals, &BlobStart, &BlobLen);
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Abbrev Processing
+ //===--------------------------------------------------------------------===//
+
+ void ReadAbbrevRecord() {
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ unsigned NumOpInfo = ReadVBR(5);
+ for (unsigned i = 0; i != NumOpInfo; ++i) {
+ bool IsLiteral = Read(1) ? true : false;
+ if (IsLiteral) {
+ Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
+ continue;
+ }
+
+ BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
+ if (BitCodeAbbrevOp::hasEncodingData(E))
+ Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5)));
+ else
+ Abbv->Add(BitCodeAbbrevOp(E));
+ }
+ 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;
+ BitstreamReader::BlockInfo *CurBlockInfo = 0;
+
+ // Read all the records for this module.
+ while (1) {
+ unsigned Code = ReadCode();
+ if (Code == bitc::END_BLOCK)
+ return ReadBlockEnd();
+ if (Code == bitc::ENTER_SUBBLOCK) {
+ ReadSubBlockID();
+ if (SkipBlock()) return true;
+ continue;
+ }
+
+ // Read abbrev records, associate them with CurBID.
+ if (Code == bitc::DEFINE_ABBREV) {
+ if (!CurBlockInfo) return true;
+ ReadAbbrevRecord();
+
+ // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
+ // appropriate BlockInfo.
+ BitCodeAbbrev *Abbv = CurAbbrevs.back();
+ CurAbbrevs.pop_back();
+ CurBlockInfo->Abbrevs.push_back(Abbv);
+ continue;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (ReadRecord(Code, Record)) {
+ default: break; // Default behavior, ignore unknown content.
+ case bitc::BLOCKINFO_CODE_SETBID:
+ if (Record.size() < 1) return true;
+ CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
+ break;
+ case bitc::BLOCKINFO_CODE_BLOCKNAME: {
+ if (!CurBlockInfo) return true;
+ if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
+ std::string Name;
+ for (unsigned i = 0, e = Record.size(); i != e; ++i)
+ Name += (char)Record[i];
+ CurBlockInfo->Name = Name;
+ break;
+ }
+ case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
+ if (!CurBlockInfo) return true;
+ if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
+ std::string Name;
+ for (unsigned i = 1, e = Record.size(); i != e; ++i)
+ Name += (char)Record[i];
+ CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
+ Name));
+ break;
+ }
+ }
+ }
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h b/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h
new file mode 100644
index 000000000000..475da133f8a8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Bitcode/BitstreamWriter.h
@@ -0,0 +1,546 @@
+//===- BitstreamWriter.h - Low-level bitstream writer 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 defines the BitstreamWriter class. This class can be used to
+// write an arbitrary bitstream, regardless of its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BITSTREAM_WRITER_H
+#define BITSTREAM_WRITER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include <vector>
+
+namespace llvm {
+
+class BitstreamWriter {
+ SmallVectorImpl<char> &Out;
+
+ /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
+ unsigned CurBit;
+
+ /// CurValue - The current value. Only bits < CurBit are valid.
+ uint32_t CurValue;
+
+ /// CurCodeSize - This is the declared size of code values used for the
+ /// current block, in bits.
+ unsigned CurCodeSize;
+
+ /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
+ /// selected BLOCK ID.
+ unsigned BlockInfoCurBID;
+
+ /// CurAbbrevs - Abbrevs installed at in this block.
+ std::vector<BitCodeAbbrev*> CurAbbrevs;
+
+ struct Block {
+ unsigned PrevCodeSize;
+ unsigned StartSizeWord;
+ std::vector<BitCodeAbbrev*> PrevAbbrevs;
+ Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
+ };
+
+ /// BlockScope - This tracks the current blocks that we have entered.
+ std::vector<Block> BlockScope;
+
+ /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
+ /// These describe abbreviations that all blocks of the specified ID inherit.
+ struct BlockInfo {
+ unsigned BlockID;
+ std::vector<BitCodeAbbrev*> Abbrevs;
+ };
+ std::vector<BlockInfo> BlockInfoRecords;
+
+ // BackpatchWord - Backpatch a 32-bit word in the output with the specified
+ // value.
+ void BackpatchWord(unsigned ByteNo, unsigned NewWord) {
+ Out[ByteNo++] = (unsigned char)(NewWord >> 0);
+ Out[ByteNo++] = (unsigned char)(NewWord >> 8);
+ Out[ByteNo++] = (unsigned char)(NewWord >> 16);
+ Out[ByteNo ] = (unsigned char)(NewWord >> 24);
+ }
+
+ void WriteByte(unsigned char Value) {
+ Out.push_back(Value);
+ }
+
+ void WriteWord(unsigned Value) {
+ unsigned char Bytes[4] = {
+ (unsigned char)(Value >> 0),
+ (unsigned char)(Value >> 8),
+ (unsigned char)(Value >> 16),
+ (unsigned char)(Value >> 24) };
+ Out.append(&Bytes[0], &Bytes[4]);
+ }
+
+ unsigned GetBufferOffset() const {
+ return Out.size();
+ }
+
+ unsigned GetWordIndex() const {
+ unsigned Offset = GetBufferOffset();
+ assert((Offset & 3) == 0 && "Not 32-bit aligned");
+ return Offset / 4;
+ }
+
+public:
+ explicit BitstreamWriter(SmallVectorImpl<char> &O)
+ : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
+
+ ~BitstreamWriter() {
+ assert(CurBit == 0 && "Unflused data remaining");
+ assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
+
+ // Free the BlockInfoRecords.
+ while (!BlockInfoRecords.empty()) {
+ BlockInfo &Info = BlockInfoRecords.back();
+ // Free blockinfo abbrev info.
+ for (unsigned i = 0, e = static_cast<unsigned>(Info.Abbrevs.size());
+ i != e; ++i)
+ Info.Abbrevs[i]->dropRef();
+ BlockInfoRecords.pop_back();
+ }
+ }
+
+ /// \brief Retrieve the current position in the stream, in bits.
+ uint64_t GetCurrentBitNo() const { return GetBufferOffset() * 8 + CurBit; }
+
+ //===--------------------------------------------------------------------===//
+ // Basic Primitives for emitting bits to the stream.
+ //===--------------------------------------------------------------------===//
+
+ void Emit(uint32_t Val, unsigned NumBits) {
+ assert(NumBits && NumBits <= 32 && "Invalid value size!");
+ assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
+ CurValue |= Val << CurBit;
+ if (CurBit + NumBits < 32) {
+ CurBit += NumBits;
+ return;
+ }
+
+ // Add the current word.
+ WriteWord(CurValue);
+
+ if (CurBit)
+ CurValue = Val >> (32-CurBit);
+ else
+ CurValue = 0;
+ CurBit = (CurBit+NumBits) & 31;
+ }
+
+ void Emit64(uint64_t Val, unsigned NumBits) {
+ if (NumBits <= 32)
+ Emit((uint32_t)Val, NumBits);
+ else {
+ Emit((uint32_t)Val, 32);
+ Emit((uint32_t)(Val >> 32), NumBits-32);
+ }
+ }
+
+ void FlushToWord() {
+ if (CurBit) {
+ WriteWord(CurValue);
+ CurBit = 0;
+ CurValue = 0;
+ }
+ }
+
+ void EmitVBR(uint32_t Val, unsigned NumBits) {
+ uint32_t Threshold = 1U << (NumBits-1);
+
+ // Emit the bits with VBR encoding, NumBits-1 bits at a time.
+ while (Val >= Threshold) {
+ Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
+ Val >>= NumBits-1;
+ }
+
+ Emit(Val, NumBits);
+ }
+
+ void EmitVBR64(uint64_t Val, unsigned NumBits) {
+ if ((uint32_t)Val == Val)
+ return EmitVBR((uint32_t)Val, NumBits);
+
+ uint64_t Threshold = 1U << (NumBits-1);
+
+ // Emit the bits with VBR encoding, NumBits-1 bits at a time.
+ while (Val >= Threshold) {
+ Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
+ (1 << (NumBits-1)), NumBits);
+ Val >>= NumBits-1;
+ }
+
+ Emit((uint32_t)Val, NumBits);
+ }
+
+ /// EmitCode - Emit the specified code.
+ void EmitCode(unsigned Val) {
+ Emit(Val, CurCodeSize);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Block Manipulation
+ //===--------------------------------------------------------------------===//
+
+ /// getBlockInfo - If there is block info for the specified ID, return it,
+ /// otherwise return null.
+ BlockInfo *getBlockInfo(unsigned BlockID) {
+ // Common case, the most recent entry matches BlockID.
+ if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
+ return &BlockInfoRecords.back();
+
+ for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
+ i != e; ++i)
+ if (BlockInfoRecords[i].BlockID == BlockID)
+ return &BlockInfoRecords[i];
+ return 0;
+ }
+
+ void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
+ // Block header:
+ // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
+ EmitCode(bitc::ENTER_SUBBLOCK);
+ EmitVBR(BlockID, bitc::BlockIDWidth);
+ EmitVBR(CodeLen, bitc::CodeLenWidth);
+ FlushToWord();
+
+ unsigned BlockSizeWordIndex = GetWordIndex();
+ unsigned OldCodeSize = CurCodeSize;
+
+ // Emit a placeholder, which will be replaced when the block is popped.
+ Emit(0, bitc::BlockSizeWidth);
+
+ CurCodeSize = CodeLen;
+
+ // Push the outer block's abbrev set onto the stack, start out with an
+ // empty abbrev set.
+ BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex));
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+
+ // If there is a blockinfo for this BlockID, add all the predefined abbrevs
+ // to the abbrev list.
+ if (BlockInfo *Info = getBlockInfo(BlockID)) {
+ for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
+ i != e; ++i) {
+ CurAbbrevs.push_back(Info->Abbrevs[i]);
+ Info->Abbrevs[i]->addRef();
+ }
+ }
+ }
+
+ void ExitBlock() {
+ assert(!BlockScope.empty() && "Block scope imbalance!");
+
+ // Delete all abbrevs.
+ for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
+ i != e; ++i)
+ CurAbbrevs[i]->dropRef();
+
+ const Block &B = BlockScope.back();
+
+ // Block tail:
+ // [END_BLOCK, <align4bytes>]
+ EmitCode(bitc::END_BLOCK);
+ FlushToWord();
+
+ // Compute the size of the block, in words, not counting the size field.
+ unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1;
+ unsigned ByteNo = B.StartSizeWord*4;
+
+ // Update the block size field in the header of this sub-block.
+ BackpatchWord(ByteNo, SizeInWords);
+
+ // Restore the inner block's code size and abbrev table.
+ CurCodeSize = B.PrevCodeSize;
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+ BlockScope.pop_back();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Record Emission
+ //===--------------------------------------------------------------------===//
+
+private:
+ /// EmitAbbreviatedLiteral - Emit a literal value according to its abbrev
+ /// 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");
+ // If the abbrev specifies the literal value to use, don't emit
+ // anything.
+ 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!");
+ case BitCodeAbbrevOp::Fixed:
+ if (Op.getEncodingData())
+ Emit((unsigned)V, (unsigned)Op.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::VBR:
+ if (Op.getEncodingData())
+ EmitVBR64(V, (unsigned)Op.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::Char6:
+ Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
+ 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
+ /// known to exist at the end of the record.
+ template<typename uintty>
+ void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+ StringRef Blob) {
+ const char *BlobData = Blob.data();
+ unsigned BlobLen = (unsigned) Blob.size();
+ unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
+ assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+ BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
+
+ EmitCode(Abbrev);
+
+ unsigned RecordIdx = 0;
+ for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
+ i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ if (Op.isLiteral()) {
+ assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+ EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
+ ++RecordIdx;
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
+ // Array case.
+ assert(i+2 == e && "array op not second to last?");
+ const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+ // If this record has blob data, emit it, otherwise we must have record
+ // entries to encode this way.
+ if (BlobData) {
+ assert(RecordIdx == Vals.size() &&
+ "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 {
+ // Emit a vbr6 to indicate the number of elements present.
+ EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
+
+ // Emit each field.
+ for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx)
+ EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
+ }
+ } 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);
+ assert(RecordIdx == Vals.size() &&
+ "Blob data and record entries specified for blob operand!");
+ } else {
+ EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
+ }
+
+ // Flush to a 32-bit alignment boundary.
+ FlushToWord();
+
+ // Emit each field as a literal byte.
+ 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 {
+ for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) {
+ assert(Vals[RecordIdx] < 256 && "Value too large to emit as blob");
+ WriteByte((unsigned char)Vals[RecordIdx]);
+ }
+ }
+
+ // Align end to 32-bits.
+ while (GetBufferOffset() & 3)
+ WriteByte(0);
+ } else { // Single scalar field.
+ assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+ EmitAbbreviatedField(Op, Vals[RecordIdx]);
+ ++RecordIdx;
+ }
+ }
+ assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
+ 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
+ /// we have one to compress the output.
+ template<typename uintty>
+ void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals,
+ unsigned Abbrev = 0) {
+ if (!Abbrev) {
+ // If we don't have an abbrev to use, emit this in its fully unabbreviated
+ // form.
+ EmitCode(bitc::UNABBREV_RECORD);
+ EmitVBR(Code, 6);
+ EmitVBR(static_cast<uint32_t>(Vals.size()), 6);
+ for (unsigned i = 0, e = static_cast<unsigned>(Vals.size()); i != e; ++i)
+ EmitVBR64(Vals[i], 6);
+ return;
+ }
+
+ // 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.
+ template<typename uintty>
+ 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
+ /// EmitRecord, this routine expects that the first entry in Vals is the code
+ /// of the record.
+ template<typename uintty>
+ void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+ StringRef Blob) {
+ EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob);
+ }
+ template<typename uintty>
+ void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+ const char *BlobData, unsigned BlobLen) {
+ return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen));
+ }
+
+ /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records
+ /// that end with an array.
+ template<typename uintty>
+ void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+ StringRef Array) {
+ EmitRecordWithAbbrevImpl(Abbrev, Vals, Array);
+ }
+ template<typename uintty>
+ void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,
+ const char *ArrayData, unsigned ArrayLen) {
+ return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData,
+ ArrayLen));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Abbrev Emission
+ //===--------------------------------------------------------------------===//
+
+private:
+ // Emit the abbreviation as a DEFINE_ABBREV record.
+ void EncodeAbbrev(BitCodeAbbrev *Abbv) {
+ EmitCode(bitc::DEFINE_ABBREV);
+ EmitVBR(Abbv->getNumOperandInfos(), 5);
+ for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos());
+ i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ Emit(Op.isLiteral(), 1);
+ if (Op.isLiteral()) {
+ EmitVBR64(Op.getLiteralValue(), 8);
+ } else {
+ Emit(Op.getEncoding(), 3);
+ if (Op.hasEncodingData())
+ EmitVBR64(Op.getEncodingData(), 5);
+ }
+ }
+ }
+public:
+
+ /// EmitAbbrev - This emits an abbreviation to the stream. Note that this
+ /// method takes ownership of the specified abbrev.
+ unsigned EmitAbbrev(BitCodeAbbrev *Abbv) {
+ // Emit the abbreviation as a record.
+ EncodeAbbrev(Abbv);
+ CurAbbrevs.push_back(Abbv);
+ return static_cast<unsigned>(CurAbbrevs.size())-1 +
+ bitc::FIRST_APPLICATION_ABBREV;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // BlockInfo Block Emission
+ //===--------------------------------------------------------------------===//
+
+ /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
+ void EnterBlockInfoBlock(unsigned CodeWidth) {
+ EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth);
+ BlockInfoCurBID = ~0U;
+ }
+private:
+ /// SwitchToBlockID - If we aren't already talking about the specified block
+ /// ID, emit a BLOCKINFO_CODE_SETBID record.
+ void SwitchToBlockID(unsigned BlockID) {
+ if (BlockInfoCurBID == BlockID) return;
+ SmallVector<unsigned, 2> V;
+ V.push_back(BlockID);
+ EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
+ BlockInfoCurBID = BlockID;
+ }
+
+ BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
+ if (BlockInfo *BI = getBlockInfo(BlockID))
+ return *BI;
+
+ // Otherwise, add a new record.
+ BlockInfoRecords.push_back(BlockInfo());
+ BlockInfoRecords.back().BlockID = BlockID;
+ return BlockInfoRecords.back();
+ }
+
+public:
+
+ /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
+ /// BlockID.
+ unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) {
+ SwitchToBlockID(BlockID);
+ EncodeAbbrev(Abbv);
+
+ // Add the abbrev to the specified block record.
+ BlockInfo &Info = getOrCreateBlockInfo(BlockID);
+ Info.Abbrevs.push_back(Abbv);
+
+ return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
+ }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h
new file mode 100644
index 000000000000..a8c34cb82995
--- /dev/null
+++ b/contrib/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -0,0 +1,326 @@
+//===- LLVMBitCodes.h - Enum values for the LLVM bitcode format -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines Bitcode enum values for LLVM IR bitcode files.
+//
+// The enum values defined in this file should be considered permanent. If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_LLVMBITCODES_H
+#define LLVM_BITCODE_LLVMBITCODES_H
+
+#include "llvm/Bitcode/BitCodes.h"
+
+namespace llvm {
+namespace bitc {
+ // The only top-level block type defined is for a module.
+ enum BlockIDs {
+ // Blocks
+ MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID,
+
+ // Module sub-block id's.
+ 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
+ };
+
+
+ /// MODULE blocks have a number of optional fields and subblocks.
+ enum ModuleCodes {
+ MODULE_CODE_VERSION = 1, // VERSION: [version#]
+ MODULE_CODE_TRIPLE = 2, // TRIPLE: [strchr x N]
+ MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N]
+ MODULE_CODE_ASM = 4, // ASM: [strchr x N]
+ MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N]
+ MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N]
+
+ // GLOBALVAR: [pointer type, isconst, initid,
+ // linkage, alignment, section, visibility, threadlocal]
+ MODULE_CODE_GLOBALVAR = 7,
+
+ // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
+ // section, visibility, gc, unnamed_addr]
+ MODULE_CODE_FUNCTION = 8,
+
+ // ALIAS: [alias type, aliasee val#, linkage, visibility]
+ MODULE_CODE_ALIAS = 9,
+
+ /// MODULE_CODE_PURGEVALS: [numvals]
+ MODULE_CODE_PURGEVALS = 10,
+
+ MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N]
+ };
+
+ /// PARAMATTR blocks have code for defining a parameter attribute set.
+ enum AttributeCodes {
+ PARAMATTR_CODE_ENTRY = 1 // ENTRY: [paramidx0, attr0, paramidx1, attr1...]
+ };
+
+ /// TYPE blocks have codes for each type primitive they use.
+ enum TypeCodes {
+ TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries]
+
+ // Type Codes
+ TYPE_CODE_VOID = 2, // VOID
+ TYPE_CODE_FLOAT = 3, // FLOAT
+ TYPE_CODE_DOUBLE = 4, // DOUBLE
+ TYPE_CODE_LABEL = 5, // LABEL
+ TYPE_CODE_OPAQUE = 6, // OPAQUE
+ TYPE_CODE_INTEGER = 7, // INTEGER: [width]
+ TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
+
+ 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]
+
+ // These are not with the other floating point types because they're
+ // a late addition, and putting them in the right place breaks
+ // binary compatibility.
+ TYPE_CODE_X86_FP80 = 13, // X86 LONG DOUBLE
+ TYPE_CODE_FP128 = 14, // LONG DOUBLE (112 bit mantissa)
+ TYPE_CODE_PPC_FP128= 15, // PPC LONG DOUBLE (2 doubles)
+
+ TYPE_CODE_METADATA = 16, // METADATA
+
+ TYPE_CODE_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]
+
+ TYPE_CODE_FUNCTION = 21 // FUNCTION: [vararg, retty, paramty x N]
+ };
+
+ // The type symbol table only has one code (TST_ENTRY_CODE).
+ enum TypeSymtabCodes {
+ TST_CODE_ENTRY = 1 // TST_ENTRY: [typeid, namechar x N]
+ };
+
+ // The value symbol table only has one code (VST_ENTRY_CODE).
+ enum ValueSymtabCodes {
+ VST_CODE_ENTRY = 1, // VST_ENTRY: [valid, namechar x N]
+ VST_CODE_BBENTRY = 2 // VST_BBENTRY: [bbid, namechar x N]
+ };
+
+ enum MetadataCodes {
+ METADATA_STRING = 1, // MDSTRING: [values]
+ // 2 is unused.
+ // 3 is unused.
+ METADATA_NAME = 4, // STRING: [values]
+ // 5 is unused.
+ METADATA_KIND = 6, // [n x [id, name]]
+ // 7 is unused.
+ METADATA_NODE = 8, // NODE: [n x (type num, value num)]
+ METADATA_FN_NODE = 9, // FN_NODE: [n x (type num, value num)]
+ METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
+ METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]]
+ };
+ // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
+ // constant and maintains an implicit current type value.
+ enum ConstantsCodes {
+ CST_CODE_SETTYPE = 1, // SETTYPE: [typeid]
+ CST_CODE_NULL = 2, // NULL
+ CST_CODE_UNDEF = 3, // UNDEF
+ CST_CODE_INTEGER = 4, // INTEGER: [intval]
+ CST_CODE_WIDE_INTEGER = 5, // WIDE_INTEGER: [n x intval]
+ CST_CODE_FLOAT = 6, // FLOAT: [fpval]
+ CST_CODE_AGGREGATE = 7, // AGGREGATE: [n x value number]
+ CST_CODE_STRING = 8, // STRING: [values]
+ CST_CODE_CSTRING = 9, // CSTRING: [values]
+ CST_CODE_CE_BINOP = 10, // CE_BINOP: [opcode, opval, opval]
+ CST_CODE_CE_CAST = 11, // CE_CAST: [opcode, opty, opval]
+ CST_CODE_CE_GEP = 12, // CE_GEP: [n x operands]
+ CST_CODE_CE_SELECT = 13, // CE_SELECT: [opval, opval, opval]
+ CST_CODE_CE_EXTRACTELT = 14, // CE_EXTRACTELT: [opty, opval, opval]
+ CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval]
+ CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval]
+ CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred]
+ CST_CODE_INLINEASM = 18, // INLINEASM: [sideeffect,asmstr,conststr]
+ CST_CODE_CE_SHUFVEC_EX = 19, // SHUFVEC_EX: [opty, opval, opval, opval]
+ CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP: [n x operands]
+ CST_CODE_BLOCKADDRESS = 21, // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
+ CST_CODE_DATA = 22 // DATA: [n x elements]
+ };
+
+ /// CastOpcodes - These are values used in the bitcode files to encode which
+ /// cast a CST_CODE_CE_CAST or a XXX refers to. The values of these enums
+ /// have no fixed relation to the LLVM IR enum values. Changing these will
+ /// break compatibility with old files.
+ enum CastOpcodes {
+ CAST_TRUNC = 0,
+ CAST_ZEXT = 1,
+ CAST_SEXT = 2,
+ CAST_FPTOUI = 3,
+ CAST_FPTOSI = 4,
+ CAST_UITOFP = 5,
+ CAST_SITOFP = 6,
+ CAST_FPTRUNC = 7,
+ CAST_FPEXT = 8,
+ CAST_PTRTOINT = 9,
+ CAST_INTTOPTR = 10,
+ CAST_BITCAST = 11
+ };
+
+ /// BinaryOpcodes - These are values used in the bitcode files to encode which
+ /// binop a CST_CODE_CE_BINOP or a XXX refers to. The values of these enums
+ /// have no fixed relation to the LLVM IR enum values. Changing these will
+ /// break compatibility with old files.
+ enum BinaryOpcodes {
+ BINOP_ADD = 0,
+ BINOP_SUB = 1,
+ BINOP_MUL = 2,
+ BINOP_UDIV = 3,
+ BINOP_SDIV = 4, // overloaded for FP
+ BINOP_UREM = 5,
+ BINOP_SREM = 6, // overloaded for FP
+ BINOP_SHL = 7,
+ BINOP_LSHR = 8,
+ BINOP_ASHR = 9,
+ BINOP_AND = 10,
+ BINOP_OR = 11,
+ BINOP_XOR = 12
+ };
+
+ /// These are values used in the bitcode files to encode AtomicRMW operations.
+ /// The values of these enums have no fixed relation to the LLVM IR enum
+ /// values. Changing these will break compatibility with old files.
+ enum RMWOperations {
+ RMW_XCHG = 0,
+ RMW_ADD = 1,
+ RMW_SUB = 2,
+ RMW_AND = 3,
+ RMW_NAND = 4,
+ RMW_OR = 5,
+ RMW_XOR = 6,
+ RMW_MAX = 7,
+ RMW_MIN = 8,
+ RMW_UMAX = 9,
+ RMW_UMIN = 10
+ };
+
+ /// OverflowingBinaryOperatorOptionalFlags - Flags for serializing
+ /// OverflowingBinaryOperator's SubclassOptionalData contents.
+ enum OverflowingBinaryOperatorOptionalFlags {
+ OBO_NO_UNSIGNED_WRAP = 0,
+ OBO_NO_SIGNED_WRAP = 1
+ };
+
+ /// PossiblyExactOperatorOptionalFlags - Flags for serializing
+ /// PossiblyExactOperator's SubclassOptionalData contents.
+ enum PossiblyExactOperatorOptionalFlags {
+ PEO_EXACT = 0
+ };
+
+ /// Encoded AtomicOrdering values.
+ enum AtomicOrderingCodes {
+ ORDERING_NOTATOMIC = 0,
+ ORDERING_UNORDERED = 1,
+ ORDERING_MONOTONIC = 2,
+ ORDERING_ACQUIRE = 3,
+ ORDERING_RELEASE = 4,
+ ORDERING_ACQREL = 5,
+ ORDERING_SEQCST = 6
+ };
+
+ /// Encoded SynchronizationScope values.
+ enum AtomicSynchScopeCodes {
+ SYNCHSCOPE_SINGLETHREAD = 0,
+ SYNCHSCOPE_CROSSTHREAD = 1
+ };
+
+ // The function body block (FUNCTION_BLOCK_ID) describes function bodies. It
+ // can contain a constant block (CONSTANTS_BLOCK_ID).
+ enum FunctionCodes {
+ FUNC_CODE_DECLAREBLOCKS = 1, // DECLAREBLOCKS: [n]
+
+ FUNC_CODE_INST_BINOP = 2, // BINOP: [opcode, ty, opval, opval]
+ FUNC_CODE_INST_CAST = 3, // CAST: [opcode, ty, opty, opval]
+ FUNC_CODE_INST_GEP = 4, // GEP: [n x operands]
+ FUNC_CODE_INST_SELECT = 5, // SELECT: [ty, opval, opval, opval]
+ FUNC_CODE_INST_EXTRACTELT = 6, // EXTRACTELT: [opty, opval, opval]
+ FUNC_CODE_INST_INSERTELT = 7, // INSERTELT: [ty, opval, opval, opval]
+ FUNC_CODE_INST_SHUFFLEVEC = 8, // SHUFFLEVEC: [ty, opval, opval, opval]
+ FUNC_CODE_INST_CMP = 9, // CMP: [opty, opval, opval, pred]
+
+ FUNC_CODE_INST_RET = 10, // RET: [opty,opval<both optional>]
+ FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#]
+ FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...]
+ FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...]
+ // 14 is unused.
+ FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
+
+ FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...]
+ // 17 is unused.
+ // 18 is unused.
+ FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align]
+ FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
+ // 21 is unused.
+ // 22 is unused.
+ FUNC_CODE_INST_VAARG = 23, // VAARG: [valistty, valist, instty]
+ // This store code encodes the pointer type, rather than the value type
+ // this is so information only available in the pointer type (e.g. address
+ // spaces) is retained.
+ FUNC_CODE_INST_STORE = 24, // STORE: [ptrty,ptr,val, align, vol]
+ // 25 is unused.
+ FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands]
+ FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands]
+ // fcmp/icmp returning Int1TY or vector of Int1Ty. Same as CMP, exists to
+ // support legacy vicmp/vfcmp instructions.
+ FUNC_CODE_INST_CMP2 = 28, // CMP2: [opty, opval, opval, pred]
+ // new select on i1 or [N x i1]
+ FUNC_CODE_INST_VSELECT = 29, // VSELECT: [ty,opval,opval,predty,pred]
+ FUNC_CODE_INST_INBOUNDS_GEP= 30, // INBOUNDS_GEP: [n x operands]
+ FUNC_CODE_INST_INDIRECTBR = 31, // INDIRECTBR: [opty, op0, op1, ...]
+ // 32 is unused.
+ FUNC_CODE_DEBUG_LOC_AGAIN = 33, // DEBUG_LOC_AGAIN
+
+ FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...]
+
+ FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal]
+ FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
+ FUNC_CODE_INST_CMPXCHG = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
+ // ordering, synchscope]
+ FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
+ // align, vol,
+ // ordering, synchscope]
+ FUNC_CODE_INST_RESUME = 39, // RESUME: [opval]
+ FUNC_CODE_INST_LANDINGPAD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...]
+ FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol,
+ // ordering, synchscope]
+ FUNC_CODE_INST_STOREATOMIC = 42 // STORE: [ptrty,ptr,val, align, vol
+ // ordering, synchscope]
+ };
+
+ enum UseListCodes {
+ USELIST_CODE_ENTRY = 1 // USELIST_CODE_ENTRY: TBD.
+ };
+} // End bitc namespace
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h b/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h
new file mode 100644
index 000000000000..cc2b473f2c57
--- /dev/null
+++ b/contrib/llvm/include/llvm/Bitcode/ReaderWriter.h
@@ -0,0 +1,154 @@
+//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines interfaces to read and write LLVM bitcode files/streams.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_H
+#define LLVM_BITCODE_H
+
+#include <string>
+
+namespace llvm {
+ class BitstreamWriter;
+ class MemoryBuffer;
+ class DataStreamer;
+ class LLVMContext;
+ class Module;
+ class ModulePass;
+ class raw_ostream;
+
+ /// getLazyBitcodeModule - Read the header of the specified bitcode buffer
+ /// and prepare for lazy deserialization of function bodies. If successful,
+ /// this takes ownership of 'buffer' and returns a non-null pointer. On
+ /// error, this returns null, *does not* take ownership of Buffer, and fills
+ /// in *ErrMsg with an error description if ErrMsg is non-null.
+ Module *getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext &Context,
+ std::string *ErrMsg = 0);
+
+ /// getStreamedBitcodeModule - Read the header of the specified stream
+ /// and prepare for lazy deserialization and streaming of function bodies.
+ /// On error, this returns null, and fills in *ErrMsg with an error
+ /// description if ErrMsg is non-null.
+ Module *getStreamedBitcodeModule(const std::string &name,
+ DataStreamer *streamer,
+ LLVMContext &Context,
+ std::string *ErrMsg = 0);
+
+ /// getBitcodeTargetTriple - Read the header of the specified bitcode
+ /// buffer and extract just the triple information. If successful,
+ /// this returns a string and *does not* take ownership
+ /// of 'buffer'. On error, this returns "", and fills in *ErrMsg
+ /// if ErrMsg is non-null.
+ std::string getBitcodeTargetTriple(MemoryBuffer *Buffer,
+ LLVMContext &Context,
+ std::string *ErrMsg = 0);
+
+ /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+ /// If an error occurs, this returns null and fills in *ErrMsg if it is
+ /// non-null. This method *never* takes ownership of Buffer.
+ Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context,
+ std::string *ErrMsg = 0);
+
+ /// WriteBitcodeToFile - Write the specified module to the specified
+ /// raw output stream. For streams where it matters, the given stream
+ /// should be in "binary" mode.
+ void WriteBitcodeToFile(const Module *M, raw_ostream &Out);
+
+ /// createBitcodeWriterPass - Create and return a pass that writes the module
+ /// to the specified ostream.
+ ModulePass *createBitcodeWriterPass(raw_ostream &Str);
+
+
+ /// isBitcodeWrapper - Return true if the given bytes are the magic bytes
+ /// for an LLVM IR bitcode wrapper.
+ ///
+ static inline bool isBitcodeWrapper(const unsigned char *BufPtr,
+ const unsigned char *BufEnd) {
+ // See if you can find the hidden message in the magic bytes :-).
+ // (Hint: it's a little-endian encoding.)
+ return BufPtr != BufEnd &&
+ BufPtr[0] == 0xDE &&
+ BufPtr[1] == 0xC0 &&
+ BufPtr[2] == 0x17 &&
+ BufPtr[3] == 0x0B;
+ }
+
+ /// isRawBitcode - Return true if the given bytes are the magic bytes for
+ /// raw LLVM IR bitcode (without a wrapper).
+ ///
+ static inline bool isRawBitcode(const unsigned char *BufPtr,
+ const unsigned char *BufEnd) {
+ // These bytes sort of have a hidden message, but it's not in
+ // little-endian this time, and it's a little redundant.
+ return BufPtr != BufEnd &&
+ BufPtr[0] == 'B' &&
+ BufPtr[1] == 'C' &&
+ BufPtr[2] == 0xc0 &&
+ BufPtr[3] == 0xde;
+ }
+
+ /// isBitcode - Return true if the given bytes are the magic bytes for
+ /// LLVM IR bitcode, either with or without a wrapper.
+ ///
+ static bool inline isBitcode(const unsigned char *BufPtr,
+ const unsigned char *BufEnd) {
+ return isBitcodeWrapper(BufPtr, BufEnd) ||
+ isRawBitcode(BufPtr, BufEnd);
+ }
+
+ /// SkipBitcodeWrapperHeader - Some systems wrap bc files with a special
+ /// header for padding or other reasons. The format of this header is:
+ ///
+ /// struct bc_header {
+ /// uint32_t Magic; // 0x0B17C0DE
+ /// uint32_t Version; // Version, currently always 0.
+ /// uint32_t BitcodeOffset; // Offset to traditional bitcode file.
+ /// uint32_t BitcodeSize; // Size of traditional bitcode file.
+ /// ... potentially other gunk ...
+ /// };
+ ///
+ /// This function is called when we find a file with a matching magic number.
+ /// In this case, skip down to the subsection of the file that is actually a
+ /// BC file.
+ /// If 'VerifyBufferSize' is true, check that the buffer is large enough to
+ /// contain the whole bitcode file.
+ static inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr,
+ const unsigned char *&BufEnd,
+ bool VerifyBufferSize) {
+ enum {
+ KnownHeaderSize = 4*4, // Size of header we read.
+ OffsetField = 2*4, // Offset in bytes to Offset field.
+ SizeField = 3*4 // Offset in bytes to Size field.
+ };
+
+ // Must contain the header!
+ if (BufEnd-BufPtr < KnownHeaderSize) return true;
+
+ unsigned Offset = ( BufPtr[OffsetField ] |
+ (BufPtr[OffsetField+1] << 8) |
+ (BufPtr[OffsetField+2] << 16) |
+ (BufPtr[OffsetField+3] << 24));
+ unsigned Size = ( BufPtr[SizeField ] |
+ (BufPtr[SizeField +1] << 8) |
+ (BufPtr[SizeField +2] << 16) |
+ (BufPtr[SizeField +3] << 24));
+
+ // Verify that Offset+Size fits in the file.
+ if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr))
+ return true;
+ BufPtr += Offset;
+ BufEnd = BufPtr+Size;
+ return false;
+ }
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CallGraphSCCPass.h b/contrib/llvm/include/llvm/CallGraphSCCPass.h
new file mode 100644
index 000000000000..7154aa3259d2
--- /dev/null
+++ b/contrib/llvm/include/llvm/CallGraphSCCPass.h
@@ -0,0 +1,104 @@
+//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- 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 CallGraphSCCPass class, which is used for passes which
+// are implemented as bottom-up traversals on the call graph. Because there may
+// be cycles in the call graph, passes of this type operate on the call-graph in
+// SCC order: that is, they process function bottom-up, except for recursive
+// functions, which they process all at once.
+//
+// These passes are inherently interprocedural, and are required to keep the
+// call graph up-to-date if they do anything which could modify it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
+#define LLVM_CALL_GRAPH_SCC_PASS_H
+
+#include "llvm/Pass.h"
+#include "llvm/Analysis/CallGraph.h"
+
+namespace llvm {
+
+class CallGraphNode;
+class CallGraph;
+class PMStack;
+class CallGraphSCC;
+
+class CallGraphSCCPass : public Pass {
+public:
+ explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
+
+ /// createPrinterPass - Get a pass that prints the Module
+ /// corresponding to a CallGraph.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
+ /// 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) {
+ return false;
+ }
+
+ /// runOnSCC - This method should be implemented by the subclass to perform
+ /// whatever action is necessary for the specified SCC. Note that
+ /// non-recursive (or only self-recursive) functions will have an SCC size of
+ /// 1, where recursive portions of the call graph will have SCC size > 1.
+ ///
+ /// SCC passes that add or delete functions to the SCC are required to update
+ /// the SCC list, otherwise stale pointers may be dereferenced.
+ ///
+ virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
+
+ /// doFinalization - This method is called after the SCC's of the program has
+ /// been processed, allowing the pass to do final cleanup as necessary.
+ virtual bool doFinalization(CallGraph &CG) {
+ return false;
+ }
+
+ /// Assign pass manager to manager this pass
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType PMT);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_CallGraphPassManager;
+ }
+
+ /// getAnalysisUsage - For this class, we declare that we require and preserve
+ /// the call graph. If the derived class implements this method, it should
+ /// always explicitly call the implementation here.
+ virtual void getAnalysisUsage(AnalysisUsage &Info) const;
+};
+
+/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
+class CallGraphSCC {
+ void *Context; // The CGPassManager object that is vending this.
+ std::vector<CallGraphNode*> Nodes;
+public:
+ CallGraphSCC(void *context) : Context(context) {}
+
+ void initialize(CallGraphNode*const*I, CallGraphNode*const*E) {
+ Nodes.assign(I, E);
+ }
+
+ bool isSingular() const { return Nodes.size() == 1; }
+ unsigned size() const { return Nodes.size(); }
+
+ /// ReplaceNode - This informs the SCC and the pass manager that the specified
+ /// Old node has been deleted, and New is to be used in its place.
+ void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
+
+ typedef std::vector<CallGraphNode*>::const_iterator iterator;
+ iterator begin() const { return Nodes.begin(); }
+ iterator end() const { return Nodes.end(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CallingConv.h b/contrib/llvm/include/llvm/CallingConv.h
new file mode 100644
index 000000000000..4c5ee626709a
--- /dev/null
+++ b/contrib/llvm/include/llvm/CallingConv.h
@@ -0,0 +1,103 @@
+//===-- llvm/CallingConv.h - LLVM Calling Conventions -----------*- 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 LLVM's set of calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CALLINGCONV_H
+#define LLVM_CALLINGCONV_H
+
+namespace llvm {
+
+/// CallingConv Namespace - This namespace contains an enum with a value for
+/// the well-known calling conventions.
+///
+namespace CallingConv {
+ /// A set of enums which specify the assigned numeric values for known llvm
+ /// calling conventions.
+ /// @brief LLVM Calling Convention Representation
+ enum ID {
+ /// C - The default llvm calling convention, compatible with C. This
+ /// convention is the only calling convention that supports varargs calls.
+ /// As with typical C calling conventions, the callee/caller have to
+ /// tolerate certain amounts of prototype mismatch.
+ C = 0,
+
+ // Generic LLVM calling conventions. None of these calling conventions
+ // support varargs calls, and all assume that the caller and callee
+ // prototype exactly match.
+
+ /// Fast - This calling convention attempts to make calls as fast as
+ /// possible (e.g. by passing things in registers).
+ Fast = 8,
+
+ // Cold - This calling convention attempts to make code in the caller as
+ // efficient as possible under the assumption that the call is not commonly
+ // executed. As such, these calls often preserve all registers so that the
+ // call does not break any live ranges in the caller side.
+ Cold = 9,
+
+ // GHC - Calling convention used by the Glasgow Haskell Compiler (GHC).
+ GHC = 10,
+
+ // Target - This is the start of the target-specific calling conventions,
+ // e.g. fastcall and thiscall on X86.
+ FirstTargetCC = 64,
+
+ /// X86_StdCall - stdcall is the calling conventions mostly used by the
+ /// Win32 API. It is basically the same as the C convention with the
+ /// difference in that the callee is responsible for popping the arguments
+ /// from the stack.
+ X86_StdCall = 64,
+
+ /// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
+ /// in ECX:EDX registers, others - via stack. Callee is responsible for
+ /// stack cleaning.
+ X86_FastCall = 65,
+
+ /// ARM_APCS - ARM Procedure Calling Standard calling convention (obsolete,
+ /// but still used on some targets).
+ ARM_APCS = 66,
+
+ /// ARM_AAPCS - ARM Architecture Procedure Calling Standard calling
+ /// convention (aka EABI). Soft float variant.
+ ARM_AAPCS = 67,
+
+ /// ARM_AAPCS_VFP - Same as ARM_AAPCS, but uses hard floating point ABI.
+ ARM_AAPCS_VFP = 68,
+
+ /// MSP430_INTR - Calling convention used for MSP430 interrupt routines.
+ MSP430_INTR = 69,
+
+ /// X86_ThisCall - Similar to X86_StdCall. Passes first argument in ECX,
+ /// others via stack. Callee is responsible for stack cleaning. MSVC uses
+ /// this by default for methods in its ABI.
+ X86_ThisCall = 70,
+
+ /// PTX_Kernel - Call to a PTX kernel.
+ /// Passes all arguments in parameter space.
+ PTX_Kernel = 71,
+
+ /// PTX_Device - Call to a PTX device function.
+ /// Passes all arguments in register or parameter space.
+ PTX_Device = 72,
+
+ /// MBLAZE_INTR - Calling convention used for MBlaze interrupt routines.
+ MBLAZE_INTR = 73,
+
+ /// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
+ /// routines (i.e. GCC's save_volatiles attribute).
+ MBLAZE_SVOL = 74
+ };
+} // End CallingConv namespace
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/Analysis.h b/contrib/llvm/include/llvm/CodeGen/Analysis.h
new file mode 100644
index 000000000000..0b609ed6586e
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/Analysis.h
@@ -0,0 +1,97 @@
+//===- CodeGen/Analysis.h - CodeGen LLVM IR Analysis Utilities --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares several CodeGen-specific LLVM IR analysis utilties.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/CallSite.h"
+
+namespace llvm {
+
+class GlobalVariable;
+class TargetLowering;
+class SDNode;
+class SDValue;
+class SelectionDAG;
+
+/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
+/// of insertvalue or extractvalue indices that identify a member, return
+/// the linearized index of the start of the member.
+///
+unsigned ComputeLinearIndex(Type *Ty,
+ const unsigned *Indices,
+ const unsigned *IndicesEnd,
+ unsigned CurIndex = 0);
+
+inline unsigned ComputeLinearIndex(Type *Ty,
+ ArrayRef<unsigned> Indices,
+ unsigned CurIndex = 0) {
+ return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex);
+}
+
+/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
+/// EVTs that represent all the individual underlying
+/// non-aggregate types that comprise it.
+///
+/// If Offsets is non-null, it points to a vector to be filled in
+/// with the in-memory offsets of each of the individual values.
+///
+void ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
+ SmallVectorImpl<EVT> &ValueVTs,
+ SmallVectorImpl<uint64_t> *Offsets = 0,
+ uint64_t StartingOffset = 0);
+
+/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
+GlobalVariable *ExtractTypeInfo(Value *V);
+
+/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being
+/// processed uses a memory 'm' constraint.
+bool hasInlineAsmMemConstraint(InlineAsm::ConstraintInfoVector &CInfos,
+ const TargetLowering &TLI);
+
+/// getFCmpCondCode - Return the ISD condition code corresponding to
+/// the given LLVM IR floating-point condition code. This includes
+/// consideration of global floating-point math flags.
+///
+ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred);
+
+/// getFCmpCodeWithoutNaN - Given an ISD condition code comparing floats,
+/// return the equivalent code if we're allowed to assume that NaNs won't occur.
+ISD::CondCode getFCmpCodeWithoutNaN(ISD::CondCode CC);
+
+/// getICmpCondCode - Return the ISD condition code corresponding to
+/// the given LLVM IR integer condition code.
+///
+ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
+
+/// Test if the given instruction is in a position to be optimized
+/// with a tail-call. This roughly means that it's in a block with
+/// a return and there's nothing that needs to be scheduled
+/// between it and the return.
+///
+/// This function only tests target-independent requirements.
+bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
+ const TargetLowering &TLI);
+
+bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
+ SDValue &Chain, const TargetLowering &TLI);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h
new file mode 100644
index 000000000000..56a87f139a21
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -0,0 +1,482 @@
+//===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the base class for target specific
+// asm writers. This class primarily handles common functionality used by
+// all asm writers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ASMPRINTER_H
+#define LLVM_CODEGEN_ASMPRINTER_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+ class BlockAddress;
+ class GCStrategy;
+ class Constant;
+ class GCMetadataPrinter;
+ class GlobalValue;
+ class GlobalVariable;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class MachineLocation;
+ class MachineLoopInfo;
+ class MachineLoop;
+ class MachineConstantPoolValue;
+ class MachineJumpTableInfo;
+ class MachineModuleInfo;
+ class MachineMove;
+ class MCAsmInfo;
+ class MCContext;
+ class MCSection;
+ class MCStreamer;
+ class MCSymbol;
+ class MDNode;
+ class DwarfDebug;
+ class DwarfException;
+ class Mangler;
+ class TargetLoweringObjectFile;
+ class TargetData;
+ class TargetMachine;
+
+ /// AsmPrinter - This class is intended to be used as a driving class for all
+ /// asm writers.
+ class AsmPrinter : public MachineFunctionPass {
+ public:
+ /// Target machine description.
+ ///
+ TargetMachine &TM;
+
+ /// Target Asm Printer information.
+ ///
+ const MCAsmInfo *MAI;
+
+ /// OutContext - This is the context for the output file that we are
+ /// streaming. This owns all of the global MC-related objects for the
+ /// generated translation unit.
+ MCContext &OutContext;
+
+ /// OutStreamer - This is the MCStreamer object for the file we are
+ /// generating. This contains the transient state for the current
+ /// translation unit that we are generating (such as the current section
+ /// etc).
+ MCStreamer &OutStreamer;
+
+ /// The current machine function.
+ const MachineFunction *MF;
+
+ /// MMI - This is a pointer to the current MachineModuleInfo.
+ MachineModuleInfo *MMI;
+
+ /// Name-mangler for global names.
+ ///
+ Mangler *Mang;
+
+ /// The symbol for the current function. This is recalculated at the
+ /// beginning of each call to runOnMachineFunction().
+ ///
+ MCSymbol *CurrentFnSym;
+
+ /// The symbol used to represent the start of the current function for the
+ /// purpose of calculating its size (e.g. using the .size directive). By
+ /// default, this is equal to CurrentFnSym.
+ MCSymbol *CurrentFnSymForSize;
+
+ private:
+ // GCMetadataPrinters - The garbage collection metadata printer table.
+ void *GCMetadataPrinters; // Really a DenseMap.
+
+ /// VerboseAsm - Emit comments in assembly output if this is true.
+ ///
+ bool VerboseAsm;
+ static char ID;
+
+ /// If VerboseAsm is set, a pointer to the loop info for this
+ /// function.
+ MachineLoopInfo *LI;
+
+ /// DD - If the target supports dwarf debug info, this pointer is non-null.
+ DwarfDebug *DD;
+
+ /// DE - If the target supports dwarf exception info, this pointer is
+ /// non-null.
+ DwarfException *DE;
+
+ protected:
+ explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer);
+
+ public:
+ virtual ~AsmPrinter();
+
+ /// isVerbose - Return true if assembly output should contain comments.
+ ///
+ bool isVerbose() const { return VerboseAsm; }
+
+ /// getFunctionNumber - Return a unique ID for the current function.
+ ///
+ unsigned getFunctionNumber() const;
+
+ /// getObjFileLowering - Return information about object file lowering.
+ const TargetLoweringObjectFile &getObjFileLowering() const;
+
+ /// getTargetData - Return information about data layout.
+ const TargetData &getTargetData() const;
+
+ /// getCurrentSection() - Return the current section we are emitting to.
+ const MCSection *getCurrentSection() const;
+
+
+ //===------------------------------------------------------------------===//
+ // MachineFunctionPass Implementation.
+ //===------------------------------------------------------------------===//
+
+ /// getAnalysisUsage - Record analysis usage.
+ ///
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// doInitialization - Set up the AsmPrinter when we are working on a new
+ /// module. If your pass overrides this, it must make sure to explicitly
+ /// call this implementation.
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Shut down the asmprinter. If you override this in your
+ /// pass, you must make sure to call it explicitly.
+ bool doFinalization(Module &M);
+
+ /// runOnMachineFunction - Emit the specified function out to the
+ /// OutStreamer.
+ virtual bool runOnMachineFunction(MachineFunction &MF) {
+ SetupMachineFunction(MF);
+ EmitFunctionHeader();
+ EmitFunctionBody();
+ return false;
+ }
+
+ //===------------------------------------------------------------------===//
+ // Coarse grained IR lowering routines.
+ //===------------------------------------------------------------------===//
+
+ /// SetupMachineFunction - This should be called when a new MachineFunction
+ /// is being processed from runOnMachineFunction.
+ void SetupMachineFunction(MachineFunction &MF);
+
+ /// EmitFunctionHeader - This method emits the header for the current
+ /// function.
+ void EmitFunctionHeader();
+
+ /// EmitFunctionBody - This method emits the body and trailer for a
+ /// function.
+ void EmitFunctionBody();
+
+ void emitPrologLabel(const MachineInstr &MI);
+
+ enum CFIMoveType {
+ CFI_M_None,
+ CFI_M_EH,
+ CFI_M_Debug
+ };
+ CFIMoveType needsCFIMoves();
+
+ bool needsSEHMoves();
+
+ /// needsRelocationsForDwarfStringPool - Specifies whether the object format
+ /// expects to use relocations to refer to debug entries. Alternatively we
+ /// emit section offsets in bytes from the start of the string pool.
+ bool needsRelocationsForDwarfStringPool() const;
+
+ /// EmitConstantPool - Print to the current output stream assembly
+ /// representations of the constants in the constant pool MCP. This is
+ /// used to print out constants which have been "spilled to memory" by
+ /// the code generator.
+ ///
+ virtual void EmitConstantPool();
+
+ /// EmitJumpTableInfo - Print assembly representations of the jump tables
+ /// used by the current function to the current output stream.
+ ///
+ void EmitJumpTableInfo();
+
+ /// EmitGlobalVariable - Emit the specified global variable to the .s file.
+ virtual void EmitGlobalVariable(const GlobalVariable *GV);
+
+ /// EmitSpecialLLVMGlobal - Check to see if the specified global is a
+ /// special global used by LLVM. If so, emit it and return true, otherwise
+ /// do nothing and return false.
+ bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
+
+ /// EmitAlignment - Emit an alignment directive to the specified power of
+ /// two boundary. For example, if you pass in 3 here, you will get an 8
+ /// byte alignment. If a global value is specified, and if that global has
+ /// an explicit alignment requested, it will override the alignment request
+ /// if required for correctness.
+ ///
+ void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const;
+
+ /// EmitBasicBlockStart - This method prints the label for the specified
+ /// MachineBasicBlock, an alignment (if present) and a comment describing
+ /// it if appropriate.
+ void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
+
+ /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
+ void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0);
+
+
+ //===------------------------------------------------------------------===//
+ // Overridable Hooks
+ //===------------------------------------------------------------------===//
+
+ // Targets can, or in the case of EmitInstruction, must implement these to
+ // customize output.
+
+ /// EmitStartOfAsmFile - This virtual method can be overridden by targets
+ /// that want to emit something at the start of their file.
+ virtual void EmitStartOfAsmFile(Module &) {}
+
+ /// EmitEndOfAsmFile - This virtual method can be overridden by targets that
+ /// want to emit something at the end of their file.
+ virtual void EmitEndOfAsmFile(Module &) {}
+
+ /// EmitFunctionBodyStart - Targets can override this to emit stuff before
+ /// the first basic block in the function.
+ virtual void EmitFunctionBodyStart() {}
+
+ /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
+ /// the last basic block in the function.
+ virtual void EmitFunctionBodyEnd() {}
+
+ /// EmitInstruction - Targets should implement this to emit instructions.
+ virtual void EmitInstruction(const MachineInstr *) {
+ llvm_unreachable("EmitInstruction not implemented");
+ }
+
+ virtual void EmitFunctionEntryLabel();
+
+ virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+
+ /// EmitXXStructor - Targets can override this to change how global
+ /// constants that are part of a C++ static/global constructor list are
+ /// emitted.
+ virtual void EmitXXStructor(const Constant *CV) {
+ EmitGlobalConstant(CV);
+ }
+
+ /// isBlockOnlyReachableByFallthough - Return true if the basic block has
+ /// exactly one predecessor and the control transfer mechanism between
+ /// the predecessor and this block is a fall-through.
+ virtual bool
+ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const;
+
+ //===------------------------------------------------------------------===//
+ // Symbol Lowering Routines.
+ //===------------------------------------------------------------------===//
+ public:
+
+ /// GetTempSymbol - Return the MCSymbol corresponding to the assembler
+ /// temporary label with the specified stem and unique ID.
+ MCSymbol *GetTempSymbol(StringRef Name, unsigned ID) const;
+
+ /// GetTempSymbol - Return an assembler temporary label with the specified
+ /// stem.
+ MCSymbol *GetTempSymbol(StringRef Name) const;
+
+
+ /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
+ /// global value name as its base, with the specified suffix, and where the
+ /// symbol is forced to have private linkage if ForcePrivate is true.
+ MCSymbol *GetSymbolWithGlobalValueBase(const GlobalValue *GV,
+ StringRef Suffix,
+ bool ForcePrivate = true) const;
+
+ /// GetExternalSymbolSymbol - Return the MCSymbol for the specified
+ /// ExternalSymbol.
+ MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const;
+
+ /// GetCPISymbol - Return the symbol for the specified constant pool entry.
+ MCSymbol *GetCPISymbol(unsigned CPID) const;
+
+ /// GetJTISymbol - Return the symbol for the specified jump table entry.
+ MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const;
+
+ /// GetJTSetSymbol - Return the symbol for the specified jump table .set
+ /// FIXME: privatize to AsmPrinter.
+ MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const;
+
+ /// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
+ /// uses of the specified basic block.
+ MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
+ MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const;
+
+ //===------------------------------------------------------------------===//
+ // Emission Helper Routines.
+ //===------------------------------------------------------------------===//
+ public:
+ /// printOffset - This is just convenient handler for printing offsets.
+ void printOffset(int64_t Offset, raw_ostream &OS) const;
+
+ /// EmitInt8 - Emit a byte directive and value.
+ ///
+ void EmitInt8(int Value) const;
+
+ /// EmitInt16 - Emit a short directive and value.
+ ///
+ void EmitInt16(int Value) const;
+
+ /// EmitInt32 - Emit a long directive and value.
+ ///
+ void EmitInt32(int Value) const;
+
+ /// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
+ /// in bytes of the directive is specified by Size and Hi/Lo specify the
+ /// labels. This implicitly uses .set if it is available.
+ void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
+ unsigned Size) const;
+
+ /// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
+ /// where the size in bytes of the directive is specified by Size and Hi/Lo
+ /// specify the labels. This implicitly uses .set if it is available.
+ void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
+ const MCSymbol *Lo, unsigned Size) const;
+
+ /// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
+ /// where the size in bytes of the directive is specified by Size and Label
+ /// specifies the label. This implicitly uses .set if it is available.
+ void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
+ unsigned Size) const;
+
+ //===------------------------------------------------------------------===//
+ // Dwarf Emission Helper Routines
+ //===------------------------------------------------------------------===//
+
+ /// EmitSLEB128 - emit the specified signed leb128 value.
+ void EmitSLEB128(int Value, const char *Desc = 0) const;
+
+ /// EmitULEB128 - emit the specified unsigned leb128 value.
+ void EmitULEB128(unsigned Value, const char *Desc = 0,
+ unsigned PadTo = 0) const;
+
+ /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
+ void EmitCFAByte(unsigned Val) const;
+
+ /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an
+ /// encoding. If verbose assembly output is enabled, we output comments
+ /// describing the encoding. Desc is a string saying what the encoding is
+ /// specifying (e.g. "LSDA").
+ void EmitEncodingByte(unsigned Val, const char *Desc = 0) const;
+
+ /// 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;
+
+ /// 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
+ /// supports it (e.g. cygwin) or by emitting it as an offset from a label at
+ /// the start of the section.
+ ///
+ /// SectionLabel is a temporary label emitted at the start of the section
+ /// that Label lives in.
+ void EmitSectionOffset(const MCSymbol *Label,
+ const MCSymbol *SectionLabel) const;
+
+ /// getDebugValueLocation - Get location information encoded by DBG_VALUE
+ /// operands.
+ virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
+
+ /// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa
+ /// encoding specified.
+ virtual unsigned getISAEncoding() { return 0; }
+
+ /// EmitDwarfRegOp - Emit dwarf register operation.
+ virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const;
+
+ //===------------------------------------------------------------------===//
+ // Dwarf Lowering Routines
+ //===------------------------------------------------------------------===//
+
+ /// EmitCFIFrameMove - Emit frame instruction to describe the layout of the
+ /// frame.
+ void EmitCFIFrameMove(const MachineMove &Move) const;
+
+ //===------------------------------------------------------------------===//
+ // Inline Asm Support
+ //===------------------------------------------------------------------===//
+ public:
+ // These are hooks that targets can override to implement inline asm
+ // support. These should probably be moved out of AsmPrinter someday.
+
+ /// PrintSpecial - Print information related to the specified machine instr
+ /// that is independent of the operand, and may be independent of the instr
+ /// itself. This can be useful for portably encoding the comment character
+ /// or other bits of target-specific knowledge into the asmstrings. The
+ /// syntax used is ${:comment}. Targets can override this to add support
+ /// for their own strange codes.
+ virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
+ const char *Code) const;
+
+ /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
+ /// instruction, using the specified assembler variant. Targets should
+ /// override this to format as appropriate. This method can return true if
+ /// the operand is erroneous.
+ virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &OS);
+
+ /// PrintAsmMemoryOperand - Print the specified operand of MI, an INLINEASM
+ /// instruction, using the specified assembler variant as an address.
+ /// Targets should override this to format as appropriate. This method can
+ /// return true if the operand is erroneous.
+ virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &OS);
+
+ private:
+ /// Private state for PrintSpecial()
+ // Assign a unique ID to this machine instruction.
+ mutable const MachineInstr *LastMI;
+ mutable unsigned LastFn;
+ mutable unsigned Counter;
+ mutable unsigned SetCounter;
+
+ /// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
+ void EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = 0) const;
+
+ /// EmitInlineAsm - This method formats and emits the specified machine
+ /// instruction that is an inline asm.
+ void EmitInlineAsm(const MachineInstr *MI) const;
+
+ //===------------------------------------------------------------------===//
+ // Internal Implementation Details
+ //===------------------------------------------------------------------===//
+
+ /// EmitVisibility - This emits visibility information about symbol, if
+ /// this is suported by the target.
+ void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
+ bool IsDefinition = true) const;
+
+ void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const;
+
+ void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ const MachineBasicBlock *MBB,
+ unsigned uid) const;
+ void EmitLLVMUsedList(const Constant *List);
+ void EmitXXStructorList(const Constant *List, bool isCtor);
+ GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h b/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h
new file mode 100644
index 000000000000..2f76a6cc5583
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/CalcSpillWeights.h
@@ -0,0 +1,78 @@
+//===---------------- lib/CodeGen/CalcSpillWeights.h ------------*- 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_CALCSPILLWEIGHTS_H
+#define LLVM_CODEGEN_CALCSPILLWEIGHTS_H
+
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+ class LiveInterval;
+ class LiveIntervals;
+ class MachineLoopInfo;
+
+ /// normalizeSpillWeight - The spill weight of a live interval is computed as:
+ ///
+ /// (sum(use freq) + sum(def freq)) / (K + size)
+ ///
+ /// @param UseDefFreq Expected number of executed use and def instructions
+ /// per function call. Derived from block frequencies.
+ /// @param Size Size of live interval as returnexd by getSize()
+ ///
+ static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) {
+ // The constant 25 instructions is added to avoid depending too much on
+ // accidental SlotIndex gaps for small intervals. The effect is that small
+ // intervals have a spill weight that is mostly proportional to the number
+ // of uses, while large intervals get a spill weight that is closer to a use
+ // density.
+ return UseDefFreq / (Size + 25*SlotIndex::InstrDist);
+ }
+
+ /// VirtRegAuxInfo - Calculate auxiliary information for a virtual
+ /// register such as its spill weight and allocation hint.
+ class VirtRegAuxInfo {
+ MachineFunction &MF;
+ LiveIntervals &LIS;
+ const MachineLoopInfo &Loops;
+ DenseMap<unsigned, float> Hint;
+ public:
+ VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis,
+ const MachineLoopInfo &loops) :
+ MF(mf), LIS(lis), Loops(loops) {}
+
+ /// CalculateWeightAndHint - (re)compute li's spill weight and allocation
+ /// hint.
+ void CalculateWeightAndHint(LiveInterval &li);
+ };
+
+ /// CalculateSpillWeights - Compute spill weights for all virtual register
+ /// live intervals.
+ class CalculateSpillWeights : public MachineFunctionPass {
+ public:
+ static char ID;
+
+ CalculateSpillWeights() : MachineFunctionPass(ID) {
+ initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &au) const;
+
+ virtual bool runOnMachineFunction(MachineFunction &fn);
+
+ private:
+ /// Returns true if the given live interval is zero length.
+ bool isZeroLengthInterval(LiveInterval *li) const;
+ };
+
+}
+
+#endif // LLVM_CODEGEN_CALCSPILLWEIGHTS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h
new file mode 100644
index 000000000000..3afe3095d4f6
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -0,0 +1,325 @@
+//===-- llvm/CallingConvLower.h - Calling Conventions -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the CCState and CCValAssign classes, used for lowering
+// and implementing calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H
+#define LLVM_CODEGEN_CALLINGCONVLOWER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Target/TargetCallingConv.h"
+#include "llvm/CallingConv.h"
+
+namespace llvm {
+ class TargetRegisterInfo;
+ class TargetMachine;
+ class CCState;
+
+/// CCValAssign - Represent assignment of one arg/retval to a location.
+class CCValAssign {
+public:
+ enum LocInfo {
+ Full, // The value fills the full location.
+ SExt, // The value is sign extended in the location.
+ ZExt, // The value is zero extended in the location.
+ AExt, // The value is extended with undefined upper bits.
+ BCvt, // The value is bit-converted in the location.
+ VExt, // The value is vector-widened in the location.
+ // FIXME: Not implemented yet. Code that uses AExt to mean
+ // vector-widen should be fixed to use VExt instead.
+ Indirect // The location contains pointer to the value.
+ // TODO: a subset of the value is in the location.
+ };
+private:
+ /// ValNo - This is the value number begin assigned (e.g. an argument number).
+ unsigned ValNo;
+
+ /// Loc is either a stack offset or a register number.
+ unsigned Loc;
+
+ /// isMem - True if this is a memory loc, false if it is a register loc.
+ bool isMem : 1;
+
+ /// isCustom - True if this arg/retval requires special handling.
+ bool isCustom : 1;
+
+ /// Information about how the value is assigned.
+ LocInfo HTP : 6;
+
+ /// ValVT - The type of the value being assigned.
+ MVT ValVT;
+
+ /// LocVT - The type of the location being assigned to.
+ MVT LocVT;
+public:
+
+ static CCValAssign getReg(unsigned ValNo, MVT ValVT,
+ unsigned RegNo, MVT LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret.ValNo = ValNo;
+ Ret.Loc = RegNo;
+ Ret.isMem = false;
+ Ret.isCustom = false;
+ Ret.HTP = HTP;
+ Ret.ValVT = ValVT;
+ Ret.LocVT = LocVT;
+ return Ret;
+ }
+
+ static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT,
+ unsigned RegNo, MVT LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret = getReg(ValNo, ValVT, RegNo, LocVT, HTP);
+ Ret.isCustom = true;
+ return Ret;
+ }
+
+ static CCValAssign getMem(unsigned ValNo, MVT ValVT,
+ unsigned Offset, MVT LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret.ValNo = ValNo;
+ Ret.Loc = Offset;
+ Ret.isMem = true;
+ Ret.isCustom = false;
+ Ret.HTP = HTP;
+ Ret.ValVT = ValVT;
+ Ret.LocVT = LocVT;
+ return Ret;
+ }
+
+ static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT,
+ unsigned Offset, MVT LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret = getMem(ValNo, ValVT, Offset, LocVT, HTP);
+ Ret.isCustom = true;
+ return Ret;
+ }
+
+ unsigned getValNo() const { return ValNo; }
+ MVT getValVT() const { return ValVT; }
+
+ bool isRegLoc() const { return !isMem; }
+ bool isMemLoc() const { return isMem; }
+
+ bool needsCustom() const { return isCustom; }
+
+ unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
+ unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
+ MVT getLocVT() const { return LocVT; }
+
+ LocInfo getLocInfo() const { return HTP; }
+ bool isExtInLoc() const {
+ return (HTP == AExt || HTP == SExt || HTP == ZExt);
+ }
+
+};
+
+/// CCAssignFn - This function assigns a location for Val, updating State to
+/// reflect the change. It returns 'true' if it failed to handle Val.
+typedef bool CCAssignFn(unsigned ValNo, MVT ValVT,
+ MVT LocVT, CCValAssign::LocInfo LocInfo,
+ ISD::ArgFlagsTy ArgFlags, CCState &State);
+
+/// CCCustomFn - This function assigns a location for Val, possibly updating
+/// all args to reflect changes and indicates if it handled it. It must set
+/// isCustom if it handles the arg and returns true.
+typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT,
+ MVT &LocVT, CCValAssign::LocInfo &LocInfo,
+ ISD::ArgFlagsTy &ArgFlags, CCState &State);
+
+/// ParmContext - This enum tracks whether calling convention lowering is in
+/// the context of prologue or call generation. Not all backends make use of
+/// this information.
+typedef enum { Unknown, Prologue, Call } ParmContext;
+
+/// CCState - This class holds information needed while lowering arguments and
+/// return values. It captures which registers are already assigned and which
+/// stack slots are used. It provides accessors to allocate these values.
+class CCState {
+private:
+ CallingConv::ID CallingConv;
+ bool IsVarArg;
+ MachineFunction &MF;
+ const TargetMachine &TM;
+ const TargetRegisterInfo &TRI;
+ SmallVector<CCValAssign, 16> &Locs;
+ LLVMContext &Context;
+
+ unsigned StackOffset;
+ SmallVector<uint32_t, 16> UsedRegs;
+ unsigned FirstByValReg;
+ bool FirstByValRegValid;
+
+protected:
+ ParmContext CallOrPrologue;
+
+public:
+ CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
+ const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs,
+ LLVMContext &C);
+
+ void addLoc(const CCValAssign &V) {
+ Locs.push_back(V);
+ }
+
+ LLVMContext &getContext() const { return Context; }
+ const TargetMachine &getTarget() const { return TM; }
+ MachineFunction &getMachineFunction() const { return MF; }
+ CallingConv::ID getCallingConv() const { return CallingConv; }
+ bool isVarArg() const { return IsVarArg; }
+
+ unsigned getNextStackOffset() const { return StackOffset; }
+
+ /// isAllocated - Return true if the specified register (or an alias) is
+ /// allocated.
+ bool isAllocated(unsigned Reg) const {
+ return UsedRegs[Reg/32] & (1 << (Reg&31));
+ }
+
+ /// AnalyzeFormalArguments - Analyze an array of argument values,
+ /// incorporating info about the formals into this state.
+ void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
+ CCAssignFn Fn);
+
+ /// AnalyzeReturn - Analyze the returned values of a return,
+ /// incorporating info about the result values into this state.
+ void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ CCAssignFn Fn);
+
+ /// CheckReturn - Analyze the return values of a function, returning
+ /// true if the return can be performed without sret-demotion, and
+ /// false otherwise.
+ bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
+ CCAssignFn Fn);
+
+ /// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
+ /// incorporating info about the passed values into this state.
+ void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ CCAssignFn Fn);
+
+ /// AnalyzeCallOperands - Same as above except it takes vectors of types
+ /// and argument flags.
+ void AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs,
+ SmallVectorImpl<ISD::ArgFlagsTy> &Flags,
+ CCAssignFn Fn);
+
+ /// AnalyzeCallResult - Analyze the return values of a call,
+ /// incorporating info about the passed values into this state.
+ void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
+ CCAssignFn Fn);
+
+ /// AnalyzeCallResult - Same as above except it's specialized for calls which
+ /// produce a single value.
+ void AnalyzeCallResult(MVT VT, CCAssignFn Fn);
+
+ /// getFirstUnallocated - Return the first unallocated register in the set, or
+ /// NumRegs if they are all allocated.
+ unsigned getFirstUnallocated(const uint16_t *Regs, unsigned NumRegs) const {
+ for (unsigned i = 0; i != NumRegs; ++i)
+ if (!isAllocated(Regs[i]))
+ return i;
+ return NumRegs;
+ }
+
+ /// AllocateReg - Attempt to allocate one register. If it is not available,
+ /// return zero. Otherwise, return the register, marking it and any aliases
+ /// as allocated.
+ unsigned AllocateReg(unsigned Reg) {
+ if (isAllocated(Reg)) return 0;
+ MarkAllocated(Reg);
+ return Reg;
+ }
+
+ /// Version of AllocateReg with extra register to be shadowed.
+ unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) {
+ if (isAllocated(Reg)) return 0;
+ MarkAllocated(Reg);
+ MarkAllocated(ShadowReg);
+ return Reg;
+ }
+
+ /// AllocateReg - Attempt to allocate one of the specified registers. If none
+ /// are available, return zero. Otherwise, return the first one available,
+ /// marking it and any aliases as allocated.
+ unsigned AllocateReg(const uint16_t *Regs, unsigned NumRegs) {
+ unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+ if (FirstUnalloc == NumRegs)
+ return 0; // Didn't find the reg.
+
+ // Mark the register and any aliases as allocated.
+ unsigned Reg = Regs[FirstUnalloc];
+ MarkAllocated(Reg);
+ return Reg;
+ }
+
+ /// Version of AllocateReg with list of registers to be shadowed.
+ unsigned AllocateReg(const uint16_t *Regs, const uint16_t *ShadowRegs,
+ unsigned NumRegs) {
+ unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+ if (FirstUnalloc == NumRegs)
+ return 0; // Didn't find the reg.
+
+ // Mark the register and any aliases as allocated.
+ unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
+ MarkAllocated(Reg);
+ MarkAllocated(ShadowReg);
+ return Reg;
+ }
+
+ /// AllocateStack - Allocate a chunk of stack space with the specified size
+ /// and alignment.
+ unsigned AllocateStack(unsigned Size, unsigned Align) {
+ assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
+ StackOffset = ((StackOffset + Align-1) & ~(Align-1));
+ unsigned Result = StackOffset;
+ StackOffset += Size;
+ return Result;
+ }
+
+ /// Version of AllocateStack with extra register to be shadowed.
+ unsigned AllocateStack(unsigned Size, unsigned Align, unsigned ShadowReg) {
+ MarkAllocated(ShadowReg);
+ return AllocateStack(Size, Align);
+ }
+
+ // HandleByVal - Allocate a stack slot large enough to pass an argument by
+ // value. The size and alignment information of the argument is encoded in its
+ // parameter attribute.
+ void HandleByVal(unsigned ValNo, MVT ValVT,
+ MVT LocVT, CCValAssign::LocInfo LocInfo,
+ int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags);
+
+ // First GPR that carries part of a byval aggregate that's split
+ // between registers and memory.
+ unsigned getFirstByValReg() const { return FirstByValRegValid ? FirstByValReg : 0; }
+ void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; }
+ void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; }
+ bool isFirstByValRegValid() const { return FirstByValRegValid; }
+
+ ParmContext getCallOrPrologue() const { return CallOrPrologue; }
+
+private:
+ /// MarkAllocated - Mark a register and all of its aliases as allocated.
+ void MarkAllocated(unsigned Reg);
+};
+
+
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h
new file mode 100644
index 000000000000..ee1ed0779be4
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/DFAPacketizer.h
@@ -0,0 +1,147 @@
+//=- llvm/CodeGen/DFAPacketizer.h - DFA Packetizer for VLIW ---*- C++ -*-=====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This class implements a deterministic finite automaton (DFA) based
+// packetizing mechanism for VLIW architectures. It provides APIs to
+// determine whether there exists a legal mapping of instructions to
+// functional unit assignments in a packet. The DFA is auto-generated from
+// the target's Schedule.td file.
+//
+// A DFA consists of 3 major elements: states, inputs, and transitions. For
+// the packetizing mechanism, the input is the set of instruction classes for
+// a target. The state models all possible combinations of functional unit
+// consumption for a given set of instructions in a packet. A transition
+// models the addition of an instruction to a packet. In the DFA constructed
+// by this class, if an instruction can be added to a packet, then a valid
+// transition exists from the corresponding state. Invalid transitions
+// indicate that the instruction cannot be added to the current packet.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DFAPACKETIZER_H
+#define LLVM_CODEGEN_DFAPACKETIZER_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+class MCInstrDesc;
+class MachineInstr;
+class MachineLoopInfo;
+class MachineDominatorTree;
+class InstrItineraryData;
+class ScheduleDAGInstrs;
+class SUnit;
+
+class DFAPacketizer {
+private:
+ typedef std::pair<unsigned, unsigned> UnsignPair;
+ const InstrItineraryData *InstrItins;
+ int CurrentState;
+ const int (*DFAStateInputTable)[2];
+ const unsigned *DFAStateEntryTable;
+
+ // CachedTable is a map from <FromState, Input> to ToState.
+ DenseMap<UnsignPair, unsigned> CachedTable;
+
+ // ReadTable - Read the DFA transition table and update CachedTable.
+ void ReadTable(unsigned int state);
+
+public:
+ DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2],
+ const unsigned *SET);
+
+ // Reset the current state to make all resources available.
+ void clearResources() {
+ CurrentState = 0;
+ }
+
+ // canReserveResources - Check if the resources occupied by a MCInstrDesc
+ // are available in the current state.
+ bool canReserveResources(const llvm::MCInstrDesc *MID);
+
+ // reserveResources - Reserve the resources occupied by a MCInstrDesc and
+ // change the current state to reflect that change.
+ void reserveResources(const llvm::MCInstrDesc *MID);
+
+ // canReserveResources - Check if the resources occupied by a machine
+ // instruction are available in the current state.
+ bool canReserveResources(llvm::MachineInstr *MI);
+
+ // reserveResources - Reserve the resources occupied by a machine
+ // instruction and change the current state to reflect that change.
+ void reserveResources(llvm::MachineInstr *MI);
+};
+
+// VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The
+// packetizer works on machine basic blocks. For each instruction I in BB, the
+// packetizer consults the DFA to see if machine resources are available to
+// execute I. If so, the packetizer checks if I depends on any instruction J in
+// the current packet. If no dependency is found, I is added to current packet
+// and machine resource is marked as taken. If any dependency is found, a target
+// API call is made to prune the dependence.
+class VLIWPacketizerList {
+ const TargetMachine &TM;
+ const MachineFunction &MF;
+ const TargetInstrInfo *TII;
+
+ // Encapsulate data types not exposed to the target interface.
+ ScheduleDAGInstrs *SchedulerImpl;
+
+protected:
+ // Vector of instructions assigned to the current packet.
+ std::vector<MachineInstr*> CurrentPacketMIs;
+ // DFA resource tracker.
+ DFAPacketizer *ResourceTracker;
+ // Scheduling units.
+ std::vector<SUnit> SUnits;
+
+public:
+ VLIWPacketizerList(
+ MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
+ bool IsPostRA);
+
+ virtual ~VLIWPacketizerList();
+
+ // PacketizeMIs - Implement this API in the backend to bundle instructions.
+ void PacketizeMIs(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator BeginItr,
+ MachineBasicBlock::iterator EndItr);
+
+ // getResourceTracker - return ResourceTracker
+ DFAPacketizer *getResourceTracker() {return ResourceTracker;}
+
+ // addToPacket - Add MI to the current packet.
+ void addToPacket(MachineInstr *MI);
+
+ // endPacket - End the current packet.
+ void endPacket(MachineBasicBlock *MBB, MachineInstr *I);
+
+ // ignorePseudoInstruction - Ignore bundling of pseudo instructions.
+ bool ignorePseudoInstruction(MachineInstr *I, MachineBasicBlock *MBB);
+
+ // isSoloInstruction - return true if instruction I must end previous
+ // packet.
+ bool isSoloInstruction(MachineInstr *I);
+
+ // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
+ // together.
+ virtual bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
+ return false;
+ }
+
+ // isLegalToPruneDependencies - Is it legal to prune dependece between SUI
+ // and SUJ.
+ virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
+ return false;
+ }
+};
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/EdgeBundles.h b/contrib/llvm/include/llvm/CodeGen/EdgeBundles.h
new file mode 100644
index 000000000000..a1d29b1f02c5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/EdgeBundles.h
@@ -0,0 +1,69 @@
+//===-------- EdgeBundles.h - Bundles of CFG edges --------------*- c++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The EdgeBundles analysis forms equivalence classes of CFG edges such that all
+// edges leaving a machine basic block are in the same bundle, and all edges
+// leaving a basic block are in the same bundle.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_EDGEBUNDLES_H
+#define LLVM_CODEGEN_EDGEBUNDLES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntEqClasses.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+class EdgeBundles : public MachineFunctionPass {
+ const MachineFunction *MF;
+
+ /// EC - Each edge bundle is an equivalence class. The keys are:
+ /// 2*BB->getNumber() -> Ingoing bundle.
+ /// 2*BB->getNumber()+1 -> Outgoing bundle.
+ IntEqClasses EC;
+
+ /// Blocks - Map each bundle to a list of basic block numbers.
+ SmallVector<SmallVector<unsigned, 8>, 4> Blocks;
+
+public:
+ static char ID;
+ EdgeBundles() : MachineFunctionPass(ID) {}
+
+ /// getBundle - Return the ingoing (Out = false) or outgoing (Out = true)
+ /// bundle number for basic block #N
+ unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; }
+
+ /// getNumBundles - Return the total number of bundles in the CFG.
+ unsigned getNumBundles() const { return EC.getNumClasses(); }
+
+ /// getBlocks - Return an array of blocks that are connected to Bundle.
+ ArrayRef<unsigned> getBlocks(unsigned Bundle) { return Blocks[Bundle]; }
+
+ /// getMachineFunction - Return the last machine function computed.
+ const MachineFunction *getMachineFunction() const { return MF; }
+
+ /// view - Visualize the annotated bipartite CFG with Graphviz.
+ void view() const;
+
+private:
+ virtual bool runOnMachineFunction(MachineFunction&);
+ virtual void getAnalysisUsage(AnalysisUsage&) const;
+};
+
+/// Specialize WriteGraph, the standard implementation won't work.
+raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G,
+ bool ShortNames = false,
+ const Twine &Title = "");
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/FastISel.h b/contrib/llvm/include/llvm/CodeGen/FastISel.h
new file mode 100644
index 000000000000..e57c8b18c63e
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/FastISel.h
@@ -0,0 +1,394 @@
+//===-- FastISel.h - Definition of the FastISel class ---------------------===//
+//
+// 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 FastISel class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_FASTISEL_H
+#define LLVM_CODEGEN_FASTISEL_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+namespace llvm {
+
+class AllocaInst;
+class Constant;
+class ConstantFP;
+class FunctionLoweringInfo;
+class Instruction;
+class LoadInst;
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineFunction;
+class MachineInstr;
+class MachineFrameInfo;
+class MachineRegisterInfo;
+class TargetData;
+class TargetInstrInfo;
+class TargetLowering;
+class TargetMachine;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class User;
+class Value;
+
+/// FastISel - This is a fast-path instruction selection class that
+/// generates poor code and doesn't support illegal types or non-trivial
+/// lowering, but runs quickly.
+class FastISel {
+protected:
+ DenseMap<const Value *, unsigned> LocalValueMap;
+ FunctionLoweringInfo &FuncInfo;
+ MachineRegisterInfo &MRI;
+ MachineFrameInfo &MFI;
+ MachineConstantPool &MCP;
+ DebugLoc DL;
+ const TargetMachine &TM;
+ const TargetData &TD;
+ const TargetInstrInfo &TII;
+ const TargetLowering &TLI;
+ const TargetRegisterInfo &TRI;
+
+ /// The position of the last instruction for materializing constants
+ /// for use in the current block. It resets to EmitStartPt when it
+ /// makes sense (for example, it's usually profitable to avoid function
+ /// calls between the definition and the use)
+ MachineInstr *LastLocalValue;
+
+ /// The top most instruction in the current block that is allowed for
+ /// emitting local variables. LastLocalValue resets to EmitStartPt when
+ /// it makes sense (for example, on function calls)
+ MachineInstr *EmitStartPt;
+
+public:
+ /// getLastLocalValue - Return the position of the last instruction
+ /// emitted for materializing constants for use in the current block.
+ MachineInstr *getLastLocalValue() { return LastLocalValue; }
+
+ /// setLastLocalValue - Update the position of the last instruction
+ /// emitted for materializing constants for use in the current block.
+ void setLastLocalValue(MachineInstr *I) {
+ EmitStartPt = I;
+ LastLocalValue = I;
+ }
+
+ /// startNewBlock - Set the current block to which generated machine
+ /// instructions will be appended, and clear the local CSE map.
+ ///
+ void startNewBlock();
+
+ /// getCurDebugLoc() - Return current debug location information.
+ DebugLoc getCurDebugLoc() const { return DL; }
+
+ /// SelectInstruction - Do "fast" instruction selection for the given
+ /// LLVM IR instruction, and append generated machine instructions to
+ /// the current block. Return true if selection was successful.
+ ///
+ bool SelectInstruction(const Instruction *I);
+
+ /// SelectOperator - Do "fast" instruction selection for the given
+ /// LLVM IR operator (Instruction or ConstantExpr), and append
+ /// generated machine instructions to the current block. Return true
+ /// if selection was successful.
+ ///
+ bool SelectOperator(const User *I, unsigned Opcode);
+
+ /// getRegForValue - Create a virtual register and arrange for it to
+ /// be assigned the value for the given LLVM value.
+ unsigned getRegForValue(const Value *V);
+
+ /// lookUpRegForValue - Look up the value to see if its value is already
+ /// cached in a register. It may be defined by instructions across blocks or
+ /// defined locally.
+ unsigned lookUpRegForValue(const Value *V);
+
+ /// getRegForGEPIndex - This is a wrapper around getRegForValue that also
+ /// takes care of truncating or sign-extending the given getelementptr
+ /// index value.
+ std::pair<unsigned, bool> getRegForGEPIndex(const Value *V);
+
+ /// TryToFoldLoad - The specified machine instr operand is a vreg, and that
+ /// vreg is being provided by the specified load instruction. If possible,
+ /// try to fold the load as an operand to the instruction, returning true if
+ /// possible.
+ virtual bool TryToFoldLoad(MachineInstr * /*MI*/, unsigned /*OpNo*/,
+ const LoadInst * /*LI*/) {
+ return false;
+ }
+
+ /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions
+ /// into the current block.
+ void recomputeInsertPt();
+
+ struct SavePoint {
+ MachineBasicBlock::iterator InsertPt;
+ DebugLoc DL;
+ };
+
+ /// enterLocalValueArea - Prepare InsertPt to begin inserting instructions
+ /// into the local value area and return the old insert position.
+ SavePoint enterLocalValueArea();
+
+ /// leaveLocalValueArea - Reset InsertPt to the given old insert position.
+ void leaveLocalValueArea(SavePoint Old);
+
+ virtual ~FastISel();
+
+protected:
+ explicit FastISel(FunctionLoweringInfo &funcInfo);
+
+ /// TargetSelectInstruction - This method is called by target-independent
+ /// code when the normal FastISel process fails to select an instruction.
+ /// This gives targets a chance to emit code for anything that doesn't
+ /// fit into FastISel's framework. It returns true if it was successful.
+ ///
+ virtual bool
+ TargetSelectInstruction(const Instruction *I) = 0;
+
+ /// FastEmit_r - This method is called by target-independent code
+ /// to request that an instruction with the given type and opcode
+ /// be emitted.
+ virtual unsigned FastEmit_(MVT VT,
+ MVT RetVT,
+ unsigned Opcode);
+
+ /// FastEmit_r - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// register operand be emitted.
+ ///
+ virtual unsigned FastEmit_r(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill);
+
+ /// FastEmit_rr - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// register operands be emitted.
+ ///
+ virtual unsigned FastEmit_rr(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill);
+
+ /// FastEmit_ri - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// register and immediate operands be emitted.
+ ///
+ virtual unsigned FastEmit_ri(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm);
+
+ /// FastEmit_rf - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// register and floating-point immediate operands be emitted.
+ ///
+ virtual unsigned FastEmit_rf(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill,
+ const ConstantFP *FPImm);
+
+ /// FastEmit_rri - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// register and immediate operands be emitted.
+ ///
+ virtual unsigned FastEmit_rri(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill,
+ uint64_t Imm);
+
+ /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It first tries
+ /// to emit an instruction with an immediate operand using FastEmit_ri.
+ /// If that fails, it materializes the immediate into a register and try
+ /// FastEmit_rr instead.
+ unsigned FastEmit_ri_(MVT VT,
+ unsigned Opcode,
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm, MVT ImmType);
+
+ /// FastEmit_i - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// immediate operand be emitted.
+ virtual unsigned FastEmit_i(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ uint64_t Imm);
+
+ /// FastEmit_f - This method is called by target-independent code
+ /// to request that an instruction with the given type, opcode, and
+ /// floating-point immediate operand be emitted.
+ virtual unsigned FastEmit_f(MVT VT,
+ MVT RetVT,
+ unsigned Opcode,
+ const ConstantFP *FPImm);
+
+ /// FastEmitInst_ - Emit a MachineInstr with no operands and a
+ /// result register in the given register class.
+ ///
+ unsigned FastEmitInst_(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC);
+
+ /// FastEmitInst_r - Emit a MachineInstr with one register operand
+ /// and a result register in the given register class.
+ ///
+ unsigned FastEmitInst_r(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill);
+
+ /// FastEmitInst_rr - Emit a MachineInstr with two register operands
+ /// and a result register in the given register class.
+ ///
+ unsigned FastEmitInst_rr(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill);
+
+ /// FastEmitInst_rrr - Emit a MachineInstr with three register operands
+ /// and a result register in the given register class.
+ ///
+ unsigned FastEmitInst_rrr(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill,
+ unsigned Op2, bool Op2IsKill);
+
+ /// FastEmitInst_ri - Emit a MachineInstr with a register operand,
+ /// an immediate, and a result register in the given register class.
+ ///
+ unsigned FastEmitInst_ri(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm);
+
+ /// FastEmitInst_rii - Emit a MachineInstr with one register operand
+ /// and two immediate operands.
+ ///
+ unsigned FastEmitInst_rii(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ uint64_t Imm1, uint64_t Imm2);
+
+ /// FastEmitInst_rf - Emit a MachineInstr with two register operands
+ /// and a result register in the given register class.
+ ///
+ unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ const ConstantFP *FPImm);
+
+ /// FastEmitInst_rri - Emit a MachineInstr with two register operands,
+ /// an immediate, and a result register in the given register class.
+ ///
+ unsigned FastEmitInst_rri(unsigned MachineInstOpcode,
+ const TargetRegisterClass *RC,
+ unsigned Op0, bool Op0IsKill,
+ unsigned Op1, bool Op1IsKill,
+ uint64_t Imm);
+
+ /// FastEmitInst_i - Emit a MachineInstr with a single immediate
+ /// operand, and a result register in the given register class.
+ unsigned FastEmitInst_i(unsigned MachineInstrOpcode,
+ const TargetRegisterClass *RC,
+ uint64_t Imm);
+
+ /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands.
+ unsigned FastEmitInst_ii(unsigned MachineInstrOpcode,
+ const TargetRegisterClass *RC,
+ uint64_t Imm1, uint64_t Imm2);
+
+ /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg
+ /// from a specified index of a superregister to a specified type.
+ unsigned FastEmitInst_extractsubreg(MVT RetVT,
+ unsigned Op0, bool Op0IsKill,
+ uint32_t Idx);
+
+ /// FastEmitZExtFromI1 - Emit MachineInstrs to compute the value of Op
+ /// with all but the least significant bit set to zero.
+ unsigned FastEmitZExtFromI1(MVT VT,
+ unsigned Op0, bool Op0IsKill);
+
+ /// FastEmitBranch - Emit an unconditional branch to the given block,
+ /// unless it is the immediate (fall-through) successor, and update
+ /// the CFG.
+ void FastEmitBranch(MachineBasicBlock *MBB, DebugLoc DL);
+
+ void UpdateValueMap(const Value* I, unsigned Reg, unsigned NumRegs = 1);
+
+ unsigned createResultReg(const TargetRegisterClass *RC);
+
+ /// TargetMaterializeConstant - Emit a constant in a register using
+ /// target-specific logic, such as constant pool loads.
+ virtual unsigned TargetMaterializeConstant(const Constant* C) {
+ return 0;
+ }
+
+ /// TargetMaterializeAlloca - Emit an alloca address in a register using
+ /// target-specific logic.
+ virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) {
+ return 0;
+ }
+
+ virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) {
+ return 0;
+ }
+
+private:
+ bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
+
+ bool SelectFNeg(const User *I);
+
+ bool SelectGetElementPtr(const User *I);
+
+ bool SelectCall(const User *I);
+
+ bool SelectBitCast(const User *I);
+
+ bool SelectCast(const User *I, unsigned Opcode);
+
+ bool SelectExtractValue(const User *I);
+
+ bool SelectInsertValue(const User *I);
+
+ /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
+ /// Emit code to ensure constants are copied into registers when needed.
+ /// Remember the virtual registers that need to be added to the Machine PHI
+ /// nodes as input. We cannot just directly add them, because expansion
+ /// might result in multiple MBB's for one BB. As such, the start of the
+ /// BB might correspond to a different MBB than the end.
+ bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
+
+ /// materializeRegForValue - Helper for getRegForVale. This function is
+ /// called when the value isn't already available in a register and must
+ /// be materialized with new instructions.
+ unsigned materializeRegForValue(const Value *V, MVT VT);
+
+ /// flushLocalValueMap - clears LocalValueMap and moves the area for the
+ /// new local variables to the beginning of the block. It helps to avoid
+ /// spilling cached variables across heavy instructions like calls.
+ void flushLocalValueMap();
+
+ /// 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);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
new file mode 100644
index 000000000000..8cf22eca4fa6
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -0,0 +1,231 @@
+//===-- FunctionLoweringInfo.h - Lower functions from LLVM IR to CodeGen --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This implements routines for translating functions from LLVM IR into
+// Machine IR.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+#include "llvm/ADT/IndexedMap.h"
+#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/Support/CallSite.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <vector>
+
+namespace llvm {
+
+class AllocaInst;
+class BasicBlock;
+class CallInst;
+class Function;
+class GlobalVariable;
+class Instruction;
+class MachineInstr;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRegisterInfo;
+class TargetLowering;
+class Value;
+
+//===--------------------------------------------------------------------===//
+/// FunctionLoweringInfo - This contains information that is global to a
+/// function that is used when lowering a region of the function.
+///
+class FunctionLoweringInfo {
+public:
+ const TargetLowering &TLI;
+ const Function *Fn;
+ MachineFunction *MF;
+ MachineRegisterInfo *RegInfo;
+ BranchProbabilityInfo *BPI;
+ /// CanLowerReturn - true iff the function's return value can be lowered to
+ /// registers.
+ bool CanLowerReturn;
+
+ /// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg
+ /// allocated to hold a pointer to the hidden sret parameter.
+ unsigned DemoteRegister;
+
+ /// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
+ DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
+
+ /// ValueMap - Since we emit code for the function a basic block at a time,
+ /// we must remember which virtual registers hold the values for
+ /// cross-basic-block values.
+ DenseMap<const Value*, unsigned> ValueMap;
+
+ /// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
+ /// the entry block. This allows the allocas to be efficiently referenced
+ /// anywhere in the function.
+ DenseMap<const AllocaInst*, int> StaticAllocaMap;
+
+ /// ByValArgFrameIndexMap - Keep track of frame indices for byval arguments.
+ DenseMap<const Argument*, int> ByValArgFrameIndexMap;
+
+ /// ArgDbgValues - A list of DBG_VALUE instructions created during isel for
+ /// function arguments that are inserted after scheduling is completed.
+ SmallVector<MachineInstr*, 8> ArgDbgValues;
+
+ /// RegFixups - Registers which need to be replaced after isel is done.
+ DenseMap<unsigned, unsigned> RegFixups;
+
+ /// MBB - The current block.
+ MachineBasicBlock *MBB;
+
+ /// MBB - The current insert position inside the current block.
+ MachineBasicBlock::iterator InsertPt;
+
+#ifndef NDEBUG
+ SmallPtrSet<const Instruction *, 8> CatchInfoLost;
+ SmallPtrSet<const Instruction *, 8> CatchInfoFound;
+#endif
+
+ struct LiveOutInfo {
+ unsigned NumSignBits : 31;
+ bool IsValid : 1;
+ APInt KnownOne, KnownZero;
+ LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
+ KnownZero(1, 0) {}
+ };
+
+ /// VisitedBBs - The set of basic blocks visited thus far by instruction
+ /// selection.
+ SmallPtrSet<const BasicBlock*, 4> VisitedBBs;
+
+ /// PHINodesToUpdate - A list of phi instructions whose operand list will
+ /// be updated after processing the current basic block.
+ /// TODO: This isn't per-function state, it's per-basic-block state. But
+ /// there's no other convenient place for it to live right now.
+ std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
+
+ explicit FunctionLoweringInfo(const TargetLowering &TLI);
+
+ /// set - Initialize this FunctionLoweringInfo with the given Function
+ /// and its associated MachineFunction.
+ ///
+ void set(const Function &Fn, MachineFunction &MF);
+
+ /// clear - Clear out all the function-specific state. This returns this
+ /// FunctionLoweringInfo to an empty state, ready to be used for a
+ /// different function.
+ void clear();
+
+ /// isExportedInst - Return true if the specified value is an instruction
+ /// exported from its block.
+ bool isExportedInst(const Value *V) {
+ return ValueMap.count(V);
+ }
+
+ unsigned CreateReg(EVT VT);
+
+ unsigned CreateRegs(Type *Ty);
+
+ unsigned InitializeRegForValue(const Value *V) {
+ unsigned &R = ValueMap[V];
+ assert(R == 0 && "Already initialized this value register!");
+ return R = CreateRegs(V->getType());
+ }
+
+ /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
+ /// register is a PHI destination and the PHI's LiveOutInfo is not valid.
+ const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg) {
+ if (!LiveOutRegInfo.inBounds(Reg))
+ return NULL;
+
+ const LiveOutInfo *LOI = &LiveOutRegInfo[Reg];
+ if (!LOI->IsValid)
+ return NULL;
+
+ return LOI;
+ }
+
+ /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
+ /// register is a PHI destination and the PHI's LiveOutInfo is not valid. If
+ /// the register's LiveOutInfo is for a smaller bit width, it is extended to
+ /// the larger bit width by zero extension. The bit width must be no smaller
+ /// than the LiveOutInfo's existing bit width.
+ const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth);
+
+ /// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
+ void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
+ const APInt &KnownZero, const APInt &KnownOne) {
+ // Only install this information if it tells us something.
+ if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0)
+ return;
+
+ LiveOutRegInfo.grow(Reg);
+ LiveOutInfo &LOI = LiveOutRegInfo[Reg];
+ LOI.NumSignBits = NumSignBits;
+ LOI.KnownOne = KnownOne;
+ LOI.KnownZero = KnownZero;
+ }
+
+ /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
+ /// register based on the LiveOutInfo of its operands.
+ void ComputePHILiveOutRegInfo(const PHINode*);
+
+ /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be
+ /// called when a block is visited before all of its predecessors.
+ void InvalidatePHILiveOutRegInfo(const PHINode *PN) {
+ // PHIs with no uses have no ValueMap entry.
+ DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN);
+ if (It == ValueMap.end())
+ return;
+
+ unsigned Reg = It->second;
+ LiveOutRegInfo.grow(Reg);
+ LiveOutRegInfo[Reg].IsValid = false;
+ }
+
+ /// setArgumentFrameIndex - Record frame index for the byval
+ /// argument.
+ void setArgumentFrameIndex(const Argument *A, int FI);
+
+ /// getArgumentFrameIndex - Get frame index for the byval argument.
+ int getArgumentFrameIndex(const Argument *A);
+
+private:
+ /// LiveOutRegInfo - Information about live out vregs.
+ IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
+};
+
+/// ComputeUsesVAFloatArgument - Determine if any floating-point values are
+/// being passed to this variadic function, and set the MachineModuleInfo's
+/// usesVAFloatArgument flag if so. This flag is used to emit an undefined
+/// reference to _fltused on Windows, which will link in MSVCRT's
+/// floating-point support.
+void ComputeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo *MMI);
+
+/// AddCatchInfo - Extract the personality and type infos from an eh.selector
+/// call, and add them to the specified machine basic block.
+void AddCatchInfo(const CallInst &I,
+ MachineModuleInfo *MMI, MachineBasicBlock *MBB);
+
+/// AddLandingPadInfo - Extract the exception handling information from the
+/// landingpad instruction and add them to the specified machine module info.
+void AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
+ MachineBasicBlock *MBB);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadata.h b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h
new file mode 100644
index 000000000000..45469ed7de80
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -0,0 +1,193 @@
+//===-- GCMetadata.h - Garbage collector metadata ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the GCFunctionInfo and GCModuleInfo classes, which are
+// used as a communication channel from the target code generator to the target
+// garbage collectors. This interface allows code generators and garbage
+// collectors to be developed independently.
+//
+// The GCFunctionInfo class logs the data necessary to build a type accurate
+// stack map. The code generator outputs:
+//
+// - Safe points as specified by the GCStrategy's NeededSafePoints.
+// - Stack offsets for GC roots, as specified by calls to llvm.gcroot
+//
+// As a refinement, liveness analysis calculates the set of live roots at each
+// safe point. Liveness analysis is not presently performed by the code
+// generator, so all roots are assumed live.
+//
+// GCModuleInfo simply collects GCFunctionInfo instances for each Function as
+// they are compiled. This accretion is necessary for collectors which must emit
+// a stack map for the compilation unit as a whole. Therefore, GCFunctionInfo
+// outlives the MachineFunction from which it is derived and must not refer to
+// any code generator data structures.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/DebugLoc.h"
+
+namespace llvm {
+ class AsmPrinter;
+ class GCStrategy;
+ class Constant;
+ class MCSymbol;
+
+ namespace GC {
+ /// PointKind - The type of a collector-safe point.
+ ///
+ enum PointKind {
+ Loop, //< Instr is a loop (backwards branch).
+ Return, //< Instr is a return instruction.
+ PreCall, //< Instr is a call instruction.
+ PostCall //< Instr is the return address of a call.
+ };
+ }
+
+ /// GCPoint - Metadata for a collector-safe point in machine code.
+ ///
+ struct GCPoint {
+ GC::PointKind Kind; //< The kind of the safe point.
+ MCSymbol *Label; //< A label.
+ DebugLoc Loc;
+
+ GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
+ : Kind(K), Label(L), Loc(DL) {}
+ };
+
+ /// GCRoot - Metadata for a pointer to an object managed by the garbage
+ /// collector.
+ struct GCRoot {
+ int Num; //< Usually a frame index.
+ int StackOffset; //< Offset from the stack pointer.
+ const Constant *Metadata;//< Metadata straight from the call to llvm.gcroot.
+
+ GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
+ };
+
+
+ /// GCFunctionInfo - Garbage collection metadata for a single function.
+ ///
+ class GCFunctionInfo {
+ public:
+ typedef std::vector<GCPoint>::iterator iterator;
+ typedef std::vector<GCRoot>::iterator roots_iterator;
+ typedef std::vector<GCRoot>::const_iterator live_iterator;
+
+ private:
+ const Function &F;
+ GCStrategy &S;
+ uint64_t FrameSize;
+ std::vector<GCRoot> Roots;
+ std::vector<GCPoint> SafePoints;
+
+ // FIXME: Liveness. A 2D BitVector, perhaps?
+ //
+ // BitVector Liveness;
+ //
+ // bool islive(int point, int root) =
+ // Liveness[point * SafePoints.size() + root]
+ //
+ // The bit vector is the more compact representation where >3.2% of roots
+ // are live per safe point (1.5% on 64-bit hosts).
+
+ public:
+ GCFunctionInfo(const Function &F, GCStrategy &S);
+ ~GCFunctionInfo();
+
+ /// getFunction - Return the function to which this metadata applies.
+ ///
+ const Function &getFunction() const { return F; }
+
+ /// getStrategy - Return the GC strategy for the function.
+ ///
+ GCStrategy &getStrategy() { return S; }
+
+ /// addStackRoot - Registers a root that lives on the stack. Num is the
+ /// stack object ID for the alloca (if the code generator is
+ // using MachineFrameInfo).
+ void addStackRoot(int Num, const Constant *Metadata) {
+ Roots.push_back(GCRoot(Num, Metadata));
+ }
+
+ /// 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).
+ void addSafePoint(GC::PointKind Kind, MCSymbol *Label, DebugLoc DL) {
+ SafePoints.push_back(GCPoint(Kind, Label, DL));
+ }
+
+ /// getFrameSize/setFrameSize - Records the function's frame size.
+ ///
+ uint64_t getFrameSize() const { return FrameSize; }
+ void setFrameSize(uint64_t S) { FrameSize = S; }
+
+ /// begin/end - Iterators for safe points.
+ ///
+ iterator begin() { return SafePoints.begin(); }
+ iterator end() { return SafePoints.end(); }
+ size_t size() const { return SafePoints.size(); }
+
+ /// roots_begin/roots_end - Iterators for all roots in the function.
+ ///
+ roots_iterator roots_begin() { return Roots.begin(); }
+ roots_iterator roots_end () { return Roots.end(); }
+ size_t roots_size() const { return Roots.size(); }
+
+ /// live_begin/live_end - Iterators for live roots at a given safe point.
+ ///
+ live_iterator live_begin(const iterator &p) { return roots_begin(); }
+ live_iterator live_end (const iterator &p) { return roots_end(); }
+ size_t live_size(const iterator &p) const { return roots_size(); }
+ };
+
+
+ /// GCModuleInfo - Garbage collection metadata for a whole module.
+ ///
+ class GCModuleInfo : public ImmutablePass {
+ typedef StringMap<GCStrategy*> strategy_map_type;
+ typedef std::vector<GCStrategy*> list_type;
+ typedef DenseMap<const Function*,GCFunctionInfo*> finfo_map_type;
+
+ strategy_map_type StrategyMap;
+ list_type StrategyList;
+ finfo_map_type FInfoMap;
+
+ GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name);
+
+ public:
+ typedef list_type::const_iterator iterator;
+
+ static char ID;
+
+ GCModuleInfo();
+ ~GCModuleInfo();
+
+ /// clear - Resets the pass. The metadata deleter pass calls this.
+ ///
+ void clear();
+
+ /// begin/end - Iterators for used strategies.
+ ///
+ iterator begin() const { return StrategyList.begin(); }
+ iterator end() const { return StrategyList.end(); }
+
+ /// get - Look up function metadata.
+ ///
+ GCFunctionInfo &getFunctionInfo(const Function &F);
+ };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h b/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
new file mode 100644
index 000000000000..17a265300000
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/GCMetadataPrinter.h
@@ -0,0 +1,73 @@
+//===-- llvm/CodeGen/GCMetadataPrinter.h - Prints asm GC tables -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The abstract base class GCMetadataPrinter supports writing GC metadata tables
+// as assembly code. This is a separate class from GCStrategy in order to allow
+// users of the LLVM JIT to avoid linking with the AsmWriter.
+//
+// Subclasses of GCMetadataPrinter must be registered using the
+// GCMetadataPrinterRegistry. This is separate from the GCStrategy itself
+// because these subclasses are logically plugins for the AsmWriter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCMETADATAPRINTER_H
+#define LLVM_CODEGEN_GCMETADATAPRINTER_H
+
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/GCStrategy.h"
+#include "llvm/Support/Registry.h"
+
+namespace llvm {
+
+ class GCMetadataPrinter;
+
+ /// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
+ /// defaults from Registry.
+ typedef Registry<GCMetadataPrinter> GCMetadataPrinterRegistry;
+
+ /// GCMetadataPrinter - Emits GC metadata as assembly code.
+ ///
+ class GCMetadataPrinter {
+ public:
+ typedef GCStrategy::list_type list_type;
+ typedef GCStrategy::iterator iterator;
+
+ private:
+ GCStrategy *S;
+
+ friend class AsmPrinter;
+
+ protected:
+ // May only be subclassed.
+ GCMetadataPrinter();
+
+ // Do not implement.
+ GCMetadataPrinter(const GCMetadataPrinter &);
+ GCMetadataPrinter &operator=(const GCMetadataPrinter &);
+
+ public:
+ GCStrategy &getStrategy() { return *S; }
+ const Module &getModule() const { return S->getModule(); }
+
+ /// begin/end - Iterate over the collected function metadata.
+ iterator begin() { return S->begin(); }
+ iterator end() { return S->end(); }
+
+ /// beginAssembly/finishAssembly - Emit module metadata as assembly code.
+ virtual void beginAssembly(AsmPrinter &AP);
+
+ virtual void finishAssembly(AsmPrinter &AP);
+
+ virtual ~GCMetadataPrinter();
+ };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/GCStrategy.h b/contrib/llvm/include/llvm/CodeGen/GCStrategy.h
new file mode 100644
index 000000000000..1cbd36abfbf8
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/GCStrategy.h
@@ -0,0 +1,153 @@
+//===-- llvm/CodeGen/GCStrategy.h - Garbage collection ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// GCStrategy coordinates code generation algorithms and implements some itself
+// in order to generate code compatible with a target code generator as
+// specified in a function's 'gc' attribute. Algorithms are enabled by setting
+// flags in a subclass's constructor, and some virtual methods can be
+// overridden.
+//
+// When requested, the GCStrategy will be populated with data about each
+// function which uses it. Specifically:
+//
+// - Safe points
+// Garbage collection is generally only possible at certain points in code.
+// GCStrategy can request that the collector insert such points:
+//
+// - At and after any call to a subroutine
+// - Before returning from the current function
+// - Before backwards branches (loops)
+//
+// - Roots
+// When a reference to a GC-allocated object exists on the stack, it must be
+// stored in an alloca registered with llvm.gcoot.
+//
+// This information can used to emit the metadata tables which are required by
+// the target garbage collector runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCSTRATEGY_H
+#define LLVM_CODEGEN_GCSTRATEGY_H
+
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/Registry.h"
+#include <string>
+
+namespace llvm {
+
+ class GCStrategy;
+
+ /// The GC strategy registry uses all the defaults from Registry.
+ ///
+ typedef Registry<GCStrategy> GCRegistry;
+
+ /// GCStrategy describes a garbage collector algorithm's code generation
+ /// requirements, and provides overridable hooks for those needs which cannot
+ /// be abstractly described.
+ class GCStrategy {
+ public:
+ typedef std::vector<GCFunctionInfo*> list_type;
+ typedef list_type::iterator iterator;
+
+ private:
+ friend class GCModuleInfo;
+ const Module *M;
+ std::string Name;
+
+ list_type Functions;
+
+ protected:
+ unsigned NeededSafePoints; //< Bitmask of required safe points.
+ bool CustomReadBarriers; //< Default is to insert loads.
+ bool CustomWriteBarriers; //< Default is to insert stores.
+ bool CustomRoots; //< Default is to pass through to backend.
+ bool CustomSafePoints; //< Default is to use NeededSafePoints
+ // to find safe points.
+ bool InitRoots; //< If set, roots are nulled during lowering.
+ bool UsesMetadata; //< If set, backend must emit metadata tables.
+
+ public:
+ GCStrategy();
+
+ virtual ~GCStrategy();
+
+
+ /// getName - The name of the GC strategy, for debugging.
+ ///
+ const std::string &getName() const { return Name; }
+
+ /// getModule - The module within which the GC strategy is operating.
+ ///
+ const Module &getModule() const { return *M; }
+
+ /// needsSafePoitns - True if safe points of any kind are required. By
+ // default, none are recorded.
+ bool needsSafePoints() const {
+ return CustomSafePoints || NeededSafePoints != 0;
+ }
+
+ /// needsSafePoint(Kind) - True if the given kind of safe point is
+ // required. By default, none are recorded.
+ bool needsSafePoint(GC::PointKind Kind) const {
+ return (NeededSafePoints & 1 << Kind) != 0;
+ }
+
+ /// customWriteBarrier - By default, write barriers are replaced with simple
+ /// store instructions. If true, then
+ /// performCustomLowering must instead lower them.
+ bool customWriteBarrier() const { return CustomWriteBarriers; }
+
+ /// customReadBarrier - By default, read barriers are replaced with simple
+ /// load instructions. If true, then
+ /// performCustomLowering must instead lower them.
+ bool customReadBarrier() const { return CustomReadBarriers; }
+
+ /// customRoots - By default, roots are left for the code generator so it
+ /// can generate a stack map. If true, then
+ // performCustomLowering must delete them.
+ bool customRoots() const { return CustomRoots; }
+
+ /// customSafePoints - By default, the GC analysis will find safe
+ /// points according to NeededSafePoints. If true,
+ /// then findCustomSafePoints must create them.
+ bool customSafePoints() const { return CustomSafePoints; }
+
+ /// initializeRoots - If set, gcroot intrinsics should initialize their
+ // allocas to null before the first use. This is
+ // necessary for most GCs and is enabled by default.
+ bool initializeRoots() const { return InitRoots; }
+
+ /// usesMetadata - If set, appropriate metadata tables must be emitted by
+ /// the back-end (assembler, JIT, or otherwise).
+ bool usesMetadata() const { return UsesMetadata; }
+
+ /// begin/end - Iterators for function metadata.
+ ///
+ iterator begin() { return Functions.begin(); }
+ iterator end() { return Functions.end(); }
+
+ /// insertFunctionMetadata - Creates metadata for a function.
+ ///
+ GCFunctionInfo *insertFunctionInfo(const Function &F);
+
+ /// initializeCustomLowering/performCustomLowering - If any of the actions
+ /// are set to custom, performCustomLowering must be overriden to transform
+ /// the corresponding actions to LLVM IR. initializeCustomLowering is
+ /// optional to override. These are the only GCStrategy methods through
+ /// which the LLVM IR can be modified.
+ virtual bool initializeCustomLowering(Module &F);
+ virtual bool performCustomLowering(Function &F);
+ virtual bool findCustomSafePoints(GCFunctionInfo& FI, MachineFunction& MF);
+ };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/GCs.h b/contrib/llvm/include/llvm/CodeGen/GCs.h
new file mode 100644
index 000000000000..c407b6167485
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/GCs.h
@@ -0,0 +1,35 @@
+//===-- GCs.h - Garbage collector linkage hacks ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains hack functions to force linking in the GC components.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GCS_H
+#define LLVM_CODEGEN_GCS_H
+
+namespace llvm {
+ class GCStrategy;
+ class GCMetadataPrinter;
+
+ /// FIXME: Collector instances are not useful on their own. These no longer
+ /// serve any purpose except to link in the plugins.
+
+ /// Creates an ocaml-compatible garbage collector.
+ void linkOcamlGC();
+
+ /// Creates an ocaml-compatible metadata printer.
+ void linkOcamlGCPrinter();
+
+ /// Creates a shadow stack garbage collector. This collector requires no code
+ /// generator support.
+ void linkShadowStackGC();
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
new file mode 100644
index 000000000000..ab8ab5dd7b4e
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -0,0 +1,809 @@
+//===-- llvm/CodeGen/ISDOpcodes.h - CodeGen opcodes -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares codegen opcodes and related utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ISDOPCODES_H
+#define LLVM_CODEGEN_ISDOPCODES_H
+
+namespace llvm {
+
+/// ISD namespace - This namespace contains an enum which represents all of the
+/// SelectionDAG node types and value types.
+///
+namespace ISD {
+
+ //===--------------------------------------------------------------------===//
+ /// ISD::NodeType enum - This enum defines the target-independent operators
+ /// for a SelectionDAG.
+ ///
+ /// Targets may also define target-dependent operator codes for SDNodes. For
+ /// example, on x86, these are the enum values in the X86ISD namespace.
+ /// Targets should aim to use target-independent operators to model their
+ /// instruction sets as much as possible, and only use target-dependent
+ /// operators when they have special requirements.
+ ///
+ /// Finally, during and after selection proper, SNodes may use special
+ /// operator codes that correspond directly with MachineInstr opcodes. These
+ /// are used to represent selected instructions. See the isMachineOpcode()
+ /// and getMachineOpcode() member functions of SDNode.
+ ///
+ enum NodeType {
+ // DELETED_NODE - This is an illegal value that is used to catch
+ // errors. This opcode is not a legal opcode for any node.
+ DELETED_NODE,
+
+ // EntryToken - This is the marker used to indicate the start of the region.
+ EntryToken,
+
+ // TokenFactor - This node takes multiple tokens as input and produces a
+ // single token result. This is used to represent the fact that the operand
+ // operators are independent of each other.
+ TokenFactor,
+
+ // AssertSext, AssertZext - These nodes record if a register contains a
+ // value that has already been zero or sign extended from a narrower type.
+ // These nodes take two operands. The first is the node that has already
+ // been extended, and the second is a value type node indicating the width
+ // of the extension
+ AssertSext, AssertZext,
+
+ // Various leaf nodes.
+ BasicBlock, VALUETYPE, CONDCODE, Register, RegisterMask,
+ Constant, ConstantFP,
+ GlobalAddress, GlobalTLSAddress, FrameIndex,
+ JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
+
+ // The address of the GOT
+ GLOBAL_OFFSET_TABLE,
+
+ // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+ // llvm.returnaddress on the DAG. These nodes take one operand, the index
+ // of the frame or return address to return. An index of zero corresponds
+ // to the current function's frame or return address, an index of one to the
+ // parent's frame or return address, and so on.
+ FRAMEADDR, RETURNADDR,
+
+ // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+ // first (possible) on-stack argument. This is needed for correct stack
+ // adjustment during unwind.
+ FRAME_TO_ARGS_OFFSET,
+
+ // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
+ // address of the exception block on entry to an landing pad block.
+ EXCEPTIONADDR,
+
+ // RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
+ // address of the Language Specific Data Area for the enclosing function.
+ LSDAADDR,
+
+ // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
+ // the selection index of the exception thrown.
+ EHSELECTION,
+
+ // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+ // 'eh_return' gcc dwarf builtin, which is used to return from
+ // exception. The general meaning is: adjust stack by OFFSET and pass
+ // execution to HANDLER. Many platform-related details also :)
+ EH_RETURN,
+
+ // RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
+ // This corresponds to the eh.sjlj.setjmp intrinsic.
+ // It takes an input chain and a pointer to the jump buffer as inputs
+ // and returns an outchain.
+ EH_SJLJ_SETJMP,
+
+ // OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
+ // This corresponds to the eh.sjlj.longjmp intrinsic.
+ // It takes an input chain and a pointer to the jump buffer as inputs
+ // and returns an outchain.
+ EH_SJLJ_LONGJMP,
+
+ // TargetConstant* - Like Constant*, but the DAG does not do any folding,
+ // simplification, or lowering of the constant. They are used for constants
+ // which are known to fit in the immediate fields of their users, or for
+ // carrying magic numbers which are not values which need to be materialized
+ // in registers.
+ TargetConstant,
+ TargetConstantFP,
+
+ // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
+ // anything else with this node, and this is valid in the target-specific
+ // dag, turning into a GlobalAddress operand.
+ TargetGlobalAddress,
+ TargetGlobalTLSAddress,
+ TargetFrameIndex,
+ TargetJumpTable,
+ TargetConstantPool,
+ TargetExternalSymbol,
+ TargetBlockAddress,
+
+ /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with no side effects.
+ /// The first operand is the ID number of the intrinsic from the
+ /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
+ /// node returns the result of the intrinsic.
+ INTRINSIC_WO_CHAIN,
+
+ /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// returns a result. The first operand is a chain pointer. The second is
+ /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
+ /// operands to the intrinsic follow. The node has two results, the result
+ /// of the intrinsic and an output chain.
+ INTRINSIC_W_CHAIN,
+
+ /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// does not return a result. The first operand is a chain pointer. The
+ /// second is the ID number of the intrinsic from the llvm::Intrinsic
+ /// namespace. The operands to the intrinsic follow.
+ INTRINSIC_VOID,
+
+ // CopyToReg - This node has three operands: a chain, a register number to
+ // set to this value, and a value.
+ CopyToReg,
+
+ // CopyFromReg - This node indicates that the input value is a virtual or
+ // physical register that is defined outside of the scope of this
+ // SelectionDAG. The register is available from the RegisterSDNode object.
+ CopyFromReg,
+
+ // UNDEF - An undefined node
+ UNDEF,
+
+ // EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
+ // a Constant, which is required to be operand #1) half of the integer or
+ // float value specified as operand #0. This is only for use before
+ // legalization, for values that will be broken into multiple registers.
+ EXTRACT_ELEMENT,
+
+ // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
+ // two values of the same integer value type, this produces a value twice as
+ // big. Like EXTRACT_ELEMENT, this can only be used before legalization.
+ BUILD_PAIR,
+
+ // MERGE_VALUES - This node takes multiple discrete operands and returns
+ // them all as its individual results. This nodes has exactly the same
+ // number of inputs and outputs. This node is useful for some pieces of the
+ // code generator that want to think about a single node with multiple
+ // results, not multiple nodes.
+ MERGE_VALUES,
+
+ // Simple integer binary arithmetic operators.
+ ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
+
+ // SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
+ // a signed/unsigned value of type i[2*N], and return the full value as
+ // two results, each of type iN.
+ SMUL_LOHI, UMUL_LOHI,
+
+ // SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
+ // remainder result.
+ SDIVREM, UDIVREM,
+
+ // CARRY_FALSE - This node is used when folding other nodes,
+ // like ADDC/SUBC, which indicate the carry result is always false.
+ CARRY_FALSE,
+
+ // Carry-setting nodes for multiple precision addition and subtraction.
+ // These nodes take two operands of the same value type, and produce two
+ // results. The first result is the normal add or sub result, the second
+ // result is the carry flag result.
+ ADDC, SUBC,
+
+ // Carry-using nodes for multiple precision addition and subtraction. These
+ // nodes take three operands: The first two are the normal lhs and rhs to
+ // the add or sub, and the third is the input carry flag. These nodes
+ // produce two results; the normal result of the add or sub, and the output
+ // carry flag. These nodes both read and write a carry flag to allow them
+ // to them to be chained together for add and sub of arbitrarily large
+ // values.
+ ADDE, SUBE,
+
+ // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
+ // These nodes take two operands: the normal LHS and RHS to the add. They
+ // produce two results: the normal result of the add, and a boolean that
+ // indicates if an overflow occurred (*not* a flag, because it may be stored
+ // to memory, etc.). If the type of the boolean is not i1 then the high
+ // bits conform to getBooleanContents.
+ // These nodes are generated from the llvm.[su]add.with.overflow intrinsics.
+ SADDO, UADDO,
+
+ // Same for subtraction
+ SSUBO, USUBO,
+
+ // Same for multiplication
+ SMULO, UMULO,
+
+ // Simple binary floating point operators.
+ FADD, FSUB, FMUL, FMA, FDIV, FREM,
+
+ // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
+ // DAG node does not require that X and Y have the same type, just that they
+ // are both floating point. X and the result must have the same type.
+ // FCOPYSIGN(f32, f64) is allowed.
+ FCOPYSIGN,
+
+ // INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
+ // value as an integer 0/1 value.
+ FGETSIGN,
+
+ /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the
+ /// specified, possibly variable, elements. The number of elements is
+ /// required to be a power of two. The types of the operands must all be
+ /// the same and must match the vector element type, except that integer
+ /// types are allowed to be larger than the element type, in which case
+ /// the operands are implicitly truncated.
+ BUILD_VECTOR,
+
+ /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
+ /// at IDX replaced with VAL. If the type of VAL is larger than the vector
+ /// element type then VAL is truncated before replacement.
+ INSERT_VECTOR_ELT,
+
+ /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+ /// identified by the (potentially variable) element number IDX. If the
+ /// return type is an integer type larger than the element type of the
+ /// vector, the result is extended to the width of the return type.
+ EXTRACT_VECTOR_ELT,
+
+ /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
+ /// vector type with the same length and element type, this produces a
+ /// concatenated vector result value, with length equal to the sum of the
+ /// lengths of the input vectors.
+ CONCAT_VECTORS,
+
+ /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector
+ /// with VECTOR2 inserted into VECTOR1 at the (potentially
+ /// variable) element number IDX, which must be a multiple of the
+ /// VECTOR2 vector length. The elements of VECTOR1 starting at
+ /// IDX are overwritten with VECTOR2. Elements IDX through
+ /// vector_length(VECTOR2) must be valid VECTOR1 indices.
+ INSERT_SUBVECTOR,
+
+ /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
+ /// vector value) starting with the element number IDX, which must be a
+ /// constant multiple of the result vector length.
+ EXTRACT_SUBVECTOR,
+
+ /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
+ /// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int
+ /// values that indicate which value (or undef) each result element will
+ /// get. These constant ints are accessible through the
+ /// ShuffleVectorSDNode class. This is quite similar to the Altivec
+ /// 'vperm' instruction, except that the indices must be constants and are
+ /// in terms of the element size of VEC1/VEC2, not in terms of bytes.
+ VECTOR_SHUFFLE,
+
+ /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
+ /// scalar value into element 0 of the resultant vector type. The top
+ /// elements 1 to N-1 of the N-element vector are undefined. The type
+ /// of the operand must match the vector element type, except when they
+ /// are integer types. In this case the operand is allowed to be wider
+ /// than the vector element type, and is implicitly truncated to it.
+ SCALAR_TO_VECTOR,
+
+ // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
+ // an unsigned/signed value of type i[2*N], then return the top part.
+ MULHU, MULHS,
+
+ /// Bitwise operators - logical and, logical or, logical xor.
+ AND, OR, XOR,
+
+ /// Shift and rotation operations. After legalization, the type of the
+ /// shift amount is known to be TLI.getShiftAmountTy(). Before legalization
+ /// the shift amount can be any type, but care must be taken to ensure it is
+ /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before
+ /// legalization, types like i1024 can occur and i8 doesn't have enough bits
+ /// to represent the shift amount. By convention, DAGCombine and
+ /// SelectionDAGBuilder forces these shift amounts to i32 for simplicity.
+ ///
+ SHL, SRA, SRL, ROTL, ROTR,
+
+ /// Byte Swap and Counting operators.
+ BSWAP, CTTZ, CTLZ, CTPOP,
+
+ /// Bit counting operators with an undefined result for zero inputs.
+ CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF,
+
+ // Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
+ // i1 then the high bits must conform to getBooleanContents.
+ SELECT,
+
+ // Select with a vector condition (op #0) and two vector operands (ops #1
+ // and #2), returning a vector result. All vectors have the same length.
+ // Much like the scalar select and setcc, each bit in the condition selects
+ // whether the corresponding result element is taken from op #1 or op #2.
+ // At first, the VSELECT condition is of vXi1 type. Later, targets may change
+ // the condition type in order to match the VSELECT node using a a pattern.
+ // The condition follows the BooleanContent format of the target.
+ VSELECT,
+
+ // Select with condition operator - This selects between a true value and
+ // a false value (ops #2 and #3) based on the boolean result of comparing
+ // the lhs and rhs (ops #0 and #1) of a conditional expression with the
+ // condition code in op #4, a CondCodeSDNode.
+ SELECT_CC,
+
+ // SetCC operator - This evaluates to a true value iff the condition is
+ // true. If the result value type is not i1 then the high bits conform
+ // to getBooleanContents. The operands to this are the left and right
+ // operands to compare (ops #0, and #1) and the condition code to compare
+ // them with (op #2) as a CondCodeSDNode. If the operands are vector types
+ // then the result type must also be a vector type.
+ SETCC,
+
+ // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
+ // integer shift operations, just like ADD/SUB_PARTS. The operation
+ // ordering is:
+ // [Lo,Hi] = op [LoLHS,HiLHS], Amt
+ SHL_PARTS, SRA_PARTS, SRL_PARTS,
+
+ // Conversion operators. These are all single input single output
+ // operations. For all of these, the result type must be strictly
+ // wider or narrower (depending on the operation) than the source
+ // type.
+
+ // SIGN_EXTEND - Used for integer types, replicating the sign bit
+ // into new bits.
+ SIGN_EXTEND,
+
+ // ZERO_EXTEND - Used for integer types, zeroing the new bits.
+ ZERO_EXTEND,
+
+ // ANY_EXTEND - Used for integer types. The high bits are undefined.
+ ANY_EXTEND,
+
+ // TRUNCATE - Completely drop the high bits.
+ TRUNCATE,
+
+ // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
+ // depends on the first letter) to floating point.
+ SINT_TO_FP,
+ UINT_TO_FP,
+
+ // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
+ // sign extend a small value in a large integer register (e.g. sign
+ // extending the low 8 bits of a 32-bit register to fill the top 24 bits
+ // with the 7th bit). The size of the smaller type is indicated by the 1th
+ // operand, a ValueType node.
+ SIGN_EXTEND_INREG,
+
+ /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
+ /// integer.
+ FP_TO_SINT,
+ FP_TO_UINT,
+
+ /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
+ /// down to the precision of the destination VT. TRUNC is a flag, which is
+ /// always an integer that is zero or one. If TRUNC is 0, this is a
+ /// normal rounding, if it is 1, this FP_ROUND is known to not change the
+ /// value of Y.
+ ///
+ /// The TRUNC = 1 case is used in cases where we know that the value will
+ /// not be modified by the node, because Y is not using any of the extra
+ /// precision of source type. This allows certain transformations like
+ /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for
+ /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
+ FP_ROUND,
+
+ // FLT_ROUNDS_ - Returns current rounding mode:
+ // -1 Undefined
+ // 0 Round to 0
+ // 1 Round to nearest
+ // 2 Round to +inf
+ // 3 Round to -inf
+ FLT_ROUNDS_,
+
+ /// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and
+ /// rounds it to a floating point value. It then promotes it and returns it
+ /// in a register of the same size. This operation effectively just
+ /// discards excess precision. The type to round down to is specified by
+ /// the VT operand, a VTSDNode.
+ FP_ROUND_INREG,
+
+ /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
+ FP_EXTEND,
+
+ // BITCAST - This operator converts between integer, vector and FP
+ // values, as if the value was stored to memory with one type and loaded
+ // from the same address with the other type (or equivalently for vector
+ // format conversions, etc). The source and result are required to have
+ // the same bit size (e.g. f32 <-> i32). This can also be used for
+ // int-to-int or fp-to-fp conversions, but that is a noop, deleted by
+ // getNode().
+ BITCAST,
+
+ // CONVERT_RNDSAT - This operator is used to support various conversions
+ // between various types (float, signed, unsigned and vectors of those
+ // types) with rounding and saturation. NOTE: Avoid using this operator as
+ // most target don't support it and the operator might be removed in the
+ // future. It takes the following arguments:
+ // 0) value
+ // 1) dest type (type to convert to)
+ // 2) src type (type to convert from)
+ // 3) rounding imm
+ // 4) saturation imm
+ // 5) ISD::CvtCode indicating the type of conversion to do
+ CONVERT_RNDSAT,
+
+ // FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform
+ // promotions and truncation for half-precision (16 bit) floating
+ // numbers. We need special nodes since FP16 is a storage-only type with
+ // special semantics of operations.
+ FP16_TO_FP32, FP32_TO_FP16,
+
+ // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
+ // FLOG, FLOG2, FLOG10, FEXP, FEXP2,
+ // FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
+ // point operations. These are inspired by libm.
+ FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
+ FLOG, FLOG2, FLOG10, FEXP, FEXP2,
+ FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
+
+ // LOAD and STORE have token chains as their first operand, then the same
+ // operands as an LLVM load/store instruction, then an offset node that
+ // is added / subtracted from the base pointer to form the address (for
+ // indexed memory ops).
+ LOAD, STORE,
+
+ // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
+ // to a specified boundary. This node always has two return values: a new
+ // stack pointer value and a chain. The first operand is the token chain,
+ // the second is the number of bytes to allocate, and the third is the
+ // alignment boundary. The size is guaranteed to be a multiple of the stack
+ // alignment, and the alignment is guaranteed to be bigger than the stack
+ // alignment (if required) or 0 to get standard stack alignment.
+ DYNAMIC_STACKALLOC,
+
+ // Control flow instructions. These all have token chains.
+
+ // BR - Unconditional branch. The first operand is the chain
+ // operand, the second is the MBB to branch to.
+ BR,
+
+ // BRIND - Indirect branch. The first operand is the chain, the second
+ // is the value to branch to, which must be of the same type as the target's
+ // pointer type.
+ BRIND,
+
+ // BR_JT - Jumptable branch. The first operand is the chain, the second
+ // is the jumptable index, the last one is the jumptable entry index.
+ BR_JT,
+
+ // BRCOND - Conditional branch. The first operand is the chain, the
+ // second is the condition, the third is the block to branch to if the
+ // condition is true. If the type of the condition is not i1, then the
+ // high bits must conform to getBooleanContents.
+ BRCOND,
+
+ // BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
+ // that the condition is represented as condition code, and two nodes to
+ // compare, rather than as a combined SetCC node. The operands in order are
+ // chain, cc, lhs, rhs, block to branch to if condition is true.
+ BR_CC,
+
+ // INLINEASM - Represents an inline asm block. This node always has two
+ // return values: a chain and a flag result. The inputs are as follows:
+ // Operand #0 : Input chain.
+ // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
+ // Operand #2 : a MDNodeSDNode with the !srcloc metadata.
+ // Operand #3 : HasSideEffect, IsAlignStack bits.
+ // After this, it is followed by a list of operands with this format:
+ // ConstantSDNode: Flags that encode whether it is a mem or not, the
+ // of operands that follow, etc. See InlineAsm.h.
+ // ... however many operands ...
+ // Operand #last: Optional, an incoming flag.
+ //
+ // The variable width operands are required to represent target addressing
+ // modes as a single "operand", even though they may have multiple
+ // SDOperands.
+ INLINEASM,
+
+ // EH_LABEL - Represents a label in mid basic block used to track
+ // locations needed for debug and exception handling tables. These nodes
+ // take a chain as input and return a chain.
+ EH_LABEL,
+
+ // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
+ // value, the same type as the pointer type for the system, and an output
+ // chain.
+ STACKSAVE,
+
+ // STACKRESTORE has two operands, an input chain and a pointer to restore to
+ // it returns an output chain.
+ STACKRESTORE,
+
+ // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
+ // a call sequence, and carry arbitrary information that target might want
+ // to know. The first operand is a chain, the rest are specified by the
+ // target and not touched by the DAG optimizers.
+ // CALLSEQ_START..CALLSEQ_END pairs may not be nested.
+ CALLSEQ_START, // Beginning of a call sequence
+ CALLSEQ_END, // End of a call sequence
+
+ // VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
+ // and the alignment. It returns a pair of values: the vaarg value and a
+ // new chain.
+ VAARG,
+
+ // VACOPY - VACOPY has five operands: an input chain, a destination pointer,
+ // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ // source.
+ VACOPY,
+
+ // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
+ // pointer, and a SRCVALUE.
+ VAEND, VASTART,
+
+ // SRCVALUE - This is a node type that holds a Value* that is used to
+ // make reference to a value in the LLVM IR.
+ SRCVALUE,
+
+ // MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
+ // reference metadata in the IR.
+ MDNODE_SDNODE,
+
+ // PCMARKER - This corresponds to the pcmarker intrinsic.
+ PCMARKER,
+
+ // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+ // The only operand is a chain and a value and a chain are produced. The
+ // value is the contents of the architecture specific cycle counter like
+ // register (or other high accuracy low latency clock source)
+ READCYCLECOUNTER,
+
+ // HANDLENODE node - Used as a handle for various purposes.
+ HANDLENODE,
+
+ // INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It
+ // takes as input a token chain, the pointer to the trampoline, the pointer
+ // to the nested function, the pointer to pass for the 'nest' parameter, a
+ // SRCVALUE for the trampoline and another for the nested function (allowing
+ // targets to access the original Function*). It produces a token chain as
+ // output.
+ INIT_TRAMPOLINE,
+
+ // ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
+ // It takes a pointer to the trampoline and produces a (possibly) new
+ // pointer to the same trampoline with platform-specific adjustments
+ // applied. The pointer it returns points to an executable block of code.
+ ADJUST_TRAMPOLINE,
+
+ // TRAP - Trapping instruction
+ TRAP,
+
+ // PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are
+ // their first operand. The other operands are the address to prefetch,
+ // read / write specifier, locality specifier and instruction / data cache
+ // specifier.
+ PREFETCH,
+
+ // OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,
+ // store-store, device)
+ // This corresponds to the memory.barrier intrinsic.
+ // it takes an input chain, 4 operands to specify the type of barrier, an
+ // operand specifying if the barrier applies to device and uncached memory
+ // and produces an output chain.
+ MEMBARRIER,
+
+ // OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
+ // This corresponds to the fence instruction. It takes an input chain, and
+ // two integer constants: an AtomicOrdering and a SynchronizationScope.
+ ATOMIC_FENCE,
+
+ // Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
+ // This corresponds to "load atomic" instruction.
+ ATOMIC_LOAD,
+
+ // OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val)
+ // This corresponds to "store atomic" instruction.
+ ATOMIC_STORE,
+
+ // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
+ // This corresponds to the cmpxchg instruction.
+ ATOMIC_CMP_SWAP,
+
+ // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
+ // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
+ // These correspond to the atomicrmw instruction.
+ ATOMIC_SWAP,
+ ATOMIC_LOAD_ADD,
+ ATOMIC_LOAD_SUB,
+ ATOMIC_LOAD_AND,
+ ATOMIC_LOAD_OR,
+ ATOMIC_LOAD_XOR,
+ ATOMIC_LOAD_NAND,
+ ATOMIC_LOAD_MIN,
+ ATOMIC_LOAD_MAX,
+ ATOMIC_LOAD_UMIN,
+ ATOMIC_LOAD_UMAX,
+
+ /// BUILTIN_OP_END - This must be the last enum value in this list.
+ /// The target-specific pre-isel opcode values start here.
+ BUILTIN_OP_END
+ };
+
+ /// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
+ /// which do not reference a specific memory location should be less than
+ /// this value. Those that do must not be less than this value, and can
+ /// be used with SelectionDAG::getMemIntrinsicNode.
+ static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+150;
+
+ //===--------------------------------------------------------------------===//
+ /// MemIndexedMode enum - This enum defines the load / store indexed
+ /// addressing modes.
+ ///
+ /// UNINDEXED "Normal" load / store. The effective address is already
+ /// computed and is available in the base pointer. The offset
+ /// operand is always undefined. In addition to producing a
+ /// chain, an unindexed load produces one value (result of the
+ /// load); an unindexed store does not produce a value.
+ ///
+ /// PRE_INC Similar to the unindexed mode where the effective address is
+ /// PRE_DEC the value of the base pointer add / subtract the offset.
+ /// It considers the computation as being folded into the load /
+ /// store operation (i.e. the load / store does the address
+ /// computation as well as performing the memory transaction).
+ /// The base operand is always undefined. In addition to
+ /// producing a chain, pre-indexed load produces two values
+ /// (result of the load and the result of the address
+ /// computation); a pre-indexed store produces one value (result
+ /// of the address computation).
+ ///
+ /// POST_INC The effective address is the value of the base pointer. The
+ /// POST_DEC value of the offset operand is then added to / subtracted
+ /// from the base after memory transaction. In addition to
+ /// producing a chain, post-indexed load produces two values
+ /// (the result of the load and the result of the base +/- offset
+ /// computation); a post-indexed store produces one value (the
+ /// the result of the base +/- offset computation).
+ enum MemIndexedMode {
+ UNINDEXED = 0,
+ PRE_INC,
+ PRE_DEC,
+ POST_INC,
+ POST_DEC,
+ LAST_INDEXED_MODE
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// LoadExtType enum - This enum defines the three variants of LOADEXT
+ /// (load with extension).
+ ///
+ /// SEXTLOAD loads the integer operand and sign extends it to a larger
+ /// integer result type.
+ /// ZEXTLOAD loads the integer operand and zero extends it to a larger
+ /// integer result type.
+ /// EXTLOAD is used for two things: floating point extending loads and
+ /// integer extending loads [the top bits are undefined].
+ enum LoadExtType {
+ NON_EXTLOAD = 0,
+ EXTLOAD,
+ SEXTLOAD,
+ ZEXTLOAD,
+ LAST_LOADEXT_TYPE
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// ISD::CondCode enum - These are ordered carefully to make the bitfields
+ /// below work out, when considering SETFALSE (something that never exists
+ /// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
+ /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
+ /// to. If the "N" column is 1, the result of the comparison is undefined if
+ /// the input is a NAN.
+ ///
+ /// All of these (except for the 'always folded ops') should be handled for
+ /// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
+ /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
+ ///
+ /// Note that these are laid out in a specific order to allow bit-twiddling
+ /// to transform conditions.
+ enum CondCode {
+ // Opcode N U L G E Intuitive operation
+ SETFALSE, // 0 0 0 0 Always false (always folded)
+ SETOEQ, // 0 0 0 1 True if ordered and equal
+ SETOGT, // 0 0 1 0 True if ordered and greater than
+ SETOGE, // 0 0 1 1 True if ordered and greater than or equal
+ SETOLT, // 0 1 0 0 True if ordered and less than
+ SETOLE, // 0 1 0 1 True if ordered and less than or equal
+ SETONE, // 0 1 1 0 True if ordered and operands are unequal
+ SETO, // 0 1 1 1 True if ordered (no nans)
+ SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ SETUEQ, // 1 0 0 1 True if unordered or equal
+ SETUGT, // 1 0 1 0 True if unordered or greater than
+ SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
+ SETULT, // 1 1 0 0 True if unordered or less than
+ SETULE, // 1 1 0 1 True if unordered, less than, or equal
+ SETUNE, // 1 1 1 0 True if unordered or not equal
+ SETTRUE, // 1 1 1 1 Always true (always folded)
+ // Don't care operations: undefined if the input is a nan.
+ SETFALSE2, // 1 X 0 0 0 Always false (always folded)
+ SETEQ, // 1 X 0 0 1 True if equal
+ SETGT, // 1 X 0 1 0 True if greater than
+ SETGE, // 1 X 0 1 1 True if greater than or equal
+ SETLT, // 1 X 1 0 0 True if less than
+ SETLE, // 1 X 1 0 1 True if less than or equal
+ SETNE, // 1 X 1 1 0 True if not equal
+ SETTRUE2, // 1 X 1 1 1 Always true (always folded)
+
+ SETCC_INVALID // Marker value.
+ };
+
+ /// isSignedIntSetCC - Return true if this is a setcc instruction that
+ /// performs a signed comparison when used with integer operands.
+ inline bool isSignedIntSetCC(CondCode Code) {
+ return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
+ }
+
+ /// isUnsignedIntSetCC - Return true if this is a setcc instruction that
+ /// performs an unsigned comparison when used with integer operands.
+ inline bool isUnsignedIntSetCC(CondCode Code) {
+ return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
+ }
+
+ /// isTrueWhenEqual - Return true if the specified condition returns true if
+ /// the two operands to the condition are equal. Note that if one of the two
+ /// operands is a NaN, this value is meaningless.
+ inline bool isTrueWhenEqual(CondCode Cond) {
+ return ((int)Cond & 1) != 0;
+ }
+
+ /// getUnorderedFlavor - This function returns 0 if the condition is always
+ /// false if an operand is a NaN, 1 if the condition is always true if the
+ /// operand is a NaN, and 2 if the condition is undefined if the operand is a
+ /// NaN.
+ inline unsigned getUnorderedFlavor(CondCode Cond) {
+ return ((int)Cond >> 3) & 3;
+ }
+
+ /// getSetCCInverse - Return the operation corresponding to !(X op Y), where
+ /// 'op' is a valid SetCC operation.
+ CondCode getSetCCInverse(CondCode Operation, bool isInteger);
+
+ /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
+ /// when given the operation for (X op Y).
+ CondCode getSetCCSwappedOperands(CondCode Operation);
+
+ /// getSetCCOrOperation - Return the result of a logical OR between different
+ /// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This
+ /// function returns SETCC_INVALID if it is not possible to represent the
+ /// resultant comparison.
+ CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+ /// getSetCCAndOperation - Return the result of a logical AND between
+ /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This
+ /// function returns SETCC_INVALID if it is not possible to represent the
+ /// resultant comparison.
+ CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+ //===--------------------------------------------------------------------===//
+ /// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT
+ /// supports.
+ enum CvtCode {
+ CVT_FF, // Float from Float
+ CVT_FS, // Float from Signed
+ CVT_FU, // Float from Unsigned
+ CVT_SF, // Signed from Float
+ CVT_UF, // Unsigned from Float
+ CVT_SS, // Signed from Signed
+ CVT_SU, // Signed from Unsigned
+ CVT_US, // Unsigned from Signed
+ CVT_UU, // Unsigned from Unsigned
+ CVT_INVALID // Marker - Invalid opcode
+ };
+
+} // end llvm::ISD namespace
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h b/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h
new file mode 100644
index 000000000000..767b66622549
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/IntrinsicLowering.h
@@ -0,0 +1,59 @@
+//===-- IntrinsicLowering.h - Intrinsic Function Lowering -------*- 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 IntrinsicLowering interface. This interface allows
+// addition of domain-specific or front-end specific intrinsics to LLVM without
+// having to modify all of the C backend or interpreter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H
+#define LLVM_CODEGEN_INTRINSICLOWERING_H
+
+#include "llvm/Intrinsics.h"
+
+namespace llvm {
+ class CallInst;
+ class Module;
+ class TargetData;
+
+ class IntrinsicLowering {
+ const TargetData& TD;
+
+
+ bool Warned;
+ public:
+ explicit IntrinsicLowering(const TargetData &td) :
+ TD(td), Warned(false) {}
+
+ /// AddPrototypes - This method, if called, causes all of the prototypes
+ /// that might be needed by an intrinsic lowering implementation to be
+ /// inserted into the module specified.
+ void AddPrototypes(Module &M);
+
+ /// LowerIntrinsicCall - This method replaces a call with the LLVM function
+ /// which should be used to implement the specified intrinsic function call.
+ /// If an intrinsic function must be implemented by the code generator
+ /// (such as va_start), this function should print a message and abort.
+ ///
+ /// Otherwise, if an intrinsic function call can be lowered, the code to
+ /// implement it (often a call to a non-intrinsic function) is inserted
+ /// _after_ the call instruction and the call is deleted. The caller must
+ /// be capable of handling this kind of change.
+ ///
+ void LowerIntrinsicCall(CallInst *CI);
+
+ /// LowerToByteSwap - Replace a call instruction into a call to bswap
+ /// intrinsic. Return false if it has determined the call is not a
+ /// simple integer bswap.
+ static bool LowerToByteSwap(CallInst *CI);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h b/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h
new file mode 100644
index 000000000000..89f00e91f78e
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/JITCodeEmitter.h
@@ -0,0 +1,342 @@
+//===-- llvm/CodeGen/JITCodeEmitter.h - Code emission ----------*- 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 an abstract interface that is used by the machine code
+// emission framework to output the code. This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_JITCODEEMITTER_H
+#define LLVM_CODEGEN_JITCODEEMITTER_H
+
+#include <string>
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRelocation;
+class Value;
+class GlobalValue;
+class Function;
+
+/// JITCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxiliary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it. As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit. In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+///
+class JITCodeEmitter : public MachineCodeEmitter {
+ virtual void anchor();
+public:
+ virtual ~JITCodeEmitter() {}
+
+ /// startFunction - This callback is invoked when the specified function is
+ /// about to be code generated. This initializes the BufferBegin/End/Ptr
+ /// fields.
+ ///
+ virtual void startFunction(MachineFunction &F) = 0;
+
+ /// finishFunction - This callback is invoked when the specified function has
+ /// finished code generation. If a buffer overflow has occurred, this method
+ /// returns true (the callee is required to try again), otherwise it returns
+ /// false.
+ ///
+ virtual bool finishFunction(MachineFunction &F) = 0;
+
+ /// allocIndirectGV - Allocates and fills storage for an indirect
+ /// GlobalValue, and returns the address.
+ virtual void *allocIndirectGV(const GlobalValue *GV,
+ const uint8_t *Buffer, size_t Size,
+ unsigned Alignment) = 0;
+
+ /// emitByte - This callback is invoked when a byte needs to be written to the
+ /// output stream.
+ ///
+ void emitByte(uint8_t B) {
+ if (CurBufferPtr != BufferEnd)
+ *CurBufferPtr++ = B;
+ }
+
+ /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in little-endian format.
+ ///
+ void emitWordLE(uint32_t W) {
+ if (4 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in big-endian format.
+ ///
+ void emitWordBE(uint32_t W) {
+ if (4 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
+ /// written to the output stream in little-endian format.
+ ///
+ void emitDWordLE(uint64_t W) {
+ if (8 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (uint8_t)(W >> 32);
+ *CurBufferPtr++ = (uint8_t)(W >> 40);
+ *CurBufferPtr++ = (uint8_t)(W >> 48);
+ *CurBufferPtr++ = (uint8_t)(W >> 56);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
+ /// written to the output stream in big-endian format.
+ ///
+ void emitDWordBE(uint64_t W) {
+ if (8 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 56);
+ *CurBufferPtr++ = (uint8_t)(W >> 48);
+ *CurBufferPtr++ = (uint8_t)(W >> 40);
+ *CurBufferPtr++ = (uint8_t)(W >> 32);
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
+ /// alignment (saturated to BufferEnd of course).
+ void emitAlignment(unsigned Alignment) {
+ if (Alignment == 0) Alignment = 1;
+ uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr,
+ Alignment);
+ CurBufferPtr = std::min(NewPtr, BufferEnd);
+ }
+
+ /// emitAlignmentWithFill - Similar to emitAlignment, except that the
+ /// extra bytes are filled with the provided byte.
+ void emitAlignmentWithFill(unsigned Alignment, uint8_t Fill) {
+ if (Alignment == 0) Alignment = 1;
+ uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr,
+ Alignment);
+ // Fail if we don't have room.
+ if (NewPtr > BufferEnd) {
+ CurBufferPtr = BufferEnd;
+ return;
+ }
+ while (CurBufferPtr < NewPtr) {
+ *CurBufferPtr++ = Fill;
+ }
+ }
+
+ /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
+ /// written to the output stream.
+ void emitULEB128Bytes(uint64_t Value, unsigned PadTo = 0) {
+ do {
+ uint8_t Byte = Value & 0x7f;
+ Value >>= 7;
+ if (Value || PadTo != 0) Byte |= 0x80;
+ emitByte(Byte);
+ } while (Value);
+
+ if (PadTo) {
+ do {
+ uint8_t Byte = (PadTo > 1) ? 0x80 : 0x0;
+ emitByte(Byte);
+ } while (--PadTo);
+ }
+ }
+
+ /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
+ /// written to the output stream.
+ void emitSLEB128Bytes(int64_t Value) {
+ int32_t Sign = Value >> (8 * sizeof(Value) - 1);
+ bool IsMore;
+
+ do {
+ uint8_t Byte = Value & 0x7f;
+ Value >>= 7;
+ IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+ if (IsMore) Byte |= 0x80;
+ emitByte(Byte);
+ } while (IsMore);
+ }
+
+ /// emitString - This callback is invoked when a String needs to be
+ /// written to the output stream.
+ void emitString(const std::string &String) {
+ for (unsigned i = 0, N = static_cast<unsigned>(String.size());
+ i < N; ++i) {
+ uint8_t C = String[i];
+ emitByte(C);
+ }
+ emitByte(0);
+ }
+
+ /// emitInt32 - Emit a int32 directive.
+ void emitInt32(uint32_t Value) {
+ if (4 <= BufferEnd-CurBufferPtr) {
+ *((uint32_t*)CurBufferPtr) = Value;
+ CurBufferPtr += 4;
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitInt64 - Emit a int64 directive.
+ void emitInt64(uint64_t Value) {
+ if (8 <= BufferEnd-CurBufferPtr) {
+ *((uint64_t*)CurBufferPtr) = Value;
+ CurBufferPtr += 8;
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitInt32At - Emit the Int32 Value in Addr.
+ void emitInt32At(uintptr_t *Addr, uintptr_t Value) {
+ if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+ (*(uint32_t*)Addr) = (uint32_t)Value;
+ }
+
+ /// emitInt64At - Emit the Int64 Value in Addr.
+ void emitInt64At(uintptr_t *Addr, uintptr_t Value) {
+ if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+ (*(uint64_t*)Addr) = (uint64_t)Value;
+ }
+
+
+ /// emitLabel - Emits a label
+ virtual void emitLabel(MCSymbol *Label) = 0;
+
+ /// allocateSpace - Allocate a block of space in the current output buffer,
+ /// returning null (and setting conditions to indicate buffer overflow) on
+ /// failure. Alignment is the alignment in bytes of the buffer desired.
+ virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) {
+ emitAlignment(Alignment);
+ void *Result;
+
+ // Check for buffer overflow.
+ if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) {
+ CurBufferPtr = BufferEnd;
+ Result = 0;
+ } else {
+ // Allocate the space.
+ Result = CurBufferPtr;
+ CurBufferPtr += Size;
+ }
+
+ return Result;
+ }
+
+ /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
+ /// this method does not allocate memory in the current output buffer,
+ /// because a global may live longer than the current function.
+ virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0;
+
+ /// StartMachineBasicBlock - This should be called by the target when a new
+ /// basic block is about to be emitted. This way the MCE knows where the
+ /// start of the block is, and can implement getMachineBasicBlockAddress.
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
+
+ /// getCurrentPCValue - This returns the address that the next emitted byte
+ /// will be output to.
+ ///
+ virtual uintptr_t getCurrentPCValue() const {
+ return (uintptr_t)CurBufferPtr;
+ }
+
+ /// getCurrentPCOffset - Return the offset from the start of the emitted
+ /// buffer that we are currently writing to.
+ uintptr_t getCurrentPCOffset() const {
+ return CurBufferPtr-BufferBegin;
+ }
+
+ /// earlyResolveAddresses - True if the code emitter can use symbol addresses
+ /// during code emission time. The JIT is capable of doing this because it
+ /// creates jump tables or constant pools in memory on the fly while the
+ /// object code emitters rely on a linker to have real addresses and should
+ /// use relocations instead.
+ bool earlyResolveAddresses() const { return true; }
+
+ /// addRelocation - Whenever a relocatable address is needed, it should be
+ /// noted with this interface.
+ virtual void addRelocation(const MachineRelocation &MR) = 0;
+
+ /// FIXME: These should all be handled with relocations!
+
+ /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
+ /// the constant pool that was last emitted with the emitConstantPool method.
+ ///
+ virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
+
+ /// getJumpTableEntryAddress - Return the address of the jump table with index
+ /// 'Index' in the function that last called initJumpTableInfo.
+ ///
+ virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
+
+ /// getMachineBasicBlockAddress - Return the address of the specified
+ /// MachineBasicBlock, only usable after the label for the MBB has been
+ /// emitted.
+ ///
+ virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
+
+ /// getLabelAddress - Return the address of the specified Label, only usable
+ /// after the Label has been emitted.
+ ///
+ virtual uintptr_t getLabelAddress(MCSymbol *Label) const = 0;
+
+ /// Specifies the MachineModuleInfo object. This is used for exception handling
+ /// purposes.
+ virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
+
+ /// getLabelLocations - Return the label locations map of the label IDs to
+ /// their address.
+ virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { return 0; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h b/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h
new file mode 100644
index 000000000000..8fb31aa8a6d1
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -0,0 +1,100 @@
+//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the LatencyPriorityQueue class, which is a
+// SchedulingPriorityQueue that schedules using latency information to
+// reduce the length of the critical path through the basic block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LATENCY_PRIORITY_QUEUE_H
+#define LATENCY_PRIORITY_QUEUE_H
+
+#include "llvm/CodeGen/ScheduleDAG.h"
+
+namespace llvm {
+ class LatencyPriorityQueue;
+
+ /// Sorting functions for the Available queue.
+ struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
+ LatencyPriorityQueue *PQ;
+ explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
+
+ bool operator()(const SUnit* left, const SUnit* right) const;
+ };
+
+ class LatencyPriorityQueue : public SchedulingPriorityQueue {
+ // SUnits - The SUnits for the current graph.
+ std::vector<SUnit> *SUnits;
+
+ /// NumNodesSolelyBlocking - This vector contains, for every node in the
+ /// Queue, the number of nodes that the node is the sole unscheduled
+ /// predecessor for. This is used as a tie-breaker heuristic for better
+ /// mobility.
+ std::vector<unsigned> NumNodesSolelyBlocking;
+
+ /// Queue - The queue.
+ std::vector<SUnit*> Queue;
+ latency_sort Picker;
+
+ public:
+ LatencyPriorityQueue() : Picker(this) {
+ }
+
+ bool isBottomUp() const { return false; }
+
+ void initNodes(std::vector<SUnit> &sunits) {
+ SUnits = &sunits;
+ NumNodesSolelyBlocking.resize(SUnits->size(), 0);
+ }
+
+ void addNode(const SUnit *SU) {
+ NumNodesSolelyBlocking.resize(SUnits->size(), 0);
+ }
+
+ void updateNode(const SUnit *SU) {
+ }
+
+ void releaseState() {
+ SUnits = 0;
+ }
+
+ unsigned getLatency(unsigned NodeNum) const {
+ assert(NodeNum < (*SUnits).size());
+ return (*SUnits)[NodeNum].getHeight();
+ }
+
+ unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
+ assert(NodeNum < NumNodesSolelyBlocking.size());
+ return NumNodesSolelyBlocking[NodeNum];
+ }
+
+ bool empty() const { return Queue.empty(); }
+
+ virtual void push(SUnit *U);
+
+ virtual SUnit *pop();
+
+ virtual void remove(SUnit *SU);
+
+ virtual void dump(ScheduleDAG* DAG) const;
+
+ // scheduledNode - As nodes are scheduled, we look to see if there are any
+ // successor nodes that have a single unscheduled predecessor. If so, that
+ // single predecessor has a higher priority, since scheduling it will make
+ // the node available.
+ void scheduledNode(SUnit *Node);
+
+private:
+ void AdjustPriorityOfUnscheduledPreds(SUnit *SU);
+ SUnit *getSingleUnscheduledPred(SUnit *SU);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h b/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h
new file mode 100644
index 000000000000..eb01f66c3129
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LexicalScopes.h
@@ -0,0 +1,249 @@
+//===- LexicalScopes.cpp - Collecting lexical scope info -*- C++ -*--------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements LexicalScopes analysis.
+//
+// This pass collects lexical scope information and maps machine instructions
+// to respective lexical scopes.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/DebugLoc.h"
+#include "llvm/Support/ValueHandle.h"
+#include <utility>
+namespace llvm {
+
+class MachineInstr;
+class MachineBasicBlock;
+class MachineFunction;
+class LexicalScope;
+
+//===----------------------------------------------------------------------===//
+/// InsnRange - This is used to track range of instructions with identical
+/// lexical scope.
+///
+typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
+
+//===----------------------------------------------------------------------===//
+/// LexicalScopes - This class provides interface to collect and use lexical
+/// scoping information from machine instruction.
+///
+class LexicalScopes {
+public:
+ LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { }
+ virtual ~LexicalScopes();
+
+ /// initialize - Scan machine function and constuct lexical scope nest.
+ virtual void initialize(const MachineFunction &);
+
+ /// releaseMemory - release memory.
+ virtual void releaseMemory();
+
+ /// empty - Return true if there is any lexical scope information available.
+ bool empty() { return CurrentFnLexicalScope == NULL; }
+
+ /// isCurrentFunctionScope - Return true if given lexical scope represents
+ /// current function.
+ bool isCurrentFunctionScope(const LexicalScope *LS) {
+ return LS == CurrentFnLexicalScope;
+ }
+
+ /// getCurrentFunctionScope - Return lexical scope for the current function.
+ LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;}
+
+ /// getMachineBasicBlocks - Populate given set using machine basic blocks
+ /// which have machine instructions that belong to lexical scope identified by
+ /// DebugLoc.
+ void getMachineBasicBlocks(DebugLoc DL,
+ SmallPtrSet<const MachineBasicBlock*, 4> &MBBs);
+
+ /// dominates - Return true if DebugLoc's lexical scope dominates at least one
+ /// machine instruction's lexical scope in a given machine basic block.
+ bool dominates(DebugLoc DL, MachineBasicBlock *MBB);
+
+ /// findLexicalScope - Find lexical scope, either regular or inlined, for the
+ /// given DebugLoc. Return NULL if not found.
+ LexicalScope *findLexicalScope(DebugLoc DL);
+
+ /// getAbstractScopesList - Return a reference to list of abstract scopes.
+ ArrayRef<LexicalScope *> getAbstractScopesList() const {
+ return AbstractScopesList;
+ }
+
+ /// findAbstractScope - Find an abstract scope or return NULL.
+ LexicalScope *findAbstractScope(const MDNode *N) {
+ return AbstractScopeMap.lookup(N);
+ }
+
+ /// findInlinedScope - Find an inlined scope for the given DebugLoc or return
+ /// NULL.
+ LexicalScope *findInlinedScope(DebugLoc DL) {
+ return InlinedLexicalScopeMap.lookup(DL);
+ }
+
+ /// findLexicalScope - Find regular lexical scope or return NULL.
+ LexicalScope *findLexicalScope(const MDNode *N) {
+ return LexicalScopeMap.lookup(N);
+ }
+
+ /// dump - Print data structures to dbgs().
+ void dump();
+
+private:
+
+ /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
+ /// not available then create new lexical scope.
+ LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
+
+ /// getOrCreateRegularScope - Find or create a regular lexical scope.
+ LexicalScope *getOrCreateRegularScope(MDNode *Scope);
+
+ /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
+ LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
+
+ /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
+ LexicalScope *getOrCreateAbstractScope(const MDNode *N);
+
+ /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
+ /// for the given machine function.
+ void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
+ DenseMap<const MachineInstr *, LexicalScope *> &M);
+ void constructScopeNest(LexicalScope *Scope);
+ void assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
+ DenseMap<const MachineInstr *, LexicalScope *> &M);
+
+private:
+ const MachineFunction *MF;
+
+ /// LexicalScopeMap - Tracks the scopes in the current function. Owns the
+ /// contained LexicalScope*s.
+ DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap;
+
+ /// InlinedLexicalScopeMap - Tracks inlined function scopes in current function.
+ DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
+
+ /// AbstractScopeMap - These scopes are not included LexicalScopeMap.
+ /// AbstractScopes owns its LexicalScope*s.
+ DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
+
+ /// AbstractScopesList - Tracks abstract scopes constructed while processing
+ /// a function.
+ SmallVector<LexicalScope *, 4>AbstractScopesList;
+
+ /// CurrentFnLexicalScope - Top level scope for the current function.
+ ///
+ LexicalScope *CurrentFnLexicalScope;
+};
+
+//===----------------------------------------------------------------------===//
+/// LexicalScope - This class is used to track scope information.
+///
+class LexicalScope {
+ virtual void anchor();
+
+public:
+ LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
+ : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
+ LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) {
+ if (Parent)
+ Parent->addChild(this);
+ }
+
+ virtual ~LexicalScope() {}
+
+ // Accessors.
+ LexicalScope *getParent() const { return Parent; }
+ const MDNode *getDesc() const { return Desc; }
+ const MDNode *getInlinedAt() const { return InlinedAtLocation; }
+ const MDNode *getScopeNode() const { return Desc; }
+ bool isAbstractScope() const { return AbstractScope; }
+ SmallVector<LexicalScope *, 4> &getChildren() { return Children; }
+ SmallVector<InsnRange, 4> &getRanges() { return Ranges; }
+
+ /// addChild - Add a child scope.
+ void addChild(LexicalScope *S) { Children.push_back(S); }
+
+ /// openInsnRange - This scope covers instruction range starting from MI.
+ void openInsnRange(const MachineInstr *MI) {
+ if (!FirstInsn)
+ FirstInsn = MI;
+
+ if (Parent)
+ Parent->openInsnRange(MI);
+ }
+
+ /// extendInsnRange - Extend the current instruction range covered by
+ /// this scope.
+ void extendInsnRange(const MachineInstr *MI) {
+ assert (FirstInsn && "MI Range is not open!");
+ LastInsn = MI;
+ if (Parent)
+ Parent->extendInsnRange(MI);
+ }
+
+ /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
+ /// until now. This is used when a new scope is encountered while walking
+ /// machine instructions.
+ void closeInsnRange(LexicalScope *NewScope = NULL) {
+ assert (LastInsn && "Last insn missing!");
+ Ranges.push_back(InsnRange(FirstInsn, LastInsn));
+ FirstInsn = NULL;
+ LastInsn = NULL;
+ // If Parent dominates NewScope then do not close Parent's instruction
+ // range.
+ if (Parent && (!NewScope || !Parent->dominates(NewScope)))
+ Parent->closeInsnRange(NewScope);
+ }
+
+ /// dominates - Return true if current scope dominates given lexical scope.
+ bool dominates(const LexicalScope *S) const {
+ if (S == this)
+ return true;
+ if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
+ return true;
+ return false;
+ }
+
+ // Depth First Search support to walk and manipulate LexicalScope hierarchy.
+ unsigned getDFSOut() const { return DFSOut; }
+ void setDFSOut(unsigned O) { DFSOut = O; }
+ unsigned getDFSIn() const { return DFSIn; }
+ void setDFSIn(unsigned I) { DFSIn = I; }
+
+ /// dump - print lexical scope.
+ void dump() const;
+
+private:
+ LexicalScope *Parent; // Parent to this scope.
+ AssertingVH<const MDNode> Desc; // Debug info descriptor.
+ AssertingVH<const MDNode> InlinedAtLocation; // Location at which this
+ // scope is inlined.
+ bool AbstractScope; // Abstract Scope
+ SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.
+ // Contents not owned.
+ SmallVector<InsnRange, 4> Ranges;
+
+ const MachineInstr *LastInsn; // Last instruction of this scope.
+ const MachineInstr *FirstInsn; // First instruction of this scope.
+ unsigned DFSIn, DFSOut; // In & Out Depth use to determine
+ // scope nesting.
+ mutable unsigned IndentLevel; // Private state for dump()
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
new file mode 100644
index 000000000000..7d1b1fe477a5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -0,0 +1,37 @@
+//===- llvm/Codegen/LinkAllAsmWriterComponents.h ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all assembler writer related passes for tools like
+// llc that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
+#define LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
+
+#include "llvm/CodeGen/GCs.h"
+#include <cstdlib>
+
+namespace {
+ struct ForceAsmWriterLinking {
+ ForceAsmWriterLinking() {
+ // We must reference the plug-ins in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ llvm::linkOcamlGCPrinter();
+
+ }
+ } ForceAsmWriterLinking; // Force link by creating a global definition.
+}
+
+#endif // LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h b/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
new file mode 100644
index 000000000000..46dd004609f5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -0,0 +1,53 @@
+//===- llvm/Codegen/LinkAllCodegenComponents.h ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all codegen related passes for tools like lli and
+// llc that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/CodeGen/GCs.h"
+#include "llvm/Target/TargetMachine.h"
+#include <cstdlib>
+
+namespace {
+ struct ForceCodegenLinking {
+ ForceCodegenLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ (void) llvm::createFastRegisterAllocator();
+ (void) llvm::createBasicRegisterAllocator();
+ (void) llvm::createGreedyRegisterAllocator();
+ (void) llvm::createDefaultPBQPRegisterAllocator();
+
+ llvm::linkOcamlGC();
+ llvm::linkShadowStackGC();
+
+ (void) llvm::createBURRListDAGScheduler(NULL, llvm::CodeGenOpt::Default);
+ (void) llvm::createSourceListDAGScheduler(NULL,llvm::CodeGenOpt::Default);
+ (void) llvm::createHybridListDAGScheduler(NULL,llvm::CodeGenOpt::Default);
+ (void) llvm::createFastDAGScheduler(NULL, llvm::CodeGenOpt::Default);
+ (void) llvm::createDefaultScheduler(NULL, llvm::CodeGenOpt::Default);
+ (void) llvm::createVLIWDAGScheduler(NULL, llvm::CodeGenOpt::Default);
+
+ }
+ } ForceCodegenLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveInterval.h b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h
new file mode 100644
index 000000000000..a6008ab33761
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LiveInterval.h
@@ -0,0 +1,573 @@
+//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveRange and LiveInterval classes. Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live interval for register v if there is no instruction with number j' >= j
+// such that v is live at j' and there is no instruction with number i' < i such
+// that v is live at i'. In this implementation intervals can have holes,
+// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
+// individual range is represented as an instance of LiveRange, and the whole
+// interval is represented as an instance of LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
+#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 <cassert>
+#include <climits>
+
+namespace llvm {
+ class LiveIntervals;
+ class MachineInstr;
+ class MachineRegisterInfo;
+ class TargetRegisterInfo;
+ class raw_ostream;
+
+ /// VNInfo - Value Number Information.
+ /// This class holds information about a machine level values, including
+ /// definition and use points.
+ ///
+ class VNInfo {
+ private:
+ enum {
+ HAS_PHI_KILL = 1,
+ IS_PHI_DEF = 1 << 1,
+ IS_UNUSED = 1 << 2
+ };
+
+ unsigned char flags;
+
+ public:
+ typedef BumpPtrAllocator Allocator;
+
+ /// The ID number of this value.
+ unsigned id;
+
+ /// The index of the defining instruction.
+ SlotIndex def;
+
+ /// VNInfo constructor.
+ VNInfo(unsigned i, SlotIndex d)
+ : flags(0), id(i), def(d)
+ { }
+
+ /// VNInfo construtor, copies values from orig, except for the value number.
+ VNInfo(unsigned i, const VNInfo &orig)
+ : flags(orig.flags), id(i), def(orig.def)
+ { }
+
+ /// Copy from the parameter into this VNInfo.
+ void copyFrom(VNInfo &src) {
+ flags = src.flags;
+ def = src.def;
+ }
+
+ /// Used for copying value number info.
+ unsigned getFlags() const { return flags; }
+ void setFlags(unsigned flags) { this->flags = flags; }
+
+ /// Merge flags from another VNInfo
+ void mergeFlags(const VNInfo *VNI) {
+ flags = (flags | VNI->flags) & ~IS_UNUSED;
+ }
+
+ /// Returns true if one or more kills are PHI nodes.
+ /// Obsolete, do not use!
+ bool hasPHIKill() const { return flags & HAS_PHI_KILL; }
+ /// Set the PHI kill flag on this value.
+ void setHasPHIKill(bool hasKill) {
+ if (hasKill)
+ flags |= HAS_PHI_KILL;
+ else
+ flags &= ~HAS_PHI_KILL;
+ }
+
+ /// Returns true if this value is defined by a PHI instruction (or was,
+ /// PHI instrucions may have been eliminated).
+ bool isPHIDef() const { return flags & IS_PHI_DEF; }
+ /// Set the "phi def" flag on this value.
+ void setIsPHIDef(bool phiDef) {
+ if (phiDef)
+ flags |= IS_PHI_DEF;
+ else
+ flags &= ~IS_PHI_DEF;
+ }
+
+ /// Returns true if this value is unused.
+ bool isUnused() const { return flags & IS_UNUSED; }
+ /// Set the "is unused" flag on this value.
+ void setIsUnused(bool unused) {
+ if (unused)
+ flags |= IS_UNUSED;
+ else
+ flags &= ~IS_UNUSED;
+ }
+ };
+
+ /// LiveRange structure - This represents a simple register range in the
+ /// program, with an inclusive start point and an exclusive end point.
+ /// These ranges are rendered as [start,end).
+ struct LiveRange {
+ SlotIndex start; // Start point of the interval (inclusive)
+ SlotIndex end; // End point of the interval (exclusive)
+ VNInfo *valno; // identifier for the value contained in this interval.
+
+ LiveRange(SlotIndex S, SlotIndex E, VNInfo *V)
+ : start(S), end(E), valno(V) {
+
+ assert(S < E && "Cannot create empty or backwards range");
+ }
+
+ /// contains - Return true if the index is covered by this range.
+ ///
+ bool contains(SlotIndex I) const {
+ return start <= I && I < end;
+ }
+
+ /// containsRange - Return true if the given range, [S, E), is covered by
+ /// this range.
+ bool containsRange(SlotIndex S, SlotIndex E) const {
+ assert((S < E) && "Backwards interval?");
+ return (start <= S && S < end) && (start < E && E <= end);
+ }
+
+ bool operator<(const LiveRange &LR) const {
+ return start < LR.start || (start == LR.start && end < LR.end);
+ }
+ bool operator==(const LiveRange &LR) const {
+ return start == LR.start && end == LR.end;
+ }
+
+ void dump() const;
+ void print(raw_ostream &os) const;
+
+ private:
+ LiveRange(); // DO NOT IMPLEMENT
+ };
+
+ template <> struct isPodLike<LiveRange> { static const bool value = true; };
+
+ raw_ostream& operator<<(raw_ostream& os, const LiveRange &LR);
+
+
+ inline bool operator<(SlotIndex V, const LiveRange &LR) {
+ return V < LR.start;
+ }
+
+ inline bool operator<(const LiveRange &LR, SlotIndex V) {
+ return LR.start < V;
+ }
+
+ /// LiveInterval - This class represents some number of live ranges for a
+ /// register or value. This class also contains a bit of register allocator
+ /// state.
+ class LiveInterval {
+ public:
+
+ typedef SmallVector<LiveRange,4> Ranges;
+ typedef SmallVector<VNInfo*,4> VNInfoList;
+
+ const unsigned reg; // the register or stack slot of this interval.
+ float weight; // weight of this interval
+ Ranges ranges; // the ranges in which this register is live
+ VNInfoList valnos; // value#'s
+
+ struct InstrSlots {
+ enum {
+ LOAD = 0,
+ USE = 1,
+ DEF = 2,
+ STORE = 3,
+ NUM = 4
+ };
+
+ };
+
+ LiveInterval(unsigned Reg, float Weight)
+ : reg(Reg), weight(Weight) {}
+
+ typedef Ranges::iterator iterator;
+ iterator begin() { return ranges.begin(); }
+ iterator end() { return ranges.end(); }
+
+ typedef Ranges::const_iterator const_iterator;
+ const_iterator begin() const { return ranges.begin(); }
+ const_iterator end() const { return ranges.end(); }
+
+ typedef VNInfoList::iterator vni_iterator;
+ vni_iterator vni_begin() { return valnos.begin(); }
+ vni_iterator vni_end() { return valnos.end(); }
+
+ typedef VNInfoList::const_iterator const_vni_iterator;
+ const_vni_iterator vni_begin() const { return valnos.begin(); }
+ const_vni_iterator vni_end() const { return valnos.end(); }
+
+ /// advanceTo - Advance the specified iterator to point to the LiveRange
+ /// containing the specified position, or end() if the position is past the
+ /// end of the interval. If no LiveRange contains this position, but the
+ /// position is in a hole, this method returns an iterator pointing to the
+ /// LiveRange immediately after the hole.
+ iterator advanceTo(iterator I, SlotIndex Pos) {
+ assert(I != end());
+ if (Pos >= endIndex())
+ return end();
+ while (I->end <= Pos) ++I;
+ return I;
+ }
+
+ /// find - Return an iterator pointing to the first range that ends after
+ /// Pos, or end(). This is the same as advanceTo(begin(), Pos), but faster
+ /// when searching large intervals.
+ ///
+ /// If Pos is contained in a LiveRange, that range is returned.
+ /// If Pos is in a hole, the following LiveRange is returned.
+ /// If Pos is beyond endIndex, end() is returned.
+ iterator find(SlotIndex Pos);
+
+ const_iterator find(SlotIndex Pos) const {
+ return const_cast<LiveInterval*>(this)->find(Pos);
+ }
+
+ void clear() {
+ valnos.clear();
+ ranges.clear();
+ }
+
+ bool hasAtLeastOneValue() const { return !valnos.empty(); }
+
+ bool containsOneValue() const { return valnos.size() == 1; }
+
+ unsigned getNumValNums() const { return (unsigned)valnos.size(); }
+
+ /// getValNumInfo - Returns pointer to the specified val#.
+ ///
+ inline VNInfo *getValNumInfo(unsigned ValNo) {
+ return valnos[ValNo];
+ }
+ inline const VNInfo *getValNumInfo(unsigned ValNo) const {
+ return valnos[ValNo];
+ }
+
+ /// containsValue - Returns true if VNI belongs to this interval.
+ bool containsValue(const VNInfo *VNI) const {
+ return VNI && VNI->id < getNumValNums() && VNI == getValNumInfo(VNI->id);
+ }
+
+ /// getNextValue - Create a new value number and return it. MIIdx specifies
+ /// the instruction that defines the value number.
+ VNInfo *getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator) {
+ VNInfo *VNI =
+ new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), def);
+ valnos.push_back(VNI);
+ return VNI;
+ }
+
+ /// Create a copy of the given value. The new value will be identical except
+ /// for the Value number.
+ VNInfo *createValueCopy(const VNInfo *orig,
+ VNInfo::Allocator &VNInfoAllocator) {
+ VNInfo *VNI =
+ new (VNInfoAllocator) VNInfo((unsigned)valnos.size(), *orig);
+ valnos.push_back(VNI);
+ return VNI;
+ }
+
+ /// RenumberValues - Renumber all values in order of appearance and remove
+ /// unused values.
+ void RenumberValues(LiveIntervals &lis);
+
+ /// isOnlyLROfValNo - Return true if the specified live range is the only
+ /// one defined by the its val#.
+ bool isOnlyLROfValNo(const LiveRange *LR) {
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
+ const LiveRange *Tmp = I;
+ if (Tmp != LR && Tmp->valno == LR->valno)
+ return false;
+ }
+ return true;
+ }
+
+ /// MergeValueNumberInto - This method is called when two value nubmers
+ /// are found to be equivalent. This eliminates V1, replacing all
+ /// LiveRanges with the V1 value number with the V2 value number. This can
+ /// cause merging of V1/V2 values numbers and compaction of the value space.
+ VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2);
+
+ /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
+ /// in RHS into this live interval as the specified value number.
+ /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
+ /// current interval, it will replace the value numbers of the overlaped
+ /// live ranges with the specified value number.
+ void MergeRangesInAsValue(const LiveInterval &RHS, VNInfo *LHSValNo);
+
+ /// MergeValueInAsValue - Merge all of the live ranges of a specific val#
+ /// in RHS into this live interval as the specified value number.
+ /// The LiveRanges in RHS are allowed to overlap with LiveRanges in the
+ /// current interval, but only if the overlapping LiveRanges have the
+ /// specified value number.
+ 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.
+ SlotIndex beginIndex() const {
+ assert(!empty() && "Call to beginIndex() on empty interval.");
+ return ranges.front().start;
+ }
+
+ /// endNumber - return the maximum point of the interval of the whole,
+ /// exclusive.
+ SlotIndex endIndex() const {
+ assert(!empty() && "Call to endIndex() on empty interval.");
+ return ranges.back().end;
+ }
+
+ bool expiredAt(SlotIndex index) const {
+ return index >= endIndex();
+ }
+
+ bool liveAt(SlotIndex index) const {
+ const_iterator r = find(index);
+ return r != end() && r->start <= index;
+ }
+
+ /// killedAt - Return true if a live range ends at index. Note that the kill
+ /// point is not contained in the half-open live range. It is usually the
+ /// getDefIndex() slot following its last use.
+ bool killedAt(SlotIndex index) const {
+ const_iterator r = find(index.getRegSlot(true));
+ 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 {
+ const_iterator I = FindLiveRangeContaining(Idx);
+ return I == end() ? 0 : &*I;
+ }
+
+ /// getLiveRangeContaining - Return the live range that contains the
+ /// specified index, or null if there is none.
+ LiveRange *getLiveRangeContaining(SlotIndex Idx) {
+ iterator I = FindLiveRangeContaining(Idx);
+ return I == end() ? 0 : &*I;
+ }
+
+ const LiveRange *getLiveRangeBefore(SlotIndex Idx) const {
+ return getLiveRangeContaining(Idx.getPrevSlot());
+ }
+
+ LiveRange *getLiveRangeBefore(SlotIndex Idx) {
+ return getLiveRangeContaining(Idx.getPrevSlot());
+ }
+
+ /// getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
+ VNInfo *getVNInfoAt(SlotIndex Idx) const {
+ const_iterator I = FindLiveRangeContaining(Idx);
+ return I == end() ? 0 : I->valno;
+ }
+
+ /// getVNInfoBefore - Return the VNInfo that is live up to but not
+ /// necessarilly including Idx, or NULL. Use this to find the reaching def
+ /// used by an instruction at this SlotIndex position.
+ VNInfo *getVNInfoBefore(SlotIndex Idx) const {
+ const_iterator I = FindLiveRangeContaining(Idx.getPrevSlot());
+ return I == end() ? 0 : I->valno;
+ }
+
+ /// FindLiveRangeContaining - Return an iterator to the live range that
+ /// contains the specified index, or end() if there is none.
+ iterator FindLiveRangeContaining(SlotIndex Idx) {
+ iterator I = find(Idx);
+ return I != end() && I->start <= Idx ? I : end();
+ }
+
+ const_iterator FindLiveRangeContaining(SlotIndex Idx) const {
+ const_iterator I = find(Idx);
+ return I != end() && I->start <= Idx ? I : end();
+ }
+
+ /// findDefinedVNInfo - Find the by the specified
+ /// index (register interval) or defined
+ VNInfo *findDefinedVNInfoForRegInt(SlotIndex Idx) const;
+
+
+ /// overlaps - Return true if the intersection of the two live intervals is
+ /// not empty.
+ bool overlaps(const LiveInterval& other) const {
+ if (other.empty())
+ return false;
+ return overlapsFrom(other, other.begin());
+ }
+
+ /// overlaps - Return true if the live interval overlaps a range specified
+ /// by [Start, End).
+ bool overlaps(SlotIndex Start, SlotIndex End) const;
+
+ /// overlapsFrom - Return true if the intersection of the two live intervals
+ /// is not empty. The specified iterator is a hint that we can begin
+ /// scanning the Other interval starting at I.
+ bool overlapsFrom(const LiveInterval& other, const_iterator I) const;
+
+ /// addRange - Add the specified LiveRange to this interval, merging
+ /// intervals as appropriate. This returns an iterator to the inserted live
+ /// range (which may have grown since it was inserted.
+ void addRange(LiveRange LR) {
+ addRangeFrom(LR, ranges.begin());
+ }
+
+ /// extendInBlock - If this interval is live before Kill in the basic block
+ /// that starts at StartIdx, extend it to be live up to Kill, and return
+ /// the value. If there is no live range before Kill, return NULL.
+ VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill);
+
+ /// join - Join two live intervals (this, and other) together. This applies
+ /// mappings to the value numbers in the LHS/RHS intervals as specified. If
+ /// the intervals are not joinable, this aborts.
+ void join(LiveInterval &Other,
+ const int *ValNoAssignments,
+ const int *RHSValNoAssignments,
+ SmallVector<VNInfo*, 16> &NewVNInfo,
+ MachineRegisterInfo *MRI);
+
+ /// isInOneLiveRange - Return true if the range specified is entirely in the
+ /// a single LiveRange of the live interval.
+ bool isInOneLiveRange(SlotIndex Start, SlotIndex End) const {
+ const_iterator r = find(Start);
+ return r != end() && r->containsRange(Start, End);
+ }
+
+ /// removeRange - Remove the specified range from this interval. Note that
+ /// the range must be a single LiveRange in its entirety.
+ void removeRange(SlotIndex Start, SlotIndex End,
+ bool RemoveDeadValNo = false);
+
+ void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
+ removeRange(LR.start, LR.end, RemoveDeadValNo);
+ }
+
+ /// removeValNo - Remove all the ranges defined by the specified value#.
+ /// Also remove the value# from value# list.
+ void removeValNo(VNInfo *ValNo);
+
+ /// getSize - Returns the sum of sizes of all the LiveRange's.
+ ///
+ unsigned getSize() const;
+
+ /// Returns true if the live interval is zero length, i.e. no live ranges
+ /// span instructions. It doesn't pay to spill such an interval.
+ bool isZeroLength(SlotIndexes *Indexes) const {
+ for (const_iterator i = begin(), e = end(); i != e; ++i)
+ if (Indexes->getNextNonNullIndex(i->start).getBaseIndex() <
+ i->end.getBaseIndex())
+ return false;
+ return true;
+ }
+
+ /// isSpillable - Can this interval be spilled?
+ bool isSpillable() const {
+ return weight != HUGE_VALF;
+ }
+
+ /// markNotSpillable - Mark interval as not spillable
+ void markNotSpillable() {
+ weight = HUGE_VALF;
+ }
+
+ /// ComputeJoinedWeight - Set the weight of a live interval after
+ /// Other has been merged into it.
+ void ComputeJoinedWeight(const LiveInterval &Other);
+
+ bool operator<(const LiveInterval& other) const {
+ const SlotIndex &thisIndex = beginIndex();
+ const SlotIndex &otherIndex = other.beginIndex();
+ return (thisIndex < otherIndex ||
+ (thisIndex == otherIndex && reg < other.reg));
+ }
+
+ void print(raw_ostream &OS, const TargetRegisterInfo *TRI = 0) const;
+ void dump() const;
+
+ private:
+
+ Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
+ void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
+ Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
+ void markValNoForDeletion(VNInfo *V);
+
+ LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
+
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const LiveInterval &LI) {
+ LI.print(OS);
+ return OS;
+ }
+
+ /// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
+ /// LiveInterval into equivalence clases of connected components. A
+ /// LiveInterval that has multiple connected components can be broken into
+ /// multiple LiveIntervals.
+ ///
+ /// Given a LiveInterval that may have multiple connected components, run:
+ ///
+ /// unsigned numComps = ConEQ.Classify(LI);
+ /// if (numComps > 1) {
+ /// // allocate numComps-1 new LiveIntervals into LIS[1..]
+ /// ConEQ.Distribute(LIS);
+ /// }
+
+ class ConnectedVNInfoEqClasses {
+ LiveIntervals &LIS;
+ IntEqClasses EqClass;
+
+ // Note that values a and b are connected.
+ void Connect(unsigned a, unsigned b);
+
+ unsigned Renumber();
+
+ public:
+ explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {}
+
+ /// Classify - Classify the values in LI into connected components.
+ /// Return the number of connected components.
+ unsigned Classify(const LiveInterval *LI);
+
+ /// getEqClass - Classify creates equivalence classes numbered 0..N. Return
+ /// the equivalence class assigned the VNI.
+ unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; }
+
+ /// Distribute - Distribute values in LIV[0] into a separate LiveInterval
+ /// for each connected component. LIV must have a LiveInterval for each
+ /// connected component. The LiveIntervals in Liv[1..] must be empty.
+ /// Instructions using LIV[0] are rewritten.
+ void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI);
+
+ };
+
+}
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
new file mode 100644
index 000000000000..76201c96f915
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -0,0 +1,407 @@
+//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveInterval analysis pass. Given some numbering of
+// each the machine instructions (in this implemention depth-first order) an
+// interval [i, j) is said to be a live interval for register v if there is no
+// instruction with number j' > j such that v is live at j' and there is no
+// instruction with number i' < i such that v is live at i'. In this
+// implementation intervals can have holes, i.e. an interval might look like
+// [1,20), [50,65), [1000,1001).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_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/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include <cmath>
+#include <iterator>
+
+namespace llvm {
+
+ class AliasAnalysis;
+ class LiveVariables;
+ class MachineLoopInfo;
+ class TargetRegisterInfo;
+ class MachineRegisterInfo;
+ class TargetInstrInfo;
+ class TargetRegisterClass;
+ class VirtRegMap;
+
+ class LiveIntervals : public MachineFunctionPass {
+ MachineFunction* mf_;
+ MachineRegisterInfo* mri_;
+ const TargetMachine* tm_;
+ const TargetRegisterInfo* tri_;
+ const TargetInstrInfo* tii_;
+ AliasAnalysis *aa_;
+ LiveVariables* lv_;
+ SlotIndexes* indexes_;
+
+ /// Special pool allocator for VNInfo's (LiveInterval val#).
+ ///
+ VNInfo::Allocator VNInfoAllocator;
+
+ typedef DenseMap<unsigned, LiveInterval*> Reg2IntervalMap;
+ Reg2IntervalMap r2iMap_;
+
+ /// 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.
+ SmallVector<SlotIndex, 8> RegMaskSlots;
+
+ /// RegMaskBits - This vector is parallel to RegMaskSlots, it holds a
+ /// pointer to the corresponding register mask. This pointer can be
+ /// recomputed as:
+ ///
+ /// MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]);
+ /// unsigned OpNum = findRegMaskOperand(MI);
+ /// RegMaskBits[N] = MI->getOperand(OpNum).getRegMask();
+ ///
+ /// This is kept in a separate vector partly because some standard
+ /// libraries don't support lower_bound() with mixed objects, partly to
+ /// improve locality when searching in RegMaskSlots.
+ /// Also see the comment in LiveInterval::find().
+ SmallVector<const uint32_t*, 8> RegMaskBits;
+
+ /// For each basic block number, keep (begin, size) pairs indexing into the
+ /// RegMaskSlots and RegMaskBits arrays.
+ /// Note that basic block numbers may not be layout contiguous, that's why
+ /// we can't just keep track of the first register mask in each basic
+ /// block.
+ SmallVector<std::pair<unsigned, unsigned>, 8> RegMaskBlocks;
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveIntervals() : MachineFunctionPass(ID) {
+ initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
+ }
+
+ // Calculate the spill weight to assign to a single instruction.
+ static float getSpillWeight(bool isDef, bool isUse, unsigned loopDepth);
+
+ typedef Reg2IntervalMap::iterator iterator;
+ typedef Reg2IntervalMap::const_iterator const_iterator;
+ const_iterator begin() const { return r2iMap_.begin(); }
+ const_iterator end() const { return r2iMap_.end(); }
+ iterator begin() { return r2iMap_.begin(); }
+ iterator end() { return r2iMap_.end(); }
+ unsigned getNumIntervals() const { return (unsigned)r2iMap_.size(); }
+
+ LiveInterval &getInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return *I->second;
+ }
+
+ const LiveInterval &getInterval(unsigned reg) const {
+ Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return *I->second;
+ }
+
+ bool hasInterval(unsigned reg) const {
+ return r2iMap_.count(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);
+ }
+
+ /// getScaledIntervalSize - get the size of an interval in "units,"
+ /// where every function is composed of one thousand units. This
+ /// measure scales properly with empty index slots in the function.
+ double getScaledIntervalSize(LiveInterval& I) {
+ return (1000.0 * I.getSize()) / indexes_->getIndexesLength();
+ }
+
+ /// getFuncInstructionCount - Return the number of instructions in the
+ /// current function.
+ unsigned getFuncInstructionCount() {
+ return indexes_->getFunctionSize();
+ }
+
+ /// getApproximateInstructionCount - computes an estimate of the number
+ /// of instructions in a given LiveInterval.
+ unsigned getApproximateInstructionCount(LiveInterval& I) {
+ double IntervalPercentage = getScaledIntervalSize(I) / 1000.0;
+ return (unsigned)(IntervalPercentage * indexes_->getFunctionSize());
+ }
+
+ // Interval creation
+ LiveInterval &getOrCreateInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ if (I == r2iMap_.end())
+ I = r2iMap_.insert(std::make_pair(reg, createInterval(reg))).first;
+ return *I->second;
+ }
+
+ /// dupInterval - Duplicate a live interval. The caller is responsible for
+ /// managing the allocated memory.
+ LiveInterval *dupInterval(LiveInterval *li);
+
+ /// addLiveRangeToEndOfBlock - Given a register and an instruction,
+ /// adds a live range from that instruction to the end of its MBB.
+ LiveRange addLiveRangeToEndOfBlock(unsigned reg,
+ MachineInstr* startInst);
+
+ /// shrinkToUses - After removing some uses of a register, shrink its live
+ /// range to just the remaining uses. This method does not compute reaching
+ /// defs for new uses, and it doesn't remove dead defs.
+ /// Dead PHIDef values are marked as unused.
+ /// New dead machine instructions are added to the dead vector.
+ /// Return true if the interval may have been separated into multiple
+ /// connected components.
+ bool shrinkToUses(LiveInterval *li,
+ SmallVectorImpl<MachineInstr*> *dead = 0);
+
+ // Interval removal
+
+ void removeInterval(unsigned Reg) {
+ DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.find(Reg);
+ delete I->second;
+ r2iMap_.erase(I);
+ }
+
+ SlotIndexes *getSlotIndexes() const {
+ return indexes_;
+ }
+
+ /// isNotInMIMap - returns true if the specified machine instr has been
+ /// removed or was never entered in the map.
+ bool isNotInMIMap(const MachineInstr* Instr) const {
+ return !indexes_->hasIndex(Instr);
+ }
+
+ /// Returns the base index of the given instruction.
+ SlotIndex getInstructionIndex(const MachineInstr *instr) const {
+ return indexes_->getInstructionIndex(instr);
+ }
+
+ /// Returns the instruction associated with the given index.
+ MachineInstr* getInstructionFromIndex(SlotIndex index) const {
+ return indexes_->getInstructionFromIndex(index);
+ }
+
+ /// Return the first index in the given basic block.
+ SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+ return indexes_->getMBBStartIdx(mbb);
+ }
+
+ /// Return the last index in the given basic block.
+ SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
+ return indexes_->getMBBEndIdx(mbb);
+ }
+
+ bool isLiveInToMBB(const LiveInterval &li,
+ const MachineBasicBlock *mbb) const {
+ return li.liveAt(getMBBStartIdx(mbb));
+ }
+
+ bool isLiveOutOfMBB(const LiveInterval &li,
+ const MachineBasicBlock *mbb) const {
+ return li.liveAt(getMBBEndIdx(mbb).getPrevSlot());
+ }
+
+ MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
+ return indexes_->getMBBFromIndex(index);
+ }
+
+ SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
+ return indexes_->insertMachineInstrInMaps(MI);
+ }
+
+ void RemoveMachineInstrFromMaps(MachineInstr *MI) {
+ indexes_->removeMachineInstrFromMaps(MI);
+ }
+
+ void ReplaceMachineInstrInMaps(MachineInstr *MI, MachineInstr *NewMI) {
+ indexes_->replaceMachineInstrInMaps(MI, NewMI);
+ }
+
+ bool findLiveInMBBs(SlotIndex Start, SlotIndex End,
+ SmallVectorImpl<MachineBasicBlock*> &MBBs) const {
+ return indexes_->findLiveInMBBs(Start, End, MBBs);
+ }
+
+ VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(raw_ostream &O, const Module* = 0) const;
+
+ /// isReMaterializable - Returns true if every definition of MI of every
+ /// val# of the specified interval is re-materializable. Also returns true
+ /// by reference if all of the defs are load instructions.
+ bool isReMaterializable(const LiveInterval &li,
+ const SmallVectorImpl<LiveInterval*> *SpillIs,
+ bool &isLoad);
+
+ /// intervalIsInOneMBB - If LI is confined to a single basic block, return
+ /// a pointer to that block. If LI is live in to or out of any block,
+ /// return NULL.
+ MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const;
+
+ /// addKillFlags - Add kill flags to any instruction that kills a virtual
+ /// register.
+ void addKillFlags();
+
+ /// handleMove - call this method to notify LiveIntervals that
+ /// 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);
+
+ /// moveIntoBundle - Update intervals for operands of MI so that they
+ /// begin/end on the SlotIndex for BundleStart.
+ ///
+ /// 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);
+
+ // Register mask functions.
+ //
+ // Machine instructions may use a register mask operand to indicate that a
+ // large number of registers are clobbered by the instruction. This is
+ // typically used for calls.
+ //
+ // For compile time performance reasons, these clobbers are not recorded in
+ // the live intervals for individual physical registers. Instead,
+ // LiveIntervalAnalysis maintains a sorted list of instructions with
+ // register mask operands.
+
+ /// getRegMaskSlots - Returns a sorted array of slot indices of all
+ /// instructions with register mask operands.
+ ArrayRef<SlotIndex> getRegMaskSlots() const { return RegMaskSlots; }
+
+ /// getRegMaskSlotsInBlock - Returns a sorted array of slot indices of all
+ /// instructions with register mask operands in the basic block numbered
+ /// MBBNum.
+ ArrayRef<SlotIndex> getRegMaskSlotsInBlock(unsigned MBBNum) const {
+ std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
+ return getRegMaskSlots().slice(P.first, P.second);
+ }
+
+ /// getRegMaskBits() - Returns an array of register mask pointers
+ /// corresponding to getRegMaskSlots().
+ ArrayRef<const uint32_t*> getRegMaskBits() const { return RegMaskBits; }
+
+ /// getRegMaskBitsInBlock - Returns an array of mask pointers corresponding
+ /// to getRegMaskSlotsInBlock(MBBNum).
+ ArrayRef<const uint32_t*> getRegMaskBitsInBlock(unsigned MBBNum) const {
+ std::pair<unsigned, unsigned> P = RegMaskBlocks[MBBNum];
+ return getRegMaskBits().slice(P.first, P.second);
+ }
+
+ /// checkRegMaskInterference - Test if LI is live across any register mask
+ /// instructions, and compute a bit mask of physical registers that are not
+ /// clobbered by any of them.
+ ///
+ /// Returns false if LI doesn't cross any register mask instructions. In
+ /// that case, the bit vector is not filled in.
+ bool checkRegMaskInterference(LiveInterval &LI,
+ BitVector &UsableRegs);
+
+ private:
+ /// computeIntervals - Compute live intervals.
+ void computeIntervals();
+
+ /// handleRegisterDef - update intervals for a register def
+ /// (calls handlePhysicalRegisterDef and
+ /// handleVirtualRegisterDef)
+ void handleRegisterDef(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator MI,
+ SlotIndex MIIdx,
+ MachineOperand& MO, unsigned MOIdx);
+
+ /// isPartialRedef - Return true if the specified def at the specific index
+ /// is partially re-defining the specified live interval. A common case of
+ /// this is a definition of the sub-register.
+ bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
+ LiveInterval &interval);
+
+ /// handleVirtualRegisterDef - update intervals for a virtual
+ /// register def
+ void handleVirtualRegisterDef(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator MI,
+ SlotIndex MIIdx, MachineOperand& MO,
+ unsigned MOIdx,
+ LiveInterval& interval);
+
+ /// handlePhysicalRegisterDef - update intervals for a physical register
+ /// def.
+ void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
+ MachineBasicBlock::iterator mi,
+ SlotIndex MIIdx, MachineOperand& MO,
+ LiveInterval &interval);
+
+ /// handleLiveInRegister - Create interval for a livein register.
+ void handleLiveInRegister(MachineBasicBlock* mbb,
+ SlotIndex MIIdx,
+ LiveInterval &interval);
+
+ /// getReMatImplicitUse - If the remat definition MI has one (for now, we
+ /// only allow one) virtual register operand, then its uses are implicitly
+ /// using the register. Returns the virtual register.
+ unsigned getReMatImplicitUse(const LiveInterval &li,
+ MachineInstr *MI) const;
+
+ /// isValNoAvailableAt - Return true if the val# of the specified interval
+ /// which reaches the given instruction also reaches the specified use
+ /// index.
+ bool isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
+ SlotIndex UseIdx) const;
+
+ /// isReMaterializable - Returns true if the definition MI of the specified
+ /// val# of the specified interval is re-materializable. Also returns true
+ /// by reference if the def is a load.
+ bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
+ MachineInstr *MI,
+ const SmallVectorImpl<LiveInterval*> *SpillIs,
+ bool &isLoad);
+
+ static LiveInterval* createInterval(unsigned Reg);
+
+ void printInstrs(raw_ostream &O) const;
+ void dumpInstrs() const;
+
+ class HMEditor;
+ };
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h
new file mode 100644
index 000000000000..57a619389fa5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LiveRangeEdit.h
@@ -0,0 +1,207 @@
+//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The LiveRangeEdit class represents changes done to a virtual register when it
+// is spilled or split.
+//
+// The parent register is never changed. Instead, a number of new virtual
+// registers are created and added to the newRegs vector.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H
+#define LLVM_CODEGEN_LIVERANGEEDIT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class LiveIntervals;
+class MachineLoopInfo;
+class MachineRegisterInfo;
+class VirtRegMap;
+
+class LiveRangeEdit {
+public:
+ /// Callback methods for LiveRangeEdit owners.
+ class Delegate {
+ virtual void anchor();
+ public:
+ /// Called immediately before erasing a dead machine instruction.
+ virtual void LRE_WillEraseInstruction(MachineInstr *MI) {}
+
+ /// Called when a virtual register is no longer used. Return false to defer
+ /// its deletion from LiveIntervals.
+ virtual bool LRE_CanEraseVirtReg(unsigned) { return true; }
+
+ /// Called before shrinking the live range of a virtual register.
+ virtual void LRE_WillShrinkVirtReg(unsigned) {}
+
+ /// Called after cloning a virtual register.
+ /// This is used for new registers representing connected components of Old.
+ virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
+
+ virtual ~Delegate() {}
+ };
+
+private:
+ LiveInterval &parent_;
+ SmallVectorImpl<LiveInterval*> &newRegs_;
+ MachineRegisterInfo &MRI;
+ LiveIntervals &LIS;
+ VirtRegMap *VRM;
+ const TargetInstrInfo &TII;
+ Delegate *const delegate_;
+
+ /// firstNew_ - Index of the first register added to newRegs_.
+ const unsigned firstNew_;
+
+ /// scannedRemattable_ - true when remattable values have been identified.
+ bool scannedRemattable_;
+
+ /// remattable_ - Values defined by remattable instructions as identified by
+ /// tii.isTriviallyReMaterializable().
+ SmallPtrSet<const VNInfo*,4> remattable_;
+
+ /// rematted_ - Values that were actually rematted, and so need to have their
+ /// live range trimmed or entirely removed.
+ SmallPtrSet<const VNInfo*,4> rematted_;
+
+ /// scanRemattable - Identify the parent_ values that may rematerialize.
+ void scanRemattable(AliasAnalysis *aa);
+
+ /// allUsesAvailableAt - Return true if all registers used by OrigMI at
+ /// OrigIdx are also available with the same value at UseIdx.
+ bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
+ SlotIndex UseIdx);
+
+ /// foldAsLoad - If LI has a single use and a single def that can be folded as
+ /// a load, eliminate the register by folding the def into the use.
+ bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr*> &Dead);
+
+public:
+ /// Create a LiveRangeEdit for breaking down parent into smaller pieces.
+ /// @param parent The register being spilled or split.
+ /// @param newRegs List to receive any new registers created. This needn't be
+ /// empty initially, any existing registers are ignored.
+ /// @param MF The MachineFunction the live range edit is taking place in.
+ /// @param lis The collection of all live intervals in this function.
+ /// @param vrm Map of virtual registers to physical registers for this
+ /// function. If NULL, no virtual register map updates will
+ /// be done. This could be the case if called before Regalloc.
+ LiveRangeEdit(LiveInterval &parent,
+ SmallVectorImpl<LiveInterval*> &newRegs,
+ MachineFunction &MF,
+ LiveIntervals &lis,
+ VirtRegMap *vrm,
+ Delegate *delegate = 0)
+ : parent_(parent), newRegs_(newRegs),
+ MRI(MF.getRegInfo()), LIS(lis), VRM(vrm),
+ TII(*MF.getTarget().getInstrInfo()),
+ delegate_(delegate),
+ firstNew_(newRegs.size()),
+ scannedRemattable_(false) {}
+
+ LiveInterval &getParent() const { return parent_; }
+ unsigned getReg() const { return parent_.reg; }
+
+ /// Iterator for accessing the new registers added by this edit.
+ typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator;
+ iterator begin() const { return newRegs_.begin()+firstNew_; }
+ iterator end() const { return newRegs_.end(); }
+ unsigned size() const { return newRegs_.size()-firstNew_; }
+ bool empty() const { return size() == 0; }
+ LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; }
+
+ ArrayRef<LiveInterval*> regs() const {
+ return makeArrayRef(newRegs_).slice(firstNew_);
+ }
+
+ /// createFrom - Create a new virtual register based on OldReg.
+ LiveInterval &createFrom(unsigned OldReg);
+
+ /// create - Create a new register with the same class and original slot as
+ /// parent.
+ LiveInterval &create() {
+ return createFrom(getReg());
+ }
+
+ /// anyRematerializable - Return true if any parent values may be
+ /// rematerializable.
+ /// This function must be called before any rematerialization is attempted.
+ bool anyRematerializable(AliasAnalysis*);
+
+ /// checkRematerializable - Manually add VNI to the list of rematerializable
+ /// values if DefMI may be rematerializable.
+ bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI,
+ AliasAnalysis*);
+
+ /// Remat - Information needed to rematerialize at a specific location.
+ struct Remat {
+ VNInfo *ParentVNI; // parent_'s value at the remat location.
+ MachineInstr *OrigMI; // Instruction defining ParentVNI.
+ explicit Remat(VNInfo *ParentVNI) : ParentVNI(ParentVNI), OrigMI(0) {}
+ };
+
+ /// canRematerializeAt - Determine if ParentVNI can be rematerialized at
+ /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI.
+ /// When cheapAsAMove is set, only cheap remats are allowed.
+ bool canRematerializeAt(Remat &RM,
+ SlotIndex UseIdx,
+ bool cheapAsAMove);
+
+ /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
+ /// instruction into MBB before MI. The new instruction is mapped, but
+ /// liveness is not updated.
+ /// Return the SlotIndex of the new instruction.
+ SlotIndex rematerializeAt(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg,
+ const Remat &RM,
+ const TargetRegisterInfo&,
+ bool Late = false);
+
+ /// markRematerialized - explicitly mark a value as rematerialized after doing
+ /// it manually.
+ void markRematerialized(const VNInfo *ParentVNI) {
+ rematted_.insert(ParentVNI);
+ }
+
+ /// didRematerialize - Return true if ParentVNI was rematerialized anywhere.
+ bool didRematerialize(const VNInfo *ParentVNI) const {
+ return rematted_.count(ParentVNI);
+ }
+
+ /// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
+ /// to erase it from LIS.
+ void eraseVirtReg(unsigned Reg);
+
+ /// eliminateDeadDefs - Try to delete machine instructions that are now dead
+ /// (allDefsAreDead returns true). This may cause live intervals to be trimmed
+ /// and further dead efs to be eliminated.
+ /// RegsBeingSpilled lists registers currently being spilled by the register
+ /// allocator. These registers should not be split into new intervals
+ /// as currently those new intervals are not guaranteed to spill.
+ void eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
+ ArrayRef<unsigned> RegsBeingSpilled
+ = ArrayRef<unsigned>());
+
+ /// calculateRegClassAndHint - Recompute register class and hint for each new
+ /// register.
+ void calculateRegClassAndHint(MachineFunction&,
+ const MachineLoopInfo&);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h
new file mode 100644
index 000000000000..86c4d7c11067
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -0,0 +1,99 @@
+//===-- LiveStackAnalysis.h - Live Stack Slot Analysis ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the live stack slot analysis pass. It is analogous to
+// live interval analysis except it's analyzing liveness of stack slots rather
+// than registers.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/Allocator.h"
+#include <map>
+
+namespace llvm {
+
+ class LiveStacks : public MachineFunctionPass {
+ const TargetRegisterInfo *TRI;
+
+ /// Special pool allocator for VNInfo's (LiveInterval val#).
+ ///
+ VNInfo::Allocator VNInfoAllocator;
+
+ /// S2IMap - Stack slot indices to live interval mapping.
+ ///
+ typedef std::map<int, LiveInterval> SS2IntervalMap;
+ SS2IntervalMap S2IMap;
+
+ /// S2RCMap - Stack slot indices to register class mapping.
+ std::map<int, const TargetRegisterClass*> S2RCMap;
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveStacks() : MachineFunctionPass(ID) {
+ initializeLiveStacksPass(*PassRegistry::getPassRegistry());
+ }
+
+ typedef SS2IntervalMap::iterator iterator;
+ typedef SS2IntervalMap::const_iterator const_iterator;
+ const_iterator begin() const { return S2IMap.begin(); }
+ const_iterator end() const { return S2IMap.end(); }
+ iterator begin() { return S2IMap.begin(); }
+ iterator end() { return S2IMap.end(); }
+
+ unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
+
+ LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);
+
+ LiveInterval &getInterval(int Slot) {
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ SS2IntervalMap::iterator I = S2IMap.find(Slot);
+ assert(I != S2IMap.end() && "Interval does not exist for stack slot");
+ return I->second;
+ }
+
+ const LiveInterval &getInterval(int Slot) const {
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
+ assert(I != S2IMap.end() && "Interval does not exist for stack slot");
+ return I->second;
+ }
+
+ bool hasInterval(int Slot) const {
+ return S2IMap.count(Slot);
+ }
+
+ const TargetRegisterClass *getIntervalRegClass(int Slot) const {
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ std::map<int, const TargetRegisterClass*>::const_iterator
+ I = S2RCMap.find(Slot);
+ assert(I != S2RCMap.end() &&
+ "Register class info does not exist for stack slot");
+ return I->second;
+ }
+
+ VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(raw_ostream &O, const Module* = 0) const;
+ };
+}
+
+#endif /* LLVM_CODEGEN_LIVESTACK_ANALYSIS_H */
diff --git a/contrib/llvm/include/llvm/CodeGen/LiveVariables.h b/contrib/llvm/include/llvm/CodeGen/LiveVariables.h
new file mode 100644
index 000000000000..d4bb409e0605
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/LiveVariables.h
@@ -0,0 +1,315 @@
+//===-- llvm/CodeGen/LiveVariables.h - Live Variable Analysis ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveVariables analysis pass. For each machine
+// instruction in the function, this pass calculates the set of registers that
+// are immediately dead after the instruction (i.e., the instruction calculates
+// the value, but it is never used) and the set of registers that are used by
+// the instruction, but are never used after the instruction (i.e., they are
+// killed).
+//
+// This class computes live variables using a sparse implementation based on
+// the machine code SSA form. This class computes live variable information for
+// each virtual and _register allocatable_ physical register in a function. It
+// uses the dominance properties of SSA form to efficiently compute live
+// variables for virtual registers, and assumes that physical registers are only
+// live within a single basic block (allowing it to do a single local analysis
+// to resolve physical register lifetimes in each basic block). If a physical
+// register is not register allocatable, it is not tracked. This is useful for
+// things like the stack pointer and condition codes.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class MachineRegisterInfo;
+class TargetRegisterInfo;
+
+class LiveVariables : public MachineFunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveVariables() : MachineFunctionPass(ID) {
+ initializeLiveVariablesPass(*PassRegistry::getPassRegistry());
+ }
+
+ /// VarInfo - This represents the regions where a virtual register is live in
+ /// the program. We represent this with three different pieces of
+ /// information: the set of blocks in which the instruction is live
+ /// throughout, the set of blocks in which the instruction is actually used,
+ /// and the set of non-phi instructions that are the last users of the value.
+ ///
+ /// In the common case where a value is defined and killed in the same block,
+ /// There is one killing instruction, and AliveBlocks is empty.
+ ///
+ /// Otherwise, the value is live out of the block. If the value is live
+ /// throughout any blocks, these blocks are listed in AliveBlocks. Blocks
+ /// where the liveness range ends are not included in AliveBlocks, instead
+ /// being captured by the Kills set. In these blocks, the value is live into
+ /// the block (unless the value is defined and killed in the same block) and
+ /// lives until the specified instruction. Note that there cannot ever be a
+ /// value whose Kills set contains two instructions from the same basic block.
+ ///
+ /// PHI nodes complicate things a bit. If a PHI node is the last user of a
+ /// value in one of its predecessor blocks, it is not listed in the kills set,
+ /// but does include the predecessor block in the AliveBlocks set (unless that
+ /// block also defines the value). This leads to the (perfectly sensical)
+ /// situation where a value is defined in a block, and the last use is a phi
+ /// node in the successor. In this case, AliveBlocks is empty (the value is
+ /// not live across any blocks) and Kills is empty (phi nodes are not
+ /// included). This is sensical because the value must be live to the end of
+ /// the block, but is not live in any successor blocks.
+ struct VarInfo {
+ /// AliveBlocks - Set of blocks in which this value is alive completely
+ /// through. This is a bit set which uses the basic block number as an
+ /// index.
+ ///
+ SparseBitVector<> AliveBlocks;
+
+ /// Kills - List of MachineInstruction's which are the last use of this
+ /// virtual register (kill it) in their basic block.
+ ///
+ std::vector<MachineInstr*> Kills;
+
+ /// removeKill - Delete a kill corresponding to the specified
+ /// machine instruction. Returns true if there was a kill
+ /// corresponding to this instruction, false otherwise.
+ bool removeKill(MachineInstr *MI) {
+ std::vector<MachineInstr*>::iterator
+ I = std::find(Kills.begin(), Kills.end(), MI);
+ if (I == Kills.end())
+ return false;
+ Kills.erase(I);
+ return true;
+ }
+
+ /// findKill - Find a kill instruction in MBB. Return NULL if none is found.
+ MachineInstr *findKill(const MachineBasicBlock *MBB) const;
+
+ /// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
+ /// MBB, or it is killed in MBB. If Reg is only used by PHI instructions in
+ /// MBB, it is not considered live in.
+ bool isLiveIn(const MachineBasicBlock &MBB,
+ unsigned Reg,
+ MachineRegisterInfo &MRI);
+
+ void dump() const;
+ };
+
+private:
+ /// VirtRegInfo - This list is a mapping from virtual register number to
+ /// variable information.
+ ///
+ IndexedMap<VarInfo, VirtReg2IndexFunctor> VirtRegInfo;
+
+ /// PHIJoins - list of virtual registers that are PHI joins. These registers
+ /// may have multiple definitions, and they require special handling when
+ /// building live intervals.
+ SparseBitVector<> PHIJoins;
+
+ /// ReservedRegisters - This vector keeps track of which registers
+ /// are reserved register which are not allocatable by the target machine.
+ /// We can not track liveness for values that are in this set.
+ ///
+ BitVector ReservedRegisters;
+
+private: // Intermediate data structures
+ MachineFunction *MF;
+
+ MachineRegisterInfo* MRI;
+
+ const TargetRegisterInfo *TRI;
+
+ // PhysRegInfo - Keep track of which instruction was the last def of a
+ // physical register. This is a purely local property, because all physical
+ // register references are presumed dead across basic blocks.
+ MachineInstr **PhysRegDef;
+
+ // PhysRegInfo - Keep track of which instruction was the last use of a
+ // physical register. This is a purely local property, because all physical
+ // register references are presumed dead across basic blocks.
+ MachineInstr **PhysRegUse;
+
+ SmallVector<unsigned, 4> *PHIVarInfo;
+
+ // DistanceMap - Keep track the distance of a MI from the start of the
+ // current basic block.
+ DenseMap<MachineInstr*, unsigned> DistanceMap;
+
+ /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
+ /// uses. Pay special attention to the sub-register uses which may come below
+ /// the last use of the whole register.
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
+
+ /// HandleRegMask - Call HandlePhysRegKill for all registers clobbered by Mask.
+ void HandleRegMask(const MachineOperand&);
+
+ void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
+ void HandlePhysRegDef(unsigned Reg, MachineInstr *MI,
+ SmallVector<unsigned, 4> &Defs);
+ void UpdatePhysRegDefs(MachineInstr *MI, SmallVector<unsigned, 4> &Defs);
+
+ /// FindLastRefOrPartRef - Return the last reference or partial reference of
+ /// the specified register.
+ MachineInstr *FindLastRefOrPartRef(unsigned Reg);
+
+ /// FindLastPartialDef - Return the last partial def of the specified
+ /// register. Also returns the sub-registers that're defined by the
+ /// instruction.
+ MachineInstr *FindLastPartialDef(unsigned Reg,
+ SmallSet<unsigned,4> &PartDefRegs);
+
+ /// analyzePHINodes - Gather information about the PHI nodes in here. In
+ /// particular, we want to map the variable information of a virtual
+ /// register which is used in a PHI node. We map that to the BB the vreg
+ /// is coming from.
+ void analyzePHINodes(const MachineFunction& Fn);
+public:
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ /// RegisterDefIsDead - Return true if the specified instruction defines the
+ /// specified register, but that definition is dead.
+ bool RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const;
+
+ //===--------------------------------------------------------------------===//
+ // API to update live variable information
+
+ /// replaceKillInstruction - Update register kill info by replacing a kill
+ /// instruction with a new one.
+ void replaceKillInstruction(unsigned Reg, MachineInstr *OldMI,
+ MachineInstr *NewMI);
+
+ /// addVirtualRegisterKilled - Add information about the fact that the
+ /// specified register is killed after being used by the specified
+ /// instruction. If AddIfNotFound is true, add a implicit operand if it's
+ /// not found.
+ void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false) {
+ if (MI->addRegisterKilled(IncomingReg, TRI, AddIfNotFound))
+ getVarInfo(IncomingReg).Kills.push_back(MI);
+ }
+
+ /// removeVirtualRegisterKilled - Remove the specified kill of the virtual
+ /// register from the live variable information. Returns true if the
+ /// variable was marked as killed by the specified instruction,
+ /// false otherwise.
+ bool removeVirtualRegisterKilled(unsigned reg, MachineInstr *MI) {
+ if (!getVarInfo(reg).removeKill(MI))
+ return false;
+
+ bool Removed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isKill() && MO.getReg() == reg) {
+ MO.setIsKill(false);
+ Removed = true;
+ break;
+ }
+ }
+
+ assert(Removed && "Register is not used by this instruction!");
+ (void)Removed;
+ return true;
+ }
+
+ /// removeVirtualRegistersKilled - Remove all killed info for the specified
+ /// instruction.
+ void removeVirtualRegistersKilled(MachineInstr *MI);
+
+ /// addVirtualRegisterDead - Add information about the fact that the specified
+ /// register is dead after being used by the specified instruction. If
+ /// AddIfNotFound is true, add a implicit operand if it's not found.
+ void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false) {
+ if (MI->addRegisterDead(IncomingReg, TRI, AddIfNotFound))
+ getVarInfo(IncomingReg).Kills.push_back(MI);
+ }
+
+ /// removeVirtualRegisterDead - Remove the specified kill of the virtual
+ /// register from the live variable information. Returns true if the
+ /// variable was marked dead at the specified instruction, false
+ /// otherwise.
+ bool removeVirtualRegisterDead(unsigned reg, MachineInstr *MI) {
+ if (!getVarInfo(reg).removeKill(MI))
+ return false;
+
+ bool Removed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isDef() && MO.getReg() == reg) {
+ MO.setIsDead(false);
+ Removed = true;
+ break;
+ }
+ }
+ assert(Removed && "Register is not defined by this instruction!");
+ (void)Removed;
+ return true;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ virtual void releaseMemory() {
+ VirtRegInfo.clear();
+ }
+
+ /// getVarInfo - Return the VarInfo structure for the specified VIRTUAL
+ /// register.
+ VarInfo &getVarInfo(unsigned RegIdx);
+
+ void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+ MachineBasicBlock *BB);
+ void MarkVirtRegAliveInBlock(VarInfo& VRInfo, MachineBasicBlock* DefBlock,
+ MachineBasicBlock *BB,
+ std::vector<MachineBasicBlock*> &WorkList);
+ void HandleVirtRegDef(unsigned reg, MachineInstr *MI);
+ void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
+ MachineInstr *MI);
+
+ bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB) {
+ return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
+ }
+
+ /// isLiveOut - Determine if Reg is live out from MBB, when not considering
+ /// PHI nodes. This means that Reg is either killed by a successor block or
+ /// passed through one.
+ bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB);
+
+ /// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
+ /// variables that are live out of DomBB and live into SuccBB will be marked
+ /// as passing live through BB. This method assumes that the machine code is
+ /// still in SSA form.
+ void addNewBlock(MachineBasicBlock *BB,
+ MachineBasicBlock *DomBB,
+ MachineBasicBlock *SuccBB);
+
+ /// isPHIJoin - Return true if Reg is a phi join register.
+ bool isPHIJoin(unsigned Reg) { return PHIJoins.test(Reg); }
+
+ /// setPHIJoin - Mark Reg as a phi join register.
+ void setPHIJoin(unsigned Reg) { PHIJoins.set(Reg); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachORelocation.h b/contrib/llvm/include/llvm/CodeGen/MachORelocation.h
new file mode 100644
index 000000000000..21fe74f8e1cd
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachORelocation.h
@@ -0,0 +1,56 @@
+//=== MachORelocation.h - Mach-O Relocation 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 MachORelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H
+#define LLVM_CODEGEN_MACHO_RELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+ /// MachORelocation - This struct contains information about each relocation
+ /// that needs to be emitted to the file.
+ /// see <mach-o/reloc.h>
+ class MachORelocation {
+ uint32_t r_address; // offset in the section to what is being relocated
+ uint32_t r_symbolnum; // symbol index if r_extern == 1 else section index
+ bool r_pcrel; // was relocated pc-relative already
+ uint8_t r_length; // length = 2 ^ r_length
+ bool r_extern; //
+ uint8_t r_type; // if not 0, machine-specific relocation type.
+ bool r_scattered; // 1 = scattered, 0 = non-scattered
+ int32_t r_value; // the value the item to be relocated is referring
+ // to.
+ public:
+ uint32_t getPackedFields() const {
+ if (r_scattered)
+ return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) |
+ ((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
+ else
+ return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
+ (r_extern << 4) | (r_type & 15);
+ }
+ uint32_t getAddress() const { return r_scattered ? r_value : r_address; }
+ uint32_t getRawAddress() const { return r_address; }
+
+ MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
+ bool ext, uint8_t type, bool scattered = false,
+ int32_t value = 0) :
+ r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
+ r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_MACHO_RELOCATION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
new file mode 100644
index 000000000000..ef9c0c200584
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -0,0 +1,708 @@
+//===-- llvm/CodeGen/MachineBasicBlock.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect the sequence of machine instructions for a basic block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
+#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
+
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Support/DataTypes.h"
+#include <functional>
+
+namespace llvm {
+
+class Pass;
+class BasicBlock;
+class MachineFunction;
+class MCSymbol;
+class SlotIndexes;
+class StringRef;
+class raw_ostream;
+class MachineBranchProbabilityInfo;
+
+template <>
+struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
+private:
+ mutable ilist_half_node<MachineInstr> Sentinel;
+
+ // this is only set by the MachineBasicBlock owning the LiveList
+ friend class MachineBasicBlock;
+ MachineBasicBlock* Parent;
+
+public:
+ MachineInstr *createSentinel() const {
+ return static_cast<MachineInstr*>(&Sentinel);
+ }
+ void destroySentinel(MachineInstr *) const {}
+
+ MachineInstr *provideInitialHead() const { return createSentinel(); }
+ MachineInstr *ensureHead(MachineInstr*) const { return createSentinel(); }
+ static void noteHead(MachineInstr*, MachineInstr*) {}
+
+ void addNodeToList(MachineInstr* N);
+ void removeNodeFromList(MachineInstr* N);
+ void transferNodesFromList(ilist_traits &SrcTraits,
+ ilist_iterator<MachineInstr> first,
+ ilist_iterator<MachineInstr> last);
+ void deleteNode(MachineInstr *N);
+private:
+ void createNode(const MachineInstr &);
+};
+
+class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
+ typedef ilist<MachineInstr> Instructions;
+ Instructions Insts;
+ const BasicBlock *BB;
+ int Number;
+ MachineFunction *xParent;
+
+ /// Predecessors/Successors - Keep track of the predecessor / successor
+ /// basicblocks.
+ std::vector<MachineBasicBlock *> Predecessors;
+ std::vector<MachineBasicBlock *> Successors;
+
+
+ /// Weights - Keep track of the weights to the successors. This vector
+ /// has the same order as Successors, or it is empty if we don't use it
+ /// (disable optimization).
+ std::vector<uint32_t> Weights;
+ typedef std::vector<uint32_t>::iterator weight_iterator;
+ typedef std::vector<uint32_t>::const_iterator const_weight_iterator;
+
+ /// LiveIns - Keep track of the physical registers that are livein of
+ /// the basicblock.
+ std::vector<unsigned> LiveIns;
+
+ /// Alignment - Alignment of the basic block. Zero if the basic block does
+ /// not need to be aligned.
+ /// The alignment is specified as log2(bytes).
+ unsigned Alignment;
+
+ /// IsLandingPad - Indicate that this basic block is entered via an
+ /// exception handler.
+ bool IsLandingPad;
+
+ /// AddressTaken - Indicate that this basic block is potentially the
+ /// target of an indirect branch.
+ bool AddressTaken;
+
+ // Intrusive list support
+ MachineBasicBlock() {}
+
+ explicit MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb);
+
+ ~MachineBasicBlock();
+
+ // MachineBasicBlocks are allocated and owned by MachineFunction.
+ friend class MachineFunction;
+
+public:
+ /// getBasicBlock - Return the LLVM basic block that this instance
+ /// corresponded to originally. Note that this may be NULL if this instance
+ /// does not correspond directly to an LLVM basic block.
+ ///
+ const BasicBlock *getBasicBlock() const { return BB; }
+
+ /// getName - Return the name of the corresponding LLVM basic block, or
+ /// "(null)".
+ StringRef getName() const;
+
+ /// getFullName - Return a formatted string to identify this block and its
+ /// parent function.
+ std::string getFullName() const;
+
+ /// hasAddressTaken - Test whether this block is potentially the target
+ /// of an indirect branch.
+ bool hasAddressTaken() const { return AddressTaken; }
+
+ /// setHasAddressTaken - Set this block to reflect that it potentially
+ /// is the target of an indirect branch.
+ void setHasAddressTaken() { AddressTaken = true; }
+
+ /// getParent - Return the MachineFunction containing this basic block.
+ ///
+ const MachineFunction *getParent() const { return xParent; }
+ MachineFunction *getParent() { return xParent; }
+
+
+ /// bundle_iterator - MachineBasicBlock iterator that automatically skips over
+ /// MIs that are inside bundles (i.e. walk top level MIs only).
+ template<typename Ty, typename IterTy>
+ class bundle_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, ptrdiff_t> {
+ IterTy MII;
+
+ public:
+ bundle_iterator(IterTy mii) : MII(mii) {
+ assert(!MII->isInsideBundle() &&
+ "It's not legal to initialize bundle_iterator with a bundled MI");
+ }
+
+ bundle_iterator(Ty &mi) : MII(mi) {
+ assert(!mi.isInsideBundle() &&
+ "It's not legal to initialize bundle_iterator with a bundled MI");
+ }
+ bundle_iterator(Ty *mi) : MII(mi) {
+ assert((!mi || !mi->isInsideBundle()) &&
+ "It's not legal to initialize bundle_iterator with a bundled MI");
+ }
+ bundle_iterator(const bundle_iterator &I) : MII(I.MII) {}
+ bundle_iterator() : MII(0) {}
+
+ Ty &operator*() const { return *MII; }
+ Ty *operator->() const { return &operator*(); }
+
+ operator Ty*() const { return MII; }
+
+ bool operator==(const bundle_iterator &x) const {
+ return MII == x.MII;
+ }
+ bool operator!=(const bundle_iterator &x) const {
+ return !operator==(x);
+ }
+
+ // Increment and decrement operators...
+ bundle_iterator &operator--() { // predecrement - Back up
+ do {
+ --MII;
+ } while (MII->isInsideBundle());
+ return *this;
+ }
+ bundle_iterator &operator++() { // preincrement - Advance
+ do {
+ ++MII;
+ } while (MII->isInsideBundle());
+ return *this;
+ }
+ bundle_iterator operator--(int) { // postdecrement operators...
+ bundle_iterator tmp = *this;
+ do {
+ --MII;
+ } while (MII->isInsideBundle());
+ return tmp;
+ }
+ bundle_iterator operator++(int) { // postincrement operators...
+ bundle_iterator tmp = *this;
+ do {
+ ++MII;
+ } while (MII->isInsideBundle());
+ return tmp;
+ }
+
+ IterTy getInstrIterator() const {
+ return MII;
+ }
+ };
+
+ typedef Instructions::iterator instr_iterator;
+ typedef Instructions::const_iterator const_instr_iterator;
+ typedef std::reverse_iterator<instr_iterator> reverse_instr_iterator;
+ typedef
+ std::reverse_iterator<const_instr_iterator> const_reverse_instr_iterator;
+
+ typedef
+ bundle_iterator<MachineInstr,instr_iterator> iterator;
+ typedef
+ bundle_iterator<const MachineInstr,const_instr_iterator> const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+
+ unsigned size() const { return (unsigned)Insts.size(); }
+ bool empty() const { return Insts.empty(); }
+
+ MachineInstr& front() { return Insts.front(); }
+ MachineInstr& back() { return Insts.back(); }
+ const MachineInstr& front() const { return Insts.front(); }
+ const MachineInstr& back() const { return Insts.back(); }
+
+ instr_iterator instr_begin() { return Insts.begin(); }
+ const_instr_iterator instr_begin() const { return Insts.begin(); }
+ instr_iterator instr_end() { return Insts.end(); }
+ const_instr_iterator instr_end() const { return Insts.end(); }
+ reverse_instr_iterator instr_rbegin() { return Insts.rbegin(); }
+ const_reverse_instr_iterator instr_rbegin() const { return Insts.rbegin(); }
+ reverse_instr_iterator instr_rend () { return Insts.rend(); }
+ const_reverse_instr_iterator instr_rend () const { return Insts.rend(); }
+
+ iterator begin() { return Insts.begin(); }
+ const_iterator begin() const { return Insts.begin(); }
+ iterator end() {
+ instr_iterator II = instr_end();
+ if (II != instr_begin()) {
+ while (II->isInsideBundle())
+ --II;
+ }
+ return II;
+ }
+ const_iterator end() const {
+ const_instr_iterator II = instr_end();
+ if (II != instr_begin()) {
+ while (II->isInsideBundle())
+ --II;
+ }
+ return II;
+ }
+ reverse_iterator rbegin() {
+ reverse_instr_iterator II = instr_rbegin();
+ if (II != instr_rend()) {
+ while (II->isInsideBundle())
+ ++II;
+ }
+ return II;
+ }
+ const_reverse_iterator rbegin() const {
+ const_reverse_instr_iterator II = instr_rbegin();
+ if (II != instr_rend()) {
+ while (II->isInsideBundle())
+ ++II;
+ }
+ return II;
+ }
+ reverse_iterator rend () { return Insts.rend(); }
+ const_reverse_iterator rend () const { return Insts.rend(); }
+
+
+ // Machine-CFG iterators
+ typedef std::vector<MachineBasicBlock *>::iterator pred_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
+ typedef std::vector<MachineBasicBlock *>::iterator succ_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ succ_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_succ_reverse_iterator;
+
+ pred_iterator pred_begin() { return Predecessors.begin(); }
+ const_pred_iterator pred_begin() const { return Predecessors.begin(); }
+ pred_iterator pred_end() { return Predecessors.end(); }
+ const_pred_iterator pred_end() const { return Predecessors.end(); }
+ pred_reverse_iterator pred_rbegin()
+ { return Predecessors.rbegin();}
+ const_pred_reverse_iterator pred_rbegin() const
+ { return Predecessors.rbegin();}
+ pred_reverse_iterator pred_rend()
+ { return Predecessors.rend(); }
+ const_pred_reverse_iterator pred_rend() const
+ { return Predecessors.rend(); }
+ unsigned pred_size() const {
+ return (unsigned)Predecessors.size();
+ }
+ bool pred_empty() const { return Predecessors.empty(); }
+ succ_iterator succ_begin() { return Successors.begin(); }
+ const_succ_iterator succ_begin() const { return Successors.begin(); }
+ succ_iterator succ_end() { return Successors.end(); }
+ const_succ_iterator succ_end() const { return Successors.end(); }
+ succ_reverse_iterator succ_rbegin()
+ { return Successors.rbegin(); }
+ const_succ_reverse_iterator succ_rbegin() const
+ { return Successors.rbegin(); }
+ succ_reverse_iterator succ_rend()
+ { return Successors.rend(); }
+ const_succ_reverse_iterator succ_rend() const
+ { return Successors.rend(); }
+ unsigned succ_size() const {
+ return (unsigned)Successors.size();
+ }
+ bool succ_empty() const { return Successors.empty(); }
+
+ // LiveIn management methods.
+
+ /// addLiveIn - Add the specified register as a live in. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); }
+
+ /// removeLiveIn - Remove the specified register from the live in set.
+ ///
+ void removeLiveIn(unsigned Reg);
+
+ /// isLiveIn - Return true if the specified register is in the live in set.
+ ///
+ bool isLiveIn(unsigned Reg) const;
+
+ // Iteration support for live in sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<unsigned>::const_iterator livein_iterator;
+ livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+
+ /// getAlignment - Return alignment of the basic block.
+ /// The alignment is specified as log2(bytes).
+ ///
+ unsigned getAlignment() const { return Alignment; }
+
+ /// setAlignment - Set alignment of the basic block.
+ /// The alignment is specified as log2(bytes).
+ ///
+ void setAlignment(unsigned Align) { Alignment = Align; }
+
+ /// isLandingPad - Returns true if the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ bool isLandingPad() const { return IsLandingPad; }
+
+ /// setIsLandingPad - Indicates the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ void setIsLandingPad(bool V = true) { IsLandingPad = V; }
+
+ /// getLandingPadSuccessor - If this block has a successor that is a landing
+ /// pad, return it. Otherwise return NULL.
+ const MachineBasicBlock *getLandingPadSuccessor() const;
+
+ // Code Layout methods.
+
+ /// moveBefore/moveAfter - move 'this' block before or after the specified
+ /// block. This only moves the block, it does not modify the CFG or adjust
+ /// potential fall-throughs at the end of the block.
+ void moveBefore(MachineBasicBlock *NewAfter);
+ void moveAfter(MachineBasicBlock *NewBefore);
+
+ /// updateTerminator - Update the terminator instructions in block to account
+ /// for changes to the layout. If the block previously used a fallthrough,
+ /// it may now need a branch, and if it previously used branching it may now
+ /// be able to use a fallthrough.
+ void updateTerminator();
+
+ // Machine-CFG mutators
+
+ /// addSuccessor - Add succ as a successor of this MachineBasicBlock.
+ /// The Predecessors list of succ is automatically updated. WEIGHT
+ /// parameter is stored in Weights list and it may be used by
+ /// MachineBranchProbabilityInfo analysis to calculate branch probability.
+ ///
+ void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
+
+ /// removeSuccessor - Remove successor from the successors list of this
+ /// MachineBasicBlock. The Predecessors list of succ is automatically updated.
+ ///
+ void removeSuccessor(MachineBasicBlock *succ);
+
+ /// removeSuccessor - Remove specified successor from the successors list of
+ /// this MachineBasicBlock. The Predecessors list of succ is automatically
+ /// updated. Return the iterator to the element after the one removed.
+ ///
+ succ_iterator removeSuccessor(succ_iterator I);
+
+ /// replaceSuccessor - Replace successor OLD with NEW and update weight info.
+ ///
+ void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+
+ /// transferSuccessors - Transfers all the successors from MBB to this
+ /// machine basic block (i.e., copies all the successors fromMBB and
+ /// remove all the successors from fromMBB).
+ void transferSuccessors(MachineBasicBlock *fromMBB);
+
+ /// transferSuccessorsAndUpdatePHIs - Transfers all the successors, as
+ /// in transferSuccessors, and update PHI operands in the successor blocks
+ /// which refer to fromMBB to refer to this.
+ void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB);
+
+ /// isSuccessor - Return true if the specified MBB is a successor of this
+ /// block.
+ bool isSuccessor(const MachineBasicBlock *MBB) const;
+
+ /// isLayoutSuccessor - Return true if the specified MBB will be emitted
+ /// immediately after this block, such that if this block exits by
+ /// falling through, control will transfer to the specified MBB. Note
+ /// that MBB need not be a successor at all, for example if this block
+ /// ends with an unconditional branch to some other block.
+ bool isLayoutSuccessor(const MachineBasicBlock *MBB) const;
+
+ /// canFallThrough - Return true if the block can implicitly transfer
+ /// control to the block after it by falling off the end of it. This should
+ /// return false if it can reach the block after it, but it uses an explicit
+ /// branch to do so (e.g., a table jump). True is a conservative answer.
+ bool canFallThrough();
+
+ /// Returns a pointer to the first instructon in this block that is not a
+ /// PHINode instruction. When adding instruction to the beginning of the
+ /// basic block, they should be added before the returned value, not before
+ /// the first instruction, which might be PHI.
+ /// Returns end() is there's no non-PHI instruction.
+ iterator getFirstNonPHI();
+
+ /// SkipPHIsAndLabels - Return the first instruction in MBB after I that is
+ /// not a PHI or a label. This is the correct point to insert copies at the
+ /// beginning of a basic block.
+ iterator SkipPHIsAndLabels(iterator I);
+
+ /// getFirstTerminator - returns an iterator to the first terminator
+ /// instruction of this basic block. If a terminator does not exist,
+ /// it returns end()
+ iterator getFirstTerminator();
+ const_iterator getFirstTerminator() const;
+
+ /// getFirstInstrTerminator - Same getFirstTerminator but it ignores bundles
+ /// and return an instr_iterator instead.
+ instr_iterator getFirstInstrTerminator();
+
+ /// getLastNonDebugInstr - returns an iterator to the last non-debug
+ /// instruction in the basic block, or end()
+ iterator getLastNonDebugInstr();
+ const_iterator getLastNonDebugInstr() const;
+
+ /// SplitCriticalEdge - Split the critical edge from this block to the
+ /// given successor block, and return the newly created block, or null
+ /// if splitting is not possible.
+ ///
+ /// This function updates LiveVariables, MachineDominatorTree, and
+ /// MachineLoopInfo, as applicable.
+ MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P);
+
+ void pop_front() { Insts.pop_front(); }
+ 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);
+ }
+
+ 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);
+ }
+ iterator insertAfter(iterator I, MachineInstr *M) {
+ return Insts.insertAfter(I.getInstrIterator(), M);
+ }
+
+ /// erase - Remove the specified element or range from the instruction list.
+ /// These functions delete any instructions removed.
+ ///
+ instr_iterator erase(instr_iterator I) {
+ return Insts.erase(I);
+ }
+ instr_iterator erase(instr_iterator I, instr_iterator E) {
+ return Insts.erase(I, E);
+ }
+ instr_iterator erase_instr(MachineInstr *I) {
+ instr_iterator MII(I);
+ return erase(MII);
+ }
+
+ iterator erase(iterator I);
+ iterator erase(iterator I, iterator E) {
+ return Insts.erase(I.getInstrIterator(), E.getInstrIterator());
+ }
+ iterator erase(MachineInstr *I) {
+ iterator MII(I);
+ return erase(MII);
+ }
+
+ /// 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);
+ 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);
+ }
+ 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,
+ From.getInstrIterator(), To.getInstrIterator());
+ }
+
+ /// removeFromParent - This method unlinks 'this' from the containing
+ /// function, and returns it, but does not delete it.
+ MachineBasicBlock *removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing
+ /// function and deletes it.
+ void eraseFromParent();
+
+ /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to
+ /// 'Old', change the code and CFG so that it branches to 'New' instead.
+ void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+ /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in
+ /// the CFG to be inserted. If we have proven that MBB can only branch to
+ /// DestA and DestB, remove any other MBB successors from the CFG. DestA and
+ /// DestB can be null. Besides DestA and DestB, retain other edges leading
+ /// to LandingPads (currently there can be only one; we don't check or require
+ /// that here). Note it is possible that DestA and/or DestB are LandingPads.
+ bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
+ MachineBasicBlock *DestB,
+ bool isCond);
+
+ /// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
+ /// any DBG_VALUE instructions. Return UnknownLoc if there is none.
+ DebugLoc findDebugLoc(instr_iterator MBBI);
+ DebugLoc findDebugLoc(iterator MBBI) {
+ return findDebugLoc(MBBI.getInstrIterator());
+ }
+
+ // Debugging methods.
+ void dump() const;
+ void print(raw_ostream &OS, SlotIndexes* = 0) const;
+
+ /// getNumber - MachineBasicBlocks are uniquely numbered at the function
+ /// level, unless they're not in a MachineFunction yet, in which case this
+ /// will return -1.
+ ///
+ int getNumber() const { return Number; }
+ void setNumber(int N) { Number = N; }
+
+ /// getSymbol - Return the MCSymbol for this basic block.
+ ///
+ MCSymbol *getSymbol() const;
+
+
+private:
+ /// getWeightIterator - Return weight iterator corresponding to the I
+ /// successor iterator.
+ weight_iterator getWeightIterator(succ_iterator I);
+ const_weight_iterator getWeightIterator(const_succ_iterator I) const;
+
+ friend class MachineBranchProbabilityInfo;
+
+ /// getSuccWeight - Return weight of the edge from this block to MBB. This
+ /// method should NOT be called directly, but by using getEdgeWeight method
+ /// from MachineBranchProbabilityInfo class.
+ uint32_t getSuccWeight(const MachineBasicBlock *succ) const;
+
+
+ // Methods used to maintain doubly linked list of blocks...
+ friend struct ilist_traits<MachineBasicBlock>;
+
+ // Machine-CFG mutators
+
+ /// addPredecessor - Remove pred as a predecessor of this MachineBasicBlock.
+ /// Don't do this unless you know what you're doing, because it doesn't
+ /// update pred's successors list. Use pred->addSuccessor instead.
+ ///
+ void addPredecessor(MachineBasicBlock *pred);
+
+ /// removePredecessor - Remove pred as a predecessor of this
+ /// MachineBasicBlock. Don't do this unless you know what you're
+ /// doing, because it doesn't update pred's successors list. Use
+ /// pred->removeSuccessor instead.
+ ///
+ void removePredecessor(MachineBasicBlock *pred);
+};
+
+raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB);
+
+void WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t);
+
+// This is useful when building IndexedMaps keyed on basic block pointers.
+struct MBB2NumberFunctor :
+ public std::unary_function<const MachineBasicBlock*, unsigned> {
+ unsigned operator()(const MachineBasicBlock *MBB) const {
+ return MBB->getNumber();
+ }
+};
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for machine basic block graphs (machine-CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks...
+//
+
+template <> struct GraphTraits<MachineBasicBlock *> {
+ typedef MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->succ_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->succ_end();
+ }
+};
+
+template <> struct GraphTraits<const MachineBasicBlock *> {
+ typedef const MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->succ_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->succ_end();
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks... and to walk it
+// in inverse order. Inverse order for a function is considered
+// to be when traversing the predecessor edges of a MBB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
+ typedef MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->pred_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->pred_end();
+ }
+};
+
+template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
+ typedef const MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::const_pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->pred_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->pred_end();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
new file mode 100644
index 000000000000..a9c7bf7dbc60
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -0,0 +1,56 @@
+//====----- MachineBlockFrequencyInfo.h - MachineBlock Frequency Analysis ----====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Loops should be simplified before this analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
+#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/BlockFrequency.h"
+#include <climits>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineBranchProbabilityInfo;
+template<class BlockT, class FunctionT, class BranchProbInfoT>
+class BlockFrequencyImpl;
+
+/// MachineBlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
+/// machine basic block frequencies.
+class MachineBlockFrequencyInfo : public MachineFunctionPass {
+
+ BlockFrequencyImpl<MachineBasicBlock, MachineFunction,
+ MachineBranchProbabilityInfo> *MBFI;
+
+public:
+ static char ID;
+
+ MachineBlockFrequencyInfo();
+
+ ~MachineBlockFrequencyInfo();
+
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ bool runOnMachineFunction(MachineFunction &F);
+
+ /// getblockFreq - Return block frequency. Return 0 if we don't have the
+ /// information. Please note that initial frequency is equal to 1024. It means
+ /// that we should not rely on the value itself, but only on the comparison to
+ /// the other block frequencies. We do this to avoid using of floating points.
+ ///
+ BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
new file mode 100644
index 000000000000..af4db7d6bde6
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
@@ -0,0 +1,86 @@
+
+//==- MachineBranchProbabilityInfo.h - Machine Branch Probability Analysis -==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to evaluate branch probabilties on machine basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
+#define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/BranchProbability.h"
+#include <climits>
+
+namespace llvm {
+
+class raw_ostream;
+class MachineBasicBlock;
+
+class MachineBranchProbabilityInfo : public ImmutablePass {
+ virtual void anchor();
+
+ // Default weight value. Used when we don't have information about the edge.
+ // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
+ // the successors have a weight yet. But it doesn't make sense when providing
+ // weight to an edge that may have siblings with non-zero weights. This can
+ // be handled various ways, but it's probably fine for an edge with unknown
+ // weight to just "inherit" the non-zero weight of an adjacent successor.
+ static const uint32_t DEFAULT_WEIGHT = 16;
+
+public:
+ static char ID;
+
+ MachineBranchProbabilityInfo() : ImmutablePass(ID) {
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeMachineBranchProbabilityInfoPass(Registry);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ // Return edge weight. If we don't have any informations about it - return
+ // DEFAULT_WEIGHT.
+ uint32_t getEdgeWeight(const MachineBasicBlock *Src,
+ const MachineBasicBlock *Dst) const;
+
+ // Get sum of the block successors' weights, potentially scaling them to fit
+ // within 32-bits. If scaling is required, sets Scale based on the necessary
+ // adjustment. Any edge weights used with the sum should be divided by Scale.
+ uint32_t getSumForBlock(const MachineBasicBlock *MBB, uint32_t &Scale) const;
+
+ // A 'Hot' edge is an edge which probability is >= 80%.
+ bool isEdgeHot(MachineBasicBlock *Src, MachineBasicBlock *Dst) const;
+
+ // Return a hot successor for the block BB or null if there isn't one.
+ // NB: This routine's complexity is linear on the number of successors.
+ MachineBasicBlock *getHotSucc(MachineBasicBlock *MBB) const;
+
+ // Return a probability as a fraction between 0 (0% probability) and
+ // 1 (100% probability), however the value is never equal to 0, and can be 1
+ // only iff SRC block has only one successor.
+ // NB: This routine's complexity is linear on the number of successors of
+ // Src. Querying sequentially for each successor's probability is a quadratic
+ // query pattern.
+ BranchProbability getEdgeProbability(MachineBasicBlock *Src,
+ MachineBasicBlock *Dst) const;
+
+ // Print value between 0 (0% probability) and 1 (100% probability),
+ // however the value is never equal to 0, and can be 1 only iff SRC block
+ // has only one successor.
+ raw_ostream &printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src,
+ MachineBasicBlock *Dst) const;
+};
+
+}
+
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h b/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h
new file mode 100644
index 000000000000..86e8f27877e2
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -0,0 +1,335 @@
+//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*- 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 an abstract interface that is used by the machine code
+// emission framework to output the code. This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
+#define LLVM_CODEGEN_MACHINECODEEMITTER_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DebugLoc.h"
+
+#include <string>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineFunction;
+class MachineModuleInfo;
+class MachineRelocation;
+class Value;
+class GlobalValue;
+class Function;
+class MCSymbol;
+
+/// MachineCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxiliary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it. As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit. In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+///
+class MachineCodeEmitter {
+ virtual void anchor();
+protected:
+ /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
+ /// allocated for this code buffer.
+ uint8_t *BufferBegin, *BufferEnd;
+ /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
+ /// code. This is guaranteed to be in the range [BufferBegin,BufferEnd]. If
+ /// this pointer is at BufferEnd, it will never move due to code emission, and
+ /// all code emission requests will be ignored (this is the buffer overflow
+ /// condition).
+ uint8_t *CurBufferPtr;
+
+public:
+ virtual ~MachineCodeEmitter() {}
+
+ /// startFunction - This callback is invoked when the specified function is
+ /// about to be code generated. This initializes the BufferBegin/End/Ptr
+ /// fields.
+ ///
+ virtual void startFunction(MachineFunction &F) = 0;
+
+ /// finishFunction - This callback is invoked when the specified function has
+ /// finished code generation. If a buffer overflow has occurred, this method
+ /// returns true (the callee is required to try again), otherwise it returns
+ /// false.
+ ///
+ virtual bool finishFunction(MachineFunction &F) = 0;
+
+ /// emitByte - This callback is invoked when a byte needs to be written to the
+ /// output stream.
+ ///
+ void emitByte(uint8_t B) {
+ if (CurBufferPtr != BufferEnd)
+ *CurBufferPtr++ = B;
+ }
+
+ /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in little-endian format.
+ ///
+ void emitWordLE(uint32_t W) {
+ if (4 <= BufferEnd-CurBufferPtr) {
+ emitWordLEInto(CurBufferPtr, W);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitWordLEInto - This callback is invoked when a 32-bit word needs to be
+ /// written to an arbitrary buffer in little-endian format. Buf must have at
+ /// least 4 bytes of available space.
+ ///
+ static void emitWordLEInto(uint8_t *&Buf, uint32_t W) {
+ *Buf++ = (uint8_t)(W >> 0);
+ *Buf++ = (uint8_t)(W >> 8);
+ *Buf++ = (uint8_t)(W >> 16);
+ *Buf++ = (uint8_t)(W >> 24);
+ }
+
+ /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in big-endian format.
+ ///
+ void emitWordBE(uint32_t W) {
+ if (4 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
+ /// written to the output stream in little-endian format.
+ ///
+ void emitDWordLE(uint64_t W) {
+ if (8 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (uint8_t)(W >> 32);
+ *CurBufferPtr++ = (uint8_t)(W >> 40);
+ *CurBufferPtr++ = (uint8_t)(W >> 48);
+ *CurBufferPtr++ = (uint8_t)(W >> 56);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
+ /// written to the output stream in big-endian format.
+ ///
+ void emitDWordBE(uint64_t W) {
+ if (8 <= BufferEnd-CurBufferPtr) {
+ *CurBufferPtr++ = (uint8_t)(W >> 56);
+ *CurBufferPtr++ = (uint8_t)(W >> 48);
+ *CurBufferPtr++ = (uint8_t)(W >> 40);
+ *CurBufferPtr++ = (uint8_t)(W >> 32);
+ *CurBufferPtr++ = (uint8_t)(W >> 24);
+ *CurBufferPtr++ = (uint8_t)(W >> 16);
+ *CurBufferPtr++ = (uint8_t)(W >> 8);
+ *CurBufferPtr++ = (uint8_t)(W >> 0);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitAlignment - Move the CurBufferPtr pointer up to the specified
+ /// alignment (saturated to BufferEnd of course).
+ void emitAlignment(unsigned Alignment) {
+ if (Alignment == 0) Alignment = 1;
+
+ if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) {
+ // Move the current buffer ptr up to the specified alignment.
+ CurBufferPtr =
+ (uint8_t*)(((uintptr_t)CurBufferPtr+Alignment-1) &
+ ~(uintptr_t)(Alignment-1));
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+
+ /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
+ /// written to the output stream.
+ void emitULEB128Bytes(uint64_t Value) {
+ do {
+ uint8_t Byte = Value & 0x7f;
+ Value >>= 7;
+ if (Value) Byte |= 0x80;
+ emitByte(Byte);
+ } while (Value);
+ }
+
+ /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
+ /// written to the output stream.
+ void emitSLEB128Bytes(uint64_t Value) {
+ uint64_t Sign = Value >> (8 * sizeof(Value) - 1);
+ bool IsMore;
+
+ do {
+ uint8_t Byte = Value & 0x7f;
+ Value >>= 7;
+ IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+ if (IsMore) Byte |= 0x80;
+ emitByte(Byte);
+ } while (IsMore);
+ }
+
+ /// emitString - This callback is invoked when a String needs to be
+ /// written to the output stream.
+ void emitString(const std::string &String) {
+ for (unsigned i = 0, N = static_cast<unsigned>(String.size());
+ i < N; ++i) {
+ uint8_t C = String[i];
+ emitByte(C);
+ }
+ emitByte(0);
+ }
+
+ /// emitInt32 - Emit a int32 directive.
+ void emitInt32(int32_t Value) {
+ if (4 <= BufferEnd-CurBufferPtr) {
+ *((uint32_t*)CurBufferPtr) = Value;
+ CurBufferPtr += 4;
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitInt64 - Emit a int64 directive.
+ void emitInt64(uint64_t Value) {
+ if (8 <= BufferEnd-CurBufferPtr) {
+ *((uint64_t*)CurBufferPtr) = Value;
+ CurBufferPtr += 8;
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitInt32At - Emit the Int32 Value in Addr.
+ void emitInt32At(uintptr_t *Addr, uintptr_t Value) {
+ if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+ (*(uint32_t*)Addr) = (uint32_t)Value;
+ }
+
+ /// emitInt64At - Emit the Int64 Value in Addr.
+ void emitInt64At(uintptr_t *Addr, uintptr_t Value) {
+ if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
+ (*(uint64_t*)Addr) = (uint64_t)Value;
+ }
+
+ /// processDebugLoc - Records debug location information about a
+ /// MachineInstruction. This is called before emitting any bytes associated
+ /// with the instruction. Even if successive instructions have the same debug
+ /// location, this method will be called for each one.
+ virtual void processDebugLoc(DebugLoc DL, bool BeforePrintintInsn) {}
+
+ /// emitLabel - Emits a label
+ virtual void emitLabel(MCSymbol *Label) = 0;
+
+ /// allocateSpace - Allocate a block of space in the current output buffer,
+ /// returning null (and setting conditions to indicate buffer overflow) on
+ /// failure. Alignment is the alignment in bytes of the buffer desired.
+ virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) {
+ emitAlignment(Alignment);
+ void *Result;
+
+ // Check for buffer overflow.
+ if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) {
+ CurBufferPtr = BufferEnd;
+ Result = 0;
+ } else {
+ // Allocate the space.
+ Result = CurBufferPtr;
+ CurBufferPtr += Size;
+ }
+
+ return Result;
+ }
+
+ /// StartMachineBasicBlock - This should be called by the target when a new
+ /// basic block is about to be emitted. This way the MCE knows where the
+ /// start of the block is, and can implement getMachineBasicBlockAddress.
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
+
+ /// getCurrentPCValue - This returns the address that the next emitted byte
+ /// will be output to.
+ ///
+ virtual uintptr_t getCurrentPCValue() const {
+ return (uintptr_t)CurBufferPtr;
+ }
+
+ /// getCurrentPCOffset - Return the offset from the start of the emitted
+ /// buffer that we are currently writing to.
+ virtual uintptr_t getCurrentPCOffset() const {
+ return CurBufferPtr-BufferBegin;
+ }
+
+ /// earlyResolveAddresses - True if the code emitter can use symbol addresses
+ /// during code emission time. The JIT is capable of doing this because it
+ /// creates jump tables or constant pools in memory on the fly while the
+ /// object code emitters rely on a linker to have real addresses and should
+ /// use relocations instead.
+ virtual bool earlyResolveAddresses() const = 0;
+
+ /// addRelocation - Whenever a relocatable address is needed, it should be
+ /// noted with this interface.
+ virtual void addRelocation(const MachineRelocation &MR) = 0;
+
+ /// FIXME: These should all be handled with relocations!
+
+ /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
+ /// the constant pool that was last emitted with the emitConstantPool method.
+ ///
+ virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
+
+ /// getJumpTableEntryAddress - Return the address of the jump table with index
+ /// 'Index' in the function that last called initJumpTableInfo.
+ ///
+ virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
+
+ /// getMachineBasicBlockAddress - Return the address of the specified
+ /// MachineBasicBlock, only usable after the label for the MBB has been
+ /// emitted.
+ ///
+ virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
+
+ /// getLabelAddress - Return the address of the specified Label, only usable
+ /// after the LabelID has been emitted.
+ ///
+ virtual uintptr_t getLabelAddress(MCSymbol *Label) const = 0;
+
+ /// Specifies the MachineModuleInfo object. This is used for exception handling
+ /// purposes.
+ virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h
new file mode 100644
index 000000000000..c5c0c4450454
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineCodeInfo.h
@@ -0,0 +1,53 @@
+//===-- MachineCodeInfo.h - Class used to report JIT 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 MachineCodeInfo, a class used by the JIT ExecutionEngine
+// to report information about the generated machine code.
+//
+// See JIT::runJITOnFunction for usage.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EE_MACHINE_CODE_INFO_H
+#define EE_MACHINE_CODE_INFO_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MachineCodeInfo {
+private:
+ size_t Size; // Number of bytes in memory used
+ void *Address; // The address of the function in memory
+
+public:
+ MachineCodeInfo() : Size(0), Address(0) {}
+
+ void setSize(size_t s) {
+ Size = s;
+ }
+
+ void setAddress(void *a) {
+ Address = a;
+ }
+
+ size_t size() const {
+ return Size;
+ }
+
+ void *address() const {
+ return Address;
+ }
+
+};
+
+}
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h
new file mode 100644
index 000000000000..d6d65a24defb
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineConstantPool.h
@@ -0,0 +1,174 @@
+//===-- CodeGen/MachineConstantPool.h - Abstract Constant Pool --*- 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 declares the MachineConstantPool class which is an abstract
+/// constant pool to keep track of constants referenced by a function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+#define LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+
+#include "llvm/ADT/DenseSet.h"
+#include <cassert>
+#include <climits>
+#include <vector>
+
+namespace llvm {
+
+class Constant;
+class FoldingSetNodeID;
+class TargetData;
+class TargetMachine;
+class Type;
+class MachineConstantPool;
+class raw_ostream;
+
+/// Abstract base class for all machine specific constantpool value subclasses.
+///
+class MachineConstantPoolValue {
+ virtual void anchor();
+ Type *Ty;
+
+public:
+ explicit MachineConstantPoolValue(Type *ty) : Ty(ty) {}
+ virtual ~MachineConstantPoolValue() {}
+
+ /// getType - get type of this MachineConstantPoolValue.
+ ///
+ Type *getType() const { return Ty; }
+
+
+ /// getRelocationInfo - This method classifies the entry according to
+ /// whether or not it may generate a relocation entry. This must be
+ /// conservative, so if it might codegen to a relocatable entry, it should say
+ /// so. The return values are the same as Constant::getRelocationInfo().
+ virtual unsigned getRelocationInfo() const = 0;
+
+ virtual int getExistingMachineCPValue(MachineConstantPool *CP,
+ unsigned Alignment) = 0;
+
+ virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
+
+ /// print - Implement operator<<
+ virtual void print(raw_ostream &O) const = 0;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const MachineConstantPoolValue &V) {
+ V.print(OS);
+ return OS;
+}
+
+
+/// This class is a data container for one entry in a MachineConstantPool.
+/// It contains a pointer to the value and an offset from the start of
+/// the constant pool.
+/// @brief An entry in a MachineConstantPool
+class MachineConstantPoolEntry {
+public:
+ /// The constant itself.
+ union {
+ const Constant *ConstVal;
+ MachineConstantPoolValue *MachineCPVal;
+ } Val;
+
+ /// The required alignment for this entry. The top bit is set when Val is
+ /// a target specific MachineConstantPoolValue.
+ unsigned Alignment;
+
+ MachineConstantPoolEntry(const Constant *V, unsigned A)
+ : Alignment(A) {
+ Val.ConstVal = V;
+ }
+ MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned A)
+ : Alignment(A) {
+ Val.MachineCPVal = V;
+ Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1);
+ }
+
+ /// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry
+ /// is indeed a target specific constantpool entry, not a wrapper over a
+ /// Constant.
+ bool isMachineConstantPoolEntry() const {
+ return (int)Alignment < 0;
+ }
+
+ int getAlignment() const {
+ return Alignment & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
+ }
+
+ Type *getType() const;
+
+ /// getRelocationInfo - This method classifies the entry according to
+ /// whether or not it may generate a relocation entry. This must be
+ /// conservative, so if it might codegen to a relocatable entry, it should say
+ /// so. The return values are:
+ ///
+ /// 0: This constant pool entry is guaranteed to never have a relocation
+ /// applied to it (because it holds a simple constant like '4').
+ /// 1: This entry has relocations, but the entries are guaranteed to be
+ /// resolvable by the static linker, so the dynamic linker will never see
+ /// them.
+ /// 2: This entry may have arbitrary relocations.
+ unsigned getRelocationInfo() const;
+};
+
+/// The MachineConstantPool class keeps track of constants referenced by a
+/// function which must be spilled to memory. This is used for constants which
+/// are unable to be used directly as operands to instructions, which typically
+/// include floating point and large integer constants.
+///
+/// Instructions reference the address of these constant pool constants through
+/// the use of MO_ConstantPoolIndex values. When emitting assembly or machine
+/// code, these virtual address references are converted to refer to the
+/// address of the function constant pool values.
+/// @brief The machine constant pool.
+class MachineConstantPool {
+ const TargetData *TD; ///< The machine's TargetData.
+ 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)
+ : TD(td), PoolAlignment(1) {}
+ ~MachineConstantPool();
+
+ /// getConstantPoolAlignment - Return the alignment required by
+ /// the whole constant pool, of which the first element must be aligned.
+ unsigned getConstantPoolAlignment() const { return PoolAlignment; }
+
+ /// getConstantPoolIndex - Create a new entry in the constant pool or return
+ /// an existing one. User must specify the minimum required alignment for
+ /// the object.
+ unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment);
+ unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment);
+
+ /// isEmpty - Return true if this constant pool contains no constants.
+ bool isEmpty() const { return Constants.empty(); }
+
+ const std::vector<MachineConstantPoolEntry> &getConstants() const {
+ return Constants;
+ }
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// constant pool objects. Implemented in MachineFunction.cpp
+ ///
+ void print(raw_ostream &OS) const;
+
+ /// dump - Call print(cerr) to be called from the debugger.
+ void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineDominators.h b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h
new file mode 100644
index 000000000000..82a4ac821b69
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineDominators.h
@@ -0,0 +1,203 @@
+//=- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation --*- 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 classes mirroring those in llvm/Analysis/Dominators.h,
+// but for target-specific code rather than target-independent IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
+#define LLVM_CODEGEN_MACHINEDOMINATORS_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 {
+
+template<>
+inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB) {
+ this->Roots.push_back(MBB);
+}
+
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>);
+
+typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
+
+//===-------------------------------------
+/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
+/// compute a normal dominator tree.
+///
+class MachineDominatorTree : public MachineFunctionPass {
+public:
+ static char ID; // Pass ID, replacement for typeid
+ DominatorTreeBase<MachineBasicBlock>* DT;
+
+ MachineDominatorTree();
+
+ ~MachineDominatorTree();
+
+ DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<MachineBasicBlock*> &getRoots() const {
+ return DT->getRoots();
+ }
+
+ inline MachineBasicBlock *getRoot() const {
+ return DT->getRoot();
+ }
+
+ inline MachineDomTreeNode *getRootNode() const {
+ return DT->getRootNode();
+ }
+
+ virtual bool runOnMachineFunction(MachineFunction &F);
+
+ inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const {
+ return DT->dominates(A, B);
+ }
+
+ inline bool dominates(MachineBasicBlock* A, MachineBasicBlock* B) const {
+ return DT->dominates(A, B);
+ }
+
+ // dominates - Return true if A dominates B. This performs the
+ // special checks necessary if A and B are in the same basic block.
+ bool dominates(MachineInstr *A, MachineInstr *B) const {
+ MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
+ if (BBA != BBB) return DT->dominates(BBA, BBB);
+
+ // Loop through the basic block until we find A or B.
+ MachineBasicBlock::iterator I = BBA->begin();
+ for (; &*I != A && &*I != B; ++I)
+ /*empty*/ ;
+
+ //if(!DT.IsPostDominators) {
+ // A dominates B if it is found first in the basic block.
+ return &*I == A;
+ //} else {
+ // // A post-dominates B if B is found first in the basic block.
+ // return &*I == B;
+ //}
+ }
+
+ inline bool properlyDominates(const MachineDomTreeNode* A,
+ MachineDomTreeNode* B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ inline bool properlyDominates(MachineBasicBlock* A,
+ MachineBasicBlock* B) const {
+ return DT->properlyDominates(A, B);
+ }
+
+ /// findNearestCommonDominator - Find nearest common dominator basic block
+ /// for basic block A and B. If there is no such block then return NULL.
+ inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
+ MachineBasicBlock *B) {
+ return DT->findNearestCommonDominator(A, B);
+ }
+
+ inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ /// getNode - return the (Post)DominatorTree node for the specified basic
+ /// block. This is the same as using operator[] on this class.
+ ///
+ inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
+ return DT->getNode(BB);
+ }
+
+ /// addNewBlock - Add a new node to the dominator tree information. This
+ /// creates a new node as a child of DomBB dominator node,linking it into
+ /// the children list of the immediate dominator.
+ inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
+ MachineBasicBlock *DomBB) {
+ return DT->addNewBlock(BB, DomBB);
+ }
+
+ /// changeImmediateDominator - This method is used to update the dominator
+ /// tree information when a node's immediate dominator changes.
+ ///
+ inline void changeImmediateDominator(MachineBasicBlock *N,
+ MachineBasicBlock* NewIDom) {
+ DT->changeImmediateDominator(N, NewIDom);
+ }
+
+ inline void changeImmediateDominator(MachineDomTreeNode *N,
+ MachineDomTreeNode* NewIDom) {
+ DT->changeImmediateDominator(N, NewIDom);
+ }
+
+ /// eraseNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Removes node from its immediate dominator's
+ /// children list. Deletes dominator node associated with basic block BB.
+ inline void eraseNode(MachineBasicBlock *BB) {
+ DT->eraseNode(BB);
+ }
+
+ /// splitBlock - BB is split and now it has one successor. Update dominator
+ /// tree to reflect this change.
+ inline void splitBlock(MachineBasicBlock* NewBB) {
+ DT->splitBlock(NewBB);
+ }
+
+ /// isReachableFromEntry - Return true if A is dominated by the entry
+ /// block of the function containing it.
+ bool isReachableFromEntry(MachineBasicBlock *A) {
+ return DT->isReachableFromEntry(A);
+ }
+
+ virtual void releaseMemory();
+
+ virtual void print(raw_ostream &OS, const Module*) const;
+};
+
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+
+template<class T> struct GraphTraits;
+
+template <> struct GraphTraits<MachineDomTreeNode *> {
+ typedef MachineDomTreeNode NodeType;
+ typedef NodeType::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(NodeType *N) {
+ return N;
+ }
+ static inline ChildIteratorType child_begin(NodeType* N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType* N) {
+ return N->end();
+ }
+};
+
+template <> struct GraphTraits<MachineDominatorTree*>
+ : public GraphTraits<MachineDomTreeNode *> {
+ static NodeType *getEntryNode(MachineDominatorTree *DT) {
+ return DT->getRootNode();
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
new file mode 100644
index 000000000000..44402a9e68fb
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -0,0 +1,561 @@
+//===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The file defines the MachineFrameInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
+#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+class raw_ostream;
+class TargetData;
+class TargetRegisterClass;
+class Type;
+class MachineFunction;
+class MachineBasicBlock;
+class TargetFrameLowering;
+class BitVector;
+
+/// The CalleeSavedInfo class tracks the information need to locate where a
+/// callee saved register is in the current frame.
+class CalleeSavedInfo {
+ unsigned Reg;
+ int FrameIdx;
+
+public:
+ explicit CalleeSavedInfo(unsigned R, int FI = 0)
+ : Reg(R), FrameIdx(FI) {}
+
+ // Accessors.
+ unsigned getReg() const { return Reg; }
+ int getFrameIdx() const { return FrameIdx; }
+ void setFrameIdx(int FI) { FrameIdx = FI; }
+};
+
+/// The MachineFrameInfo class represents an abstract stack frame until
+/// prolog/epilog code is inserted. This class is key to allowing stack frame
+/// representation optimizations, such as frame pointer elimination. It also
+/// allows more mundane (but still important) optimizations, such as reordering
+/// of abstract objects on the stack frame.
+///
+/// To support this, the class assigns unique integer identifiers to stack
+/// objects requested clients. These identifiers are negative integers for
+/// fixed stack objects (such as arguments passed on the stack) or nonnegative
+/// for objects that may be reordered. Instructions which refer to stack
+/// objects use a special MO_FrameIndex operand to represent these frame
+/// indexes.
+///
+/// Because this class keeps track of all references to the stack frame, it
+/// knows when a variable sized object is allocated on the stack. This is the
+/// sole condition which prevents frame pointer elimination, which is an
+/// important optimization on register-poor architectures. Because original
+/// variable sized alloca's in the source program are the only source of
+/// variable sized stack objects, it is safe to decide whether there will be
+/// any variable sized objects before all stack objects are known (for
+/// example, register allocator spill code never needs variable sized
+/// objects).
+///
+/// When prolog/epilog code emission is performed, the final stack frame is
+/// built and the machine instructions are modified to refer to the actual
+/// stack offsets of the object, eliminating all MO_FrameIndex operands from
+/// the program.
+///
+/// @brief Abstract Stack Frame Information
+class MachineFrameInfo {
+
+ // StackObject - Represent a single object allocated on the stack.
+ struct StackObject {
+ // SPOffset - The offset of this object from the stack pointer on entry to
+ // the function. This field has no meaning for a variable sized element.
+ int64_t SPOffset;
+
+ // The size of this object on the stack. 0 means a variable sized object,
+ // ~0ULL means a dead object.
+ uint64_t Size;
+
+ // Alignment - The required alignment of this stack slot.
+ unsigned Alignment;
+
+ // isImmutable - If true, the value of the stack object is set before
+ // entering the function and is not modified inside the function. By
+ // default, fixed objects are immutable unless marked otherwise.
+ bool isImmutable;
+
+ // isSpillSlot - If true the stack object is used as spill slot. It
+ // cannot alias any other memory objects.
+ bool isSpillSlot;
+
+ // MayNeedSP - If true the stack object triggered the creation of the stack
+ // protector. We should allocate this object right after the stack
+ // protector.
+ bool MayNeedSP;
+
+ // 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)
+ : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
+ isSpillSlot(isSS), MayNeedSP(NSP), PreAllocated(false) {}
+ };
+
+ /// Objects - The list of stack objects allocated...
+ ///
+ std::vector<StackObject> Objects;
+
+ /// NumFixedObjects - This contains the number of fixed objects contained on
+ /// the stack. Because fixed objects are stored at a negative index in the
+ /// Objects list, this is also the index to the 0th object in the list.
+ ///
+ unsigned NumFixedObjects;
+
+ /// HasVarSizedObjects - This boolean keeps track of whether any variable
+ /// sized objects have been allocated yet.
+ ///
+ bool HasVarSizedObjects;
+
+ /// FrameAddressTaken - This boolean keeps track of whether there is a call
+ /// to builtin \@llvm.frameaddress.
+ bool FrameAddressTaken;
+
+ /// ReturnAddressTaken - This boolean keeps track of whether there is a call
+ /// to builtin \@llvm.returnaddress.
+ bool ReturnAddressTaken;
+
+ /// StackSize - The prolog/epilog code inserter calculates the final stack
+ /// offsets for all of the fixed size objects, updating the Objects list
+ /// above. It then updates StackSize to contain the number of bytes that need
+ /// to be allocated on entry to the function.
+ ///
+ uint64_t StackSize;
+
+ /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to
+ /// have the actual offset from the stack/frame pointer. The exact usage of
+ /// this is target-dependent, but it is typically used to adjust between
+ /// SP-relative and FP-relative offsets. E.G., if objects are accessed via
+ /// SP then OffsetAdjustment is zero; if FP is used, OffsetAdjustment is set
+ /// to the distance between the initial SP and the value in FP. For many
+ /// targets, this value is only used when generating debug info (via
+ /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the
+ /// corresponding adjustments are performed directly.
+ int OffsetAdjustment;
+
+ /// MaxAlignment - The prolog/epilog code inserter may process objects
+ /// that require greater alignment than the default alignment the target
+ /// provides. To handle this, MaxAlignment is set to the maximum alignment
+ /// needed by the objects on the current frame. If this is greater than the
+ /// native alignment maintained by the compiler, dynamic alignment code will
+ /// be needed.
+ ///
+ unsigned MaxAlignment;
+
+ /// AdjustsStack - Set to true if this function adjusts the stack -- e.g.,
+ /// when calling another function. This is only valid during and after
+ /// prolog/epilog code insertion.
+ bool AdjustsStack;
+
+ /// HasCalls - Set to true if this function has any function calls.
+ bool HasCalls;
+
+ /// StackProtectorIdx - The frame index for the stack protector.
+ int StackProtectorIdx;
+
+ /// FunctionContextIdx - The frame index for the function context. Used for
+ /// SjLj exceptions.
+ int FunctionContextIdx;
+
+ /// MaxCallFrameSize - This contains the size of the largest call frame if the
+ /// target uses frame setup/destroy pseudo instructions (as defined in the
+ /// TargetFrameInfo class). This information is important for frame pointer
+ /// elimination. If is only valid during and after prolog/epilog code
+ /// insertion.
+ ///
+ unsigned MaxCallFrameSize;
+
+ /// CSInfo - The prolog/epilog code inserter fills in this vector with each
+ /// callee saved register saved in the frame. Beyond its use by the prolog/
+ /// epilog code inserter, this data used for debug info and exception
+ /// handling.
+ std::vector<CalleeSavedInfo> CSInfo;
+
+ /// CSIValid - Has CSInfo been set yet?
+ bool CSIValid;
+
+ /// TargetFrameLowering - Target information about frame layout.
+ ///
+ const TargetFrameLowering &TFI;
+
+ /// LocalFrameObjects - References to frame indices which are mapped
+ /// into the local frame allocation block. <FrameIdx, LocalOffset>
+ SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
+
+ /// LocalFrameSize - Size of the pre-allocated local frame block.
+ int64_t LocalFrameSize;
+
+ /// Required alignment of the local object blob, which is the strictest
+ /// alignment of any object in it.
+ unsigned LocalFrameMaxAlign;
+
+ /// Whether the local object blob needs to be allocated together. If not,
+ /// PEI should ignore the isPreAllocated flags on the stack objects and
+ /// just allocate them normally.
+ bool UseLocalStackAllocationBlock;
+
+public:
+ explicit MachineFrameInfo(const TargetFrameLowering &tfi) : TFI(tfi) {
+ StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
+ HasVarSizedObjects = false;
+ FrameAddressTaken = false;
+ ReturnAddressTaken = false;
+ AdjustsStack = false;
+ HasCalls = false;
+ StackProtectorIdx = -1;
+ FunctionContextIdx = -1;
+ MaxCallFrameSize = 0;
+ CSIValid = false;
+ LocalFrameSize = 0;
+ LocalFrameMaxAlign = 0;
+ UseLocalStackAllocationBlock = false;
+ }
+
+ /// hasStackObjects - Return true if there are any stack objects in this
+ /// function.
+ ///
+ bool hasStackObjects() const { return !Objects.empty(); }
+
+ /// hasVarSizedObjects - This method may be called any time after instruction
+ /// selection is complete to determine if the stack frame for this function
+ /// contains any variable sized objects.
+ ///
+ bool hasVarSizedObjects() const { return HasVarSizedObjects; }
+
+ /// getStackProtectorIndex/setStackProtectorIndex - Return the index for the
+ /// stack protector object.
+ ///
+ int getStackProtectorIndex() const { return StackProtectorIdx; }
+ void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
+
+ /// getFunctionContextIndex/setFunctionContextIndex - Return the index for the
+ /// function context object. This object is used for SjLj exceptions.
+ int getFunctionContextIndex() const { return FunctionContextIdx; }
+ void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
+
+ /// isFrameAddressTaken - This method may be called any time after instruction
+ /// selection is complete to determine if there is a call to
+ /// \@llvm.frameaddress in this function.
+ bool isFrameAddressTaken() const { return FrameAddressTaken; }
+ void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
+
+ /// isReturnAddressTaken - This method may be called any time after
+ /// instruction selection is complete to determine if there is a call to
+ /// \@llvm.returnaddress in this function.
+ bool isReturnAddressTaken() const { return ReturnAddressTaken; }
+ void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
+
+ /// getObjectIndexBegin - Return the minimum frame object index.
+ ///
+ int getObjectIndexBegin() const { return -NumFixedObjects; }
+
+ /// getObjectIndexEnd - Return one past the maximum frame object index.
+ ///
+ int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; }
+
+ /// getNumFixedObjects - Return the number of fixed objects.
+ unsigned getNumFixedObjects() const { return NumFixedObjects; }
+
+ /// getNumObjects - Return the number of objects.
+ ///
+ unsigned getNumObjects() const { return Objects.size(); }
+
+ /// mapLocalFrameObject - Map a frame index into the local object block
+ void mapLocalFrameObject(int ObjectIndex, int64_t Offset) {
+ LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset));
+ Objects[ObjectIndex + NumFixedObjects].PreAllocated = true;
+ }
+
+ /// getLocalFrameObjectMap - Get the local offset mapping for a for an object
+ std::pair<int, int64_t> getLocalFrameObjectMap(int i) {
+ assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() &&
+ "Invalid local object reference!");
+ return LocalFrameObjects[i];
+ }
+
+ /// getLocalFrameObjectCount - Return the number of objects allocated into
+ /// the local object block.
+ int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); }
+
+ /// setLocalFrameSize - Set the size of the local object blob.
+ void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; }
+
+ /// getLocalFrameSize - Get the size of the local object blob.
+ int64_t getLocalFrameSize() const { return LocalFrameSize; }
+
+ /// setLocalFrameMaxAlign - Required alignment of the local object blob,
+ /// which is the strictest alignment of any object in it.
+ void setLocalFrameMaxAlign(unsigned Align) { LocalFrameMaxAlign = Align; }
+
+ /// getLocalFrameMaxAlign - Return the required alignment of the local
+ /// object blob.
+ unsigned getLocalFrameMaxAlign() const { return LocalFrameMaxAlign; }
+
+ /// getUseLocalStackAllocationBlock - Get whether the local allocation blob
+ /// should be allocated together or let PEI allocate the locals in it
+ /// directly.
+ bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;}
+
+ /// setUseLocalStackAllocationBlock - Set whether the local allocation blob
+ /// should be allocated together or let PEI allocate the locals in it
+ /// directly.
+ void setUseLocalStackAllocationBlock(bool v) {
+ UseLocalStackAllocationBlock = v;
+ }
+
+ /// isObjectPreAllocated - Return true if the object was pre-allocated into
+ /// the local block.
+ bool isObjectPreAllocated(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].PreAllocated;
+ }
+
+ /// getObjectSize - Return the size of the specified object.
+ ///
+ int64_t getObjectSize(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Size;
+ }
+
+ /// setObjectSize - Change the size of the specified stack object.
+ void setObjectSize(int ObjectIdx, int64_t Size) {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ Objects[ObjectIdx+NumFixedObjects].Size = Size;
+ }
+
+ /// getObjectAlignment - Return the alignment of the specified stack object.
+ unsigned getObjectAlignment(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Alignment;
+ }
+
+ /// setObjectAlignment - Change the alignment of the specified stack object.
+ void setObjectAlignment(int ObjectIdx, unsigned Align) {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
+ MaxAlignment = std::max(MaxAlignment, Align);
+ }
+
+ /// NeedsStackProtector - Returns true if the object may need stack
+ /// protectors.
+ bool MayNeedStackProtector(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].MayNeedSP;
+ }
+
+ /// getObjectOffset - Return the assigned stack offset of the specified object
+ /// from the incoming stack pointer.
+ ///
+ int64_t getObjectOffset(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ assert(!isDeadObjectIndex(ObjectIdx) &&
+ "Getting frame offset for a dead object?");
+ return Objects[ObjectIdx+NumFixedObjects].SPOffset;
+ }
+
+ /// setObjectOffset - Set the stack frame offset of the specified object. The
+ /// offset is relative to the stack pointer on entry to the function.
+ ///
+ void setObjectOffset(int ObjectIdx, int64_t SPOffset) {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ assert(!isDeadObjectIndex(ObjectIdx) &&
+ "Setting frame offset for a dead object?");
+ Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
+ }
+
+ /// getStackSize - Return the number of bytes that must be allocated to hold
+ /// all of the fixed size frame objects. This is only valid after
+ /// Prolog/Epilog code insertion has finalized the stack frame layout.
+ ///
+ uint64_t getStackSize() const { return StackSize; }
+
+ /// setStackSize - Set the size of the stack...
+ ///
+ void setStackSize(uint64_t Size) { StackSize = Size; }
+
+ /// getOffsetAdjustment - Return the correction for frame offsets.
+ ///
+ int getOffsetAdjustment() const { return OffsetAdjustment; }
+
+ /// setOffsetAdjustment - Set the correction for frame offsets.
+ ///
+ void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
+
+ /// getMaxAlignment - Return the alignment in bytes that this function must be
+ /// aligned to, which is greater than the default stack alignment provided by
+ /// the target.
+ ///
+ unsigned getMaxAlignment() const { return MaxAlignment; }
+
+ /// setMaxAlignment - Set the preferred alignment.
+ ///
+ void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
+
+ /// AdjustsStack - Return true if this function adjusts the stack -- e.g.,
+ /// when calling another function. This is only valid during and after
+ /// prolog/epilog code insertion.
+ bool adjustsStack() const { return AdjustsStack; }
+ void setAdjustsStack(bool V) { AdjustsStack = V; }
+
+ /// hasCalls - Return true if the current function has any function calls.
+ bool hasCalls() const { return HasCalls; }
+ void setHasCalls(bool V) { HasCalls = V; }
+
+ /// getMaxCallFrameSize - Return the maximum size of a call frame that must be
+ /// allocated for an outgoing function call. This is only available if
+ /// CallFrameSetup/Destroy pseudo instructions are used by the target, and
+ /// then only during or after prolog/epilog code insertion.
+ ///
+ unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
+ void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
+
+ /// CreateFixedObject - Create a new object at a fixed location on the stack.
+ /// All fixed objects should be created before other objects are created for
+ /// efficiency. By default, fixed objects are immutable. This returns an
+ /// index with a negative value.
+ ///
+ int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
+
+
+ /// isFixedObjectIndex - Returns true if the specified index corresponds to a
+ /// fixed stack object.
+ bool isFixedObjectIndex(int ObjectIdx) const {
+ return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
+ }
+
+ /// isImmutableObjectIndex - Returns true if the specified index corresponds
+ /// to an immutable object.
+ bool isImmutableObjectIndex(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].isImmutable;
+ }
+
+ /// isSpillSlotObjectIndex - Returns true if the specified index corresponds
+ /// to a spill slot..
+ bool isSpillSlotObjectIndex(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].isSpillSlot;
+ }
+
+ /// isDeadObjectIndex - Returns true if the specified index corresponds to
+ /// a dead object.
+ bool isDeadObjectIndex(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
+ }
+
+ /// CreateStackObject - Create a new statically sized stack object, returning
+ /// a nonnegative identifier to represent it.
+ ///
+ int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
+ bool MayNeedSP = false) {
+ assert(Size != 0 && "Cannot allocate zero size stack objects!");
+ Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP));
+ int Index = (int)Objects.size() - NumFixedObjects - 1;
+ assert(Index >= 0 && "Bad frame index!");
+ MaxAlignment = std::max(MaxAlignment, Alignment);
+ return Index;
+ }
+
+ /// 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;
+ MaxAlignment = std::max(MaxAlignment, Alignment);
+ return Index;
+ }
+
+ /// RemoveStackObject - Remove or mark dead a statically sized stack object.
+ ///
+ void RemoveStackObject(int ObjectIdx) {
+ // Mark it dead.
+ Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
+ }
+
+ /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
+ /// variable sized object has been created. This must be created whenever a
+ /// 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));
+ MaxAlignment = std::max(MaxAlignment, Alignment);
+ return (int)Objects.size()-NumFixedObjects-1;
+ }
+
+ /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
+ /// current function.
+ const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const {
+ return CSInfo;
+ }
+
+ /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
+ /// callee saved information.
+ void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
+ CSInfo = CSI;
+ }
+
+ /// isCalleeSavedInfoValid - Has the callee saved info been calculated yet?
+ bool isCalleeSavedInfoValid() const { return CSIValid; }
+
+ void setCalleeSavedInfoValid(bool v) { CSIValid = v; }
+
+ /// getPristineRegs - Return a set of physical registers that are pristine on
+ /// entry to the MBB.
+ ///
+ /// Pristine registers hold a value that is useless to the current function,
+ /// but that must be preserved - they are callee saved registers that have not
+ /// been saved yet.
+ ///
+ /// Before the PrologueEpilogueInserter has placed the CSR spill code, this
+ /// method always returns an empty set.
+ BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// stack objects. Implemented in MachineFunction.cpp
+ ///
+ void print(const MachineFunction &MF, raw_ostream &OS) const;
+
+ /// dump - Print the function to stderr.
+ void dump(const MachineFunction &MF) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunction.h b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
new file mode 100644
index 000000000000..dda2dc708769
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -0,0 +1,487 @@
+//===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect native machine code for a function. This class contains a list of
+// MachineBasicBlock instances that make up the current compiled function.
+//
+// This class also contains pointers to various classes which hold
+// target-specific information about the generated code.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/Allocator.h"
+#include "llvm/Support/Recycler.h"
+
+namespace llvm {
+
+class Value;
+class Function;
+class GCModuleInfo;
+class MachineRegisterInfo;
+class MachineFrameInfo;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineModuleInfo;
+class MCContext;
+class Pass;
+class TargetMachine;
+class TargetRegisterClass;
+struct MachinePointerInfo;
+
+template <>
+struct ilist_traits<MachineBasicBlock>
+ : public ilist_default_traits<MachineBasicBlock> {
+ mutable ilist_half_node<MachineBasicBlock> Sentinel;
+public:
+ MachineBasicBlock *createSentinel() const {
+ return static_cast<MachineBasicBlock*>(&Sentinel);
+ }
+ void destroySentinel(MachineBasicBlock *) const {}
+
+ MachineBasicBlock *provideInitialHead() const { return createSentinel(); }
+ MachineBasicBlock *ensureHead(MachineBasicBlock*) const {
+ return createSentinel();
+ }
+ static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {}
+
+ void addNodeToList(MachineBasicBlock* MBB);
+ void removeNodeFromList(MachineBasicBlock* MBB);
+ void deleteNode(MachineBasicBlock *MBB);
+private:
+ void createNode(const MachineBasicBlock &);
+};
+
+/// MachineFunctionInfo - This class can be derived from and used by targets to
+/// hold private target-specific information for each MachineFunction. Objects
+/// of type are accessed/created with MF::getInfo and destroyed when the
+/// MachineFunction is destroyed.
+struct MachineFunctionInfo {
+ virtual ~MachineFunctionInfo();
+};
+
+class MachineFunction {
+ const Function *Fn;
+ const TargetMachine &Target;
+ MCContext &Ctx;
+ MachineModuleInfo &MMI;
+ GCModuleInfo *GMI;
+
+ // RegInfo - Information about each register in use in the function.
+ MachineRegisterInfo *RegInfo;
+
+ // Used to keep track of target-specific per-machine function information for
+ // the target implementation.
+ MachineFunctionInfo *MFInfo;
+
+ // Keep track of objects allocated on the stack.
+ MachineFrameInfo *FrameInfo;
+
+ // Keep track of constants which are spilled to memory
+ MachineConstantPool *ConstantPool;
+
+ // Keep track of jump tables for switch instructions
+ MachineJumpTableInfo *JumpTableInfo;
+
+ // Function-level unique numbering for MachineBasicBlocks. When a
+ // MachineBasicBlock is inserted into a MachineFunction is it automatically
+ // numbered and this vector keeps track of the mapping from ID's to MBB's.
+ std::vector<MachineBasicBlock*> MBBNumbering;
+
+ // Pool-allocate MachineFunction-lifetime and IR objects.
+ BumpPtrAllocator Allocator;
+
+ // Allocation management for instructions in function.
+ Recycler<MachineInstr> InstructionRecycler;
+
+ // Allocation management for basic blocks in function.
+ Recycler<MachineBasicBlock> BasicBlockRecycler;
+
+ // List of machine basic blocks in function
+ typedef ilist<MachineBasicBlock> BasicBlockListType;
+ BasicBlockListType BasicBlocks;
+
+ /// FunctionNumber - This provides a unique ID for each function emitted in
+ /// this translation unit.
+ ///
+ unsigned FunctionNumber;
+
+ /// Alignment - The alignment of the function.
+ unsigned Alignment;
+
+ /// ExposesReturnsTwice - True if the function calls setjmp or related
+ /// functions with attribute "returns twice", but doesn't have
+ /// the attribute itself.
+ /// This is used to limit optimizations which cannot reason
+ /// about the control flow of such functions.
+ bool ExposesReturnsTwice;
+
+ MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
+ void operator=(const MachineFunction&); // DO NOT IMPLEMENT
+public:
+ MachineFunction(const Function *Fn, const TargetMachine &TM,
+ unsigned FunctionNum, MachineModuleInfo &MMI,
+ GCModuleInfo* GMI);
+ ~MachineFunction();
+
+ MachineModuleInfo &getMMI() const { return MMI; }
+ GCModuleInfo *getGMI() const { return GMI; }
+ MCContext &getContext() const { return Ctx; }
+
+ /// getFunction - Return the LLVM function that this machine code represents
+ ///
+ const Function *getFunction() const { return Fn; }
+
+ /// getFunctionNumber - Return a unique ID for the current function.
+ ///
+ unsigned getFunctionNumber() const { return FunctionNumber; }
+
+ /// getTarget - Return the target machine this machine code is compiled with
+ ///
+ const TargetMachine &getTarget() const { return Target; }
+
+ /// getRegInfo - Return information about the registers currently in use.
+ ///
+ MachineRegisterInfo &getRegInfo() { return *RegInfo; }
+ const MachineRegisterInfo &getRegInfo() const { return *RegInfo; }
+
+ /// getFrameInfo - Return the frame info object for the current function.
+ /// This object contains information about objects allocated on the stack
+ /// frame of the current function in an abstract way.
+ ///
+ MachineFrameInfo *getFrameInfo() { return FrameInfo; }
+ const MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
+
+ /// getJumpTableInfo - Return the jump table info object for the current
+ /// function. This object contains information about jump tables in the
+ /// current function. If the current function has no jump tables, this will
+ /// return null.
+ const MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
+ MachineJumpTableInfo *getJumpTableInfo() { return JumpTableInfo; }
+
+ /// getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it
+ /// does already exist, allocate one.
+ MachineJumpTableInfo *getOrCreateJumpTableInfo(unsigned JTEntryKind);
+
+
+ /// getConstantPool - Return the constant pool object for the current
+ /// function.
+ ///
+ MachineConstantPool *getConstantPool() { return ConstantPool; }
+ const MachineConstantPool *getConstantPool() const { return ConstantPool; }
+
+ /// getAlignment - Return the alignment (log2, not bytes) of the function.
+ ///
+ unsigned getAlignment() const { return Alignment; }
+
+ /// setAlignment - Set the alignment (log2, not bytes) of the function.
+ ///
+ void setAlignment(unsigned A) { Alignment = A; }
+
+ /// EnsureAlignment - Make sure the function is at least 1 << A bytes aligned.
+ void EnsureAlignment(unsigned A) {
+ if (Alignment < A) Alignment = A;
+ }
+
+ /// exposesReturnsTwice - Returns true if the function calls setjmp or
+ /// any other similar functions with attribute "returns twice" without
+ /// having the attribute itself.
+ bool exposesReturnsTwice() const {
+ return ExposesReturnsTwice;
+ }
+
+ /// setCallsSetJmp - Set a flag that indicates if there's a call to
+ /// a "returns twice" function.
+ void setExposesReturnsTwice(bool B) {
+ ExposesReturnsTwice = B;
+ }
+
+ /// getInfo - Keep track of various per-function pieces of information for
+ /// backends that would like to do so.
+ ///
+ template<typename Ty>
+ Ty *getInfo() {
+ if (!MFInfo) {
+ // This should be just `new (Allocator.Allocate<Ty>()) Ty(*this)', but
+ // that apparently breaks GCC 3.3.
+ Ty *Loc = static_cast<Ty*>(Allocator.Allocate(sizeof(Ty),
+ AlignOf<Ty>::Alignment));
+ MFInfo = new (Loc) Ty(*this);
+ }
+ return static_cast<Ty*>(MFInfo);
+ }
+
+ template<typename Ty>
+ const Ty *getInfo() const {
+ return const_cast<MachineFunction*>(this)->getInfo<Ty>();
+ }
+
+ /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they
+ /// are inserted into the machine function. The block number for a machine
+ /// basic block can be found by using the MBB::getBlockNumber method, this
+ /// method provides the inverse mapping.
+ ///
+ MachineBasicBlock *getBlockNumbered(unsigned N) const {
+ assert(N < MBBNumbering.size() && "Illegal block number");
+ assert(MBBNumbering[N] && "Block was removed from the machine function!");
+ return MBBNumbering[N];
+ }
+
+ /// getNumBlockIDs - Return the number of MBB ID's allocated.
+ ///
+ unsigned getNumBlockIDs() const { return (unsigned)MBBNumbering.size(); }
+
+ /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
+ /// recomputes them. This guarantees that the MBB numbers are sequential,
+ /// dense, and match the ordering of the blocks within the function. If a
+ /// specific MachineBasicBlock is specified, only that block and those after
+ /// it are renumbered.
+ void RenumberBlocks(MachineBasicBlock *MBBFrom = 0);
+
+ /// print - Print out the MachineFunction in a format suitable for debugging
+ /// to the specified stream.
+ ///
+ void print(raw_ostream &OS, SlotIndexes* = 0) const;
+
+ /// viewCFG - This function is meant for use from the debugger. You can just
+ /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+ /// program, displaying the CFG of the current function with the code for each
+ /// basic block inside. This depends on there being a 'dot' and 'gv' program
+ /// in your path.
+ ///
+ void viewCFG() const;
+
+ /// viewCFGOnly - This function is meant for use from the debugger. It works
+ /// just like viewCFG, but it does not include the contents of basic blocks
+ /// into the nodes, just the label. If you are only interested in the CFG
+ /// this can make the graph smaller.
+ ///
+ void viewCFGOnly() const;
+
+ /// dump - Print the current MachineFunction to cerr, useful for debugger use.
+ ///
+ void dump() const;
+
+ /// verify - Run the current MachineFunction through the machine code
+ /// verifier, useful for debugger use.
+ void verify(Pass *p = NULL, const char *Banner = NULL) const;
+
+ // Provide accessors for the MachineBasicBlock list...
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ /// addLiveIn - Add the specified physical register as a live-in value and
+ /// create a corresponding virtual register for it.
+ unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC);
+
+ //===--------------------------------------------------------------------===//
+ // BasicBlock accessor functions.
+ //
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
+ const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
+ reverse_iterator rend () { return BasicBlocks.rend(); }
+ const_reverse_iterator rend () const { return BasicBlocks.rend(); }
+
+ unsigned size() const { return (unsigned)BasicBlocks.size();}
+ bool empty() const { return BasicBlocks.empty(); }
+ const MachineBasicBlock &front() const { return BasicBlocks.front(); }
+ MachineBasicBlock &front() { return BasicBlocks.front(); }
+ const MachineBasicBlock & back() const { return BasicBlocks.back(); }
+ MachineBasicBlock & back() { return BasicBlocks.back(); }
+
+ void push_back (MachineBasicBlock *MBB) { BasicBlocks.push_back (MBB); }
+ void push_front(MachineBasicBlock *MBB) { BasicBlocks.push_front(MBB); }
+ void insert(iterator MBBI, MachineBasicBlock *MBB) {
+ BasicBlocks.insert(MBBI, MBB);
+ }
+ void splice(iterator InsertPt, iterator MBBI) {
+ BasicBlocks.splice(InsertPt, BasicBlocks, MBBI);
+ }
+ void splice(iterator InsertPt, iterator MBBI, iterator MBBE) {
+ BasicBlocks.splice(InsertPt, BasicBlocks, MBBI, MBBE);
+ }
+
+ void remove(iterator MBBI) {
+ BasicBlocks.remove(MBBI);
+ }
+ void erase(iterator MBBI) {
+ BasicBlocks.erase(MBBI);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Internal functions used to automatically number MachineBasicBlocks
+ //
+
+ /// getNextMBBNumber - Returns the next unique number to be assigned
+ /// to a MachineBasicBlock in this MachineFunction.
+ ///
+ unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
+ MBBNumbering.push_back(MBB);
+ return (unsigned)MBBNumbering.size()-1;
+ }
+
+ /// removeFromMBBNumbering - Remove the specific machine basic block from our
+ /// tracker, this is only really to be used by the MachineBasicBlock
+ /// implementation.
+ void removeFromMBBNumbering(unsigned N) {
+ assert(N < MBBNumbering.size() && "Illegal basic block #");
+ MBBNumbering[N] = 0;
+ }
+
+ /// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
+ /// of `new MachineInstr'.
+ ///
+ MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID,
+ DebugLoc DL,
+ bool NoImp = false);
+
+ /// CloneMachineInstr - Create a new MachineInstr which is a copy of the
+ /// 'Orig' instruction, identical in all ways except the instruction
+ /// has no parent, prev, or next.
+ ///
+ /// See also TargetInstrInfo::duplicate() for target-specific fixes to cloned
+ /// instructions.
+ MachineInstr *CloneMachineInstr(const MachineInstr *Orig);
+
+ /// DeleteMachineInstr - Delete the given MachineInstr.
+ ///
+ void DeleteMachineInstr(MachineInstr *MI);
+
+ /// CreateMachineBasicBlock - Allocate a new MachineBasicBlock. Use this
+ /// instead of `new MachineBasicBlock'.
+ ///
+ MachineBasicBlock *CreateMachineBasicBlock(const BasicBlock *bb = 0);
+
+ /// DeleteMachineBasicBlock - Delete the given MachineBasicBlock.
+ ///
+ void DeleteMachineBasicBlock(MachineBasicBlock *MBB);
+
+ /// getMachineMemOperand - Allocate a new MachineMemOperand.
+ /// MachineMemOperands are owned by the MachineFunction and need not be
+ /// explicitly deallocated.
+ MachineMemOperand *getMachineMemOperand(MachinePointerInfo PtrInfo,
+ unsigned f, uint64_t s,
+ unsigned base_alignment,
+ const MDNode *TBAAInfo = 0,
+ const MDNode *Ranges = 0);
+
+ /// getMachineMemOperand - Allocate a new MachineMemOperand by copying
+ /// an existing one, adjusting by an offset and using the given size.
+ /// MachineMemOperands are owned by the MachineFunction and need not be
+ /// explicitly deallocated.
+ MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
+ int64_t Offset, uint64_t Size);
+
+ /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
+ /// pointers. This array is owned by the MachineFunction.
+ MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
+
+ /// extractLoadMemRefs - Allocate an array and populate it with just the
+ /// load information from the given MachineMemOperand sequence.
+ std::pair<MachineInstr::mmo_iterator,
+ MachineInstr::mmo_iterator>
+ extractLoadMemRefs(MachineInstr::mmo_iterator Begin,
+ MachineInstr::mmo_iterator End);
+
+ /// extractStoreMemRefs - Allocate an array and populate it with just the
+ /// store information from the given MachineMemOperand sequence.
+ std::pair<MachineInstr::mmo_iterator,
+ MachineInstr::mmo_iterator>
+ extractStoreMemRefs(MachineInstr::mmo_iterator Begin,
+ MachineInstr::mmo_iterator End);
+
+ //===--------------------------------------------------------------------===//
+ // Label Manipulation.
+ //
+
+ /// getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
+ /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
+ /// normal 'L' label is returned.
+ MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
+ bool isLinkerPrivate = false) const;
+
+ /// getPICBaseSymbol - Return a function-local symbol to represent the PIC
+ /// base.
+ MCSymbol *getPICBaseSymbol() const;
+};
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// machine function as a graph of machine basic blocks... these are
+// the same as the machine basic block iterators, except that the root
+// node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<MachineFunction*> :
+ public GraphTraits<MachineBasicBlock*> {
+ static NodeType *getEntryNode(MachineFunction *F) {
+ return &F->front();
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef MachineFunction::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(MachineFunction *F) { return F->begin(); }
+ static nodes_iterator nodes_end (MachineFunction *F) { return F->end(); }
+ static unsigned size (MachineFunction *F) { return F->size(); }
+};
+template <> struct GraphTraits<const MachineFunction*> :
+ public GraphTraits<const MachineBasicBlock*> {
+ static NodeType *getEntryNode(const MachineFunction *F) {
+ return &F->front();
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef MachineFunction::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const MachineFunction *F) {
+ return F->begin();
+ }
+ static nodes_iterator nodes_end (const MachineFunction *F) {
+ return F->end();
+ }
+ static unsigned size (const MachineFunction *F) {
+ return F->size();
+ }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineFunction*> > :
+ public GraphTraits<Inverse<MachineBasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<MachineFunction*> G) {
+ return &G.Graph->front();
+ }
+};
+template <> struct GraphTraits<Inverse<const MachineFunction*> > :
+ public GraphTraits<Inverse<const MachineBasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const MachineFunction *> G) {
+ return &G.Graph->front();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h b/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h
new file mode 100644
index 000000000000..50ea2062f30c
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -0,0 +1,51 @@
+//===-- MachineFunctionAnalysis.h - Owner of MachineFunctions ----*-C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MachineFunctionAnalysis class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H
+#define LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H
+
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+class MachineFunction;
+
+/// MachineFunctionAnalysis - This class is a Pass that manages a
+/// MachineFunction object.
+struct MachineFunctionAnalysis : public FunctionPass {
+private:
+ const TargetMachine &TM;
+ MachineFunction *MF;
+ unsigned NextFnNum;
+public:
+ static char ID;
+ explicit MachineFunctionAnalysis(const TargetMachine &tm);
+ ~MachineFunctionAnalysis();
+
+ MachineFunction &getMF() const { return *MF; }
+
+ virtual const char* getPassName() const {
+ return "Machine Function Analysis";
+ }
+
+private:
+ virtual bool doInitialization(Module &M);
+ virtual bool runOnFunction(Function &F);
+ virtual void releaseMemory();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h b/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h
new file mode 100644
index 000000000000..b7bf0a36c447
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineFunctionPass.h
@@ -0,0 +1,59 @@
+//===-- MachineFunctionPass.h - Pass for MachineFunctions --------*-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 MachineFunctionPass class. MachineFunctionPass's are
+// just FunctionPass's, except they operate on machine code as part of a code
+// generator. Because they operate on machine code, not the LLVM
+// representation, MachineFunctionPass's are not allowed to modify the LLVM
+// representation. Due to this limitation, the MachineFunctionPass class takes
+// care of declaring that no LLVM passes are invalidated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+#define LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class MachineFunction;
+
+/// MachineFunctionPass - This class adapts the FunctionPass interface to
+/// allow convenient creation of passes that operate on the MachineFunction
+/// representation. Instead of overriding runOnFunction, subclasses
+/// override runOnMachineFunction.
+class MachineFunctionPass : public FunctionPass {
+protected:
+ explicit MachineFunctionPass(char &ID) : FunctionPass(ID) {}
+
+ /// runOnMachineFunction - This method must be overloaded to perform the
+ /// desired machine code transformation or analysis.
+ ///
+ virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
+
+ /// getAnalysisUsage - Subclasses that override getAnalysisUsage
+ /// must call this.
+ ///
+ /// For MachineFunctionPasses, calling AU.preservesCFG() indicates that
+ /// the pass does not modify the MachineBasicBlock CFG.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+private:
+ /// createPrinterPass - Get a machine function printer pass.
+ virtual Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const;
+
+ virtual bool runOnFunction(Function &F);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h
new file mode 100644
index 000000000000..65093d7e7ad6
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -0,0 +1,961 @@
+//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineInstr class, which is the
+// basic representation for all target dependent machine instructions used by
+// the back end.
+//
+//===----------------------------------------------------------------------===//
+
+#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/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/DebugLoc.h"
+#include <vector>
+
+namespace llvm {
+
+template <typename T> class SmallVectorImpl;
+class AliasAnalysis;
+class TargetInstrInfo;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class MachineFunction;
+class MachineMemOperand;
+
+//===----------------------------------------------------------------------===//
+/// MachineInstr - Representation of each machine instruction.
+///
+class MachineInstr : public ilist_node<MachineInstr> {
+public:
+ typedef MachineMemOperand **mmo_iterator;
+
+ /// Flags to specify different kinds of comments to output in
+ /// assembly code. These flags carry semantic information not
+ /// otherwise easily derivable from the IR text.
+ ///
+ enum CommentFlag {
+ ReloadReuse = 0x1
+ };
+
+ enum MIFlag {
+ 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)
+ };
+private:
+ const MCInstrDesc *MCID; // Instruction descriptor.
+
+ uint8_t Flags; // Various bits of additional
+ // information about machine
+ // instruction.
+
+ uint8_t AsmPrinterFlags; // Various bits of information used by
+ // the AsmPrinter to emit helpful
+ // comments. This is *not* semantic
+ // information. Do not use this for
+ // anything other than to convey comment
+ // information to AsmPrinter.
+
+ uint16_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
+
+ // Intrusive list support
+ friend struct ilist_traits<MachineInstr>;
+ friend struct ilist_traits<MachineBasicBlock>;
+ void setParent(MachineBasicBlock *P) { Parent = P; }
+
+ /// MachineInstr ctor - This constructor creates a copy of the given
+ /// 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();
+
+ // MachineInstrs are pool-allocated and owned by MachineFunction.
+ friend class MachineFunction;
+
+public:
+ const MachineBasicBlock* getParent() const { return Parent; }
+ MachineBasicBlock* getParent() { return Parent; }
+
+ /// getAsmPrinterFlags - Return the asm printer flags bitvector.
+ ///
+ uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; }
+
+ /// clearAsmPrinterFlags - clear the AsmPrinter bitvector
+ ///
+ void clearAsmPrinterFlags() { AsmPrinterFlags = 0; }
+
+ /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set.
+ ///
+ bool getAsmPrinterFlag(CommentFlag Flag) const {
+ return AsmPrinterFlags & Flag;
+ }
+
+ /// setAsmPrinterFlag - Set a flag for the AsmPrinter.
+ ///
+ void setAsmPrinterFlag(CommentFlag Flag) {
+ AsmPrinterFlags |= (uint8_t)Flag;
+ }
+
+ /// clearAsmPrinterFlag - clear specific AsmPrinter flags
+ ///
+ void clearAsmPrinterFlag(CommentFlag Flag) {
+ AsmPrinterFlags &= ~Flag;
+ }
+
+ /// getFlags - Return the MI flags bitvector.
+ uint8_t getFlags() const {
+ return Flags;
+ }
+
+ /// getFlag - Return whether an MI flag is set.
+ bool getFlag(MIFlag Flag) const {
+ return Flags & Flag;
+ }
+
+ /// setFlag - Set a MI flag.
+ void setFlag(MIFlag Flag) {
+ Flags |= (uint8_t)Flag;
+ }
+
+ void setFlags(unsigned flags) {
+ Flags = flags;
+ }
+
+ /// clearFlag - Clear a MI flag.
+ void clearFlag(MIFlag Flag) {
+ Flags &= ~((uint8_t)Flag);
+ }
+
+ /// isInsideBundle - Return true if MI is in a bundle (but not the first MI
+ /// in a bundle).
+ ///
+ /// A bundle looks like this before it's finalized:
+ /// ----------------
+ /// | MI |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// In this case, the first MI starts a bundle but is not inside a bundle, the
+ /// next 2 MIs are considered "inside" the bundle.
+ ///
+ /// After a bundle is finalized, it looks like this:
+ /// ----------------
+ /// | Bundle |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// |
+ /// ----------------
+ /// | MI * |
+ /// ----------------
+ /// 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);
+ }
+
+ /// 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;
+
+ /// getDebugLoc - Returns the debug location id of this MachineInstr.
+ ///
+ DebugLoc getDebugLoc() const { return debugLoc; }
+
+ /// emitError - Emit an error referring to the source location of this
+ /// instruction. This should only be used for inline assembly that is somehow
+ /// impossible to compile. Other errors should have been handled much
+ /// earlier.
+ ///
+ /// If this method returns, the caller should try to recover from the error.
+ ///
+ void emitError(StringRef Msg) const;
+
+ /// getDesc - Returns the target instruction descriptor of this
+ /// MachineInstr.
+ const MCInstrDesc &getDesc() const { return *MCID; }
+
+ /// getOpcode - Returns the opcode of this MachineInstr.
+ ///
+ int getOpcode() const { return MCID->Opcode; }
+
+ /// Access to explicit operands of the instruction.
+ ///
+ unsigned getNumOperands() const { return (unsigned)Operands.size(); }
+
+ const MachineOperand& getOperand(unsigned i) const {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Operands[i];
+ }
+ MachineOperand& getOperand(unsigned i) {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Operands[i];
+ }
+
+ /// getNumExplicitOperands - Returns the number of non-implicit operands.
+ ///
+ 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;
+
+ mop_iterator operands_begin() { return Operands.begin(); }
+ mop_iterator operands_end() { return Operands.end(); }
+
+ const_mop_iterator operands_begin() const { return Operands.begin(); }
+ const_mop_iterator operands_end() const { return Operands.end(); }
+
+ /// Access to memory operands of the instruction
+ mmo_iterator memoperands_begin() const { return MemRefs; }
+ mmo_iterator memoperands_end() const { return MemRefs + NumMemRefs; }
+ bool memoperands_empty() const { return NumMemRefs == 0; }
+
+ /// hasOneMemOperand - Return true if this instruction has exactly one
+ /// MachineMemOperand.
+ bool hasOneMemOperand() const {
+ return NumMemRefs == 1;
+ }
+
+ /// API for querying MachineInstr properties. They are the same as MCInstrDesc
+ /// queries but they are bundle aware.
+
+ enum QueryType {
+ IgnoreBundle, // Ignore bundles
+ AnyInBundle, // Return true if any instruction in bundle has property
+ AllInBundle // Return true if all instructions in bundle have property
+ };
+
+ /// hasProperty - Return true if the instruction (or in the case of a bundle,
+ /// the instructions inside the bundle) has the specified property.
+ /// The first argument is the property being queried.
+ /// The second argument indicates whether the query should look inside
+ /// instruction bundles.
+ bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const {
+ // Inline the fast path.
+ if (Type == IgnoreBundle || !isBundle())
+ return getDesc().getFlags() & (1 << MCFlag);
+
+ // If we have a bundle, take the slow path.
+ return hasPropertyInBundle(1 << MCFlag, Type);
+ }
+
+ /// isVariadic - 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).
+ bool isVariadic(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::Variadic, Type);
+ }
+
+ /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
+ /// ARM instructions which can set condition code if 's' bit is set.
+ bool hasOptionalDef(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::HasOptionalDef, Type);
+ }
+
+ /// isPseudo - Return true if this is a pseudo instruction that doesn't
+ /// correspond to a real machine instruction.
+ ///
+ bool isPseudo(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::Pseudo, Type);
+ }
+
+ bool isReturn(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Return, Type);
+ }
+
+ bool isCall(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Call, Type);
+ }
+
+ /// isBarrier - 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(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Barrier, Type);
+ }
+
+ /// isTerminator - Returns true if this instruction part of the terminator for
+ /// a basic block. Typically this is things like return and branch
+ /// instructions.
+ ///
+ /// Various passes use this to insert code into the bottom of a basic block,
+ /// but before control flow occurs.
+ bool isTerminator(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Terminator, Type);
+ }
+
+ /// isBranch - 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.
+ bool isBranch(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::Branch, Type);
+ }
+
+ /// isIndirectBranch - Return true if this is an indirect branch, such as a
+ /// branch through a register.
+ bool isIndirectBranch(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::IndirectBranch, Type);
+ }
+
+ /// isConditionalBranch - 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.
+ bool isConditionalBranch(QueryType Type = AnyInBundle) const {
+ return isBranch(Type) & !isBarrier(Type) & !isIndirectBranch(Type);
+ }
+
+ /// isUnconditionalBranch - 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.
+ bool isUnconditionalBranch(QueryType Type = AnyInBundle) const {
+ return isBranch(Type) & isBarrier(Type) & !isIndirectBranch(Type);
+ }
+
+ // 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
+ /// control and modify the predicate in this instruction.
+ bool isPredicable(QueryType Type = AllInBundle) const {
+ // If it's a bundle than all bundled instructions must be predicable for this
+ // to return true.
+ return hasProperty(MCID::Predicable, Type);
+ }
+
+ /// isCompare - Return true if this instruction is a comparison.
+ bool isCompare(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::Compare, Type);
+ }
+
+ /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::MoveImm, Type);
+ }
+
+ /// isBitcast - Return true if this instruction is a bitcast instruction.
+ ///
+ bool isBitcast(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::Bitcast, Type);
+ }
+
+ /// isNotDuplicable - 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(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::NotDuplicable, Type);
+ }
+
+ /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+ /// which must be filled by the code generator.
+ bool hasDelaySlot(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::DelaySlot, Type);
+ }
+
+ /// canFoldAsLoad - Return true for instructions that can be folded as
+ /// memory operands in other instructions. The most common use for this
+ /// is instructions that are simple loads from memory that don't modify
+ /// the loaded value in any way, but it can also be used for instructions
+ /// that can be expressed as constant-pool loads, such as V_SETALLONES
+ /// on x86, to allow them to be folded when it is beneficial.
+ /// This should only be set on instructions that return a value in their
+ /// only virtual register definition.
+ bool canFoldAsLoad(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::FoldableAsLoad, Type);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Side Effect Analysis
+ //===--------------------------------------------------------------------===//
+
+ /// mayLoad - 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(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::MayLoad, Type);
+ }
+
+
+ /// mayStore - 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.
+ bool mayStore(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::MayStore, Type);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Flags that indicate whether an instruction can be modified by a method.
+ //===--------------------------------------------------------------------===//
+
+ /// isCommutable - Return true if this may be a 2- or 3-address
+ /// instruction (of the form "X = op Y, Z, ..."), which produces the same
+ /// result if Y and Z are exchanged. If this flag is set, then the
+ /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+ /// instruction.
+ ///
+ /// Note that this flag may be set on instructions that are only commutable
+ /// sometimes. In these cases, the call to commuteInstruction will fail.
+ /// Also note that some instructions require non-trivial modification to
+ /// commute them.
+ bool isCommutable(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::Commutable, Type);
+ }
+
+ /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
+ /// which can be changed into a 3-address instruction if needed. Doing this
+ /// transformation can be profitable in the register allocator, because it
+ /// means that the instruction can use a 2-address form if possible, but
+ /// degrade into a less efficient form if the source and dest register cannot
+ /// be assigned to the same register. For example, this allows the x86
+ /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
+ /// is the same speed as the shift but has bigger code size.
+ ///
+ /// If this returns true, then the target must implement the
+ /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+ /// is allowed to fail if the transformation isn't valid for this specific
+ /// instruction (e.g. shl reg, 4 on x86).
+ ///
+ bool isConvertibleTo3Addr(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::ConvertibleTo3Addr, Type);
+ }
+
+ /// usesCustomInsertionHook - Return true if this instruction requires
+ /// custom insertion support when the DAG scheduler is inserting it into a
+ /// machine basic block. If this is true for the instruction, it basically
+ /// means that it is a pseudo instruction used at SelectionDAG time that is
+ /// expanded out into magic code by the target when MachineInstrs are formed.
+ ///
+ /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+ /// is used to insert this into the MachineBasicBlock.
+ bool usesCustomInsertionHook(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::UsesCustomInserter, Type);
+ }
+
+ /// hasPostISelHook - Return true if this instruction requires *adjustment*
+ /// after instruction selection by calling a target hook. For example, this
+ /// can be used to fill in ARM 's' optional operand depending on whether
+ /// the conditional flag register is used.
+ bool hasPostISelHook(QueryType Type = IgnoreBundle) const {
+ return hasProperty(MCID::HasPostISelHook, Type);
+ }
+
+ /// isRematerializable - Returns true if this instruction is a candidate for
+ /// remat. This flag is deprecated, please don't use it anymore. If this
+ /// flag is set, the isReallyTriviallyReMaterializable() method is called to
+ /// verify the instruction is really rematable.
+ bool isRematerializable(QueryType Type = AllInBundle) const {
+ // It's only possible to re-mat a bundle if all bundled instructions are
+ // re-materializable.
+ return hasProperty(MCID::Rematerializable, Type);
+ }
+
+ /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+ /// less) than a move instruction. This is useful during certain types of
+ /// optimizations (e.g., remat during two-address conversion or machine licm)
+ /// where we would like to remat or hoist the instruction, but not if it costs
+ /// more than moving the instruction into the appropriate register. Note, we
+ /// are not marking copies from and to the same register class with this flag.
+ bool isAsCheapAsAMove(QueryType Type = AllInBundle) const {
+ // Only returns true for a bundle if all bundled instructions are cheap.
+ // FIXME: This probably requires a target hook.
+ return hasProperty(MCID::CheapAsAMove, Type);
+ }
+
+ /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::STRD's two source registers must be an
+ /// even / odd pair, ARM::STM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for sources of instructions with this flag.
+ bool hasExtraSrcRegAllocReq(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::ExtraSrcRegAllocReq, Type);
+ }
+
+ /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+ /// even / odd pair, ARM::LDM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for definitions of instructions with this flag.
+ bool hasExtraDefRegAllocReq(QueryType Type = AnyInBundle) const {
+ return hasProperty(MCID::ExtraDefRegAllocReq, Type);
+ }
+
+
+ enum MICheckType {
+ CheckDefs, // Check all operands for equality
+ CheckKillDead, // Check all operands including kill / dead markers
+ IgnoreDefs, // Ignore all definitions
+ IgnoreVRegDefs // Ignore virtual register definitions
+ };
+
+ /// isIdenticalTo - Return true if this instruction is identical to (same
+ /// opcode and same operands as) the specified instruction.
+ bool isIdenticalTo(const MachineInstr *Other,
+ MICheckType Check = CheckDefs) const;
+
+ /// removeFromParent - This method unlinks 'this' from the containing basic
+ /// block, and returns it, but does not delete it.
+ MachineInstr *removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing basic
+ /// block and deletes it.
+ void eraseFromParent();
+
+ /// isLabel - Returns true if the MachineInstr represents a label.
+ ///
+ bool isLabel() const {
+ return getOpcode() == TargetOpcode::PROLOG_LABEL ||
+ getOpcode() == TargetOpcode::EH_LABEL ||
+ getOpcode() == TargetOpcode::GC_LABEL;
+ }
+
+ bool isPrologLabel() const {
+ return getOpcode() == TargetOpcode::PROLOG_LABEL;
+ }
+ bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
+ bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
+ bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
+
+ bool isPHI() const { return getOpcode() == TargetOpcode::PHI; }
+ bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
+ bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
+ bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+ bool isStackAligningInlineAsm() const;
+ bool isInsertSubreg() const {
+ return getOpcode() == TargetOpcode::INSERT_SUBREG;
+ }
+ bool isSubregToReg() const {
+ return getOpcode() == TargetOpcode::SUBREG_TO_REG;
+ }
+ bool isRegSequence() const {
+ return getOpcode() == TargetOpcode::REG_SEQUENCE;
+ }
+ bool isBundle() const {
+ return getOpcode() == TargetOpcode::BUNDLE;
+ }
+ bool isCopy() const {
+ return getOpcode() == TargetOpcode::COPY;
+ }
+ bool isFullCopy() const {
+ return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
+ }
+
+ /// isCopyLike - Return true if the instruction behaves like a copy.
+ /// This does not include native copy instructions.
+ bool isCopyLike() const {
+ return isCopy() || isSubregToReg();
+ }
+
+ /// isIdentityCopy - Return true is the instruction is an identity copy.
+ bool isIdentityCopy() const {
+ return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() &&
+ getOperand(0).getSubReg() == getOperand(1).getSubReg();
+ }
+
+ /// getBundleSize - Return the number of instructions inside the MI bundle.
+ unsigned getBundleSize() const;
+
+ /// readsRegister - Return true if the MachineInstr reads the specified
+ /// register. If TargetRegisterInfo is passed, then it also checks if there
+ /// is a read of a super-register.
+ /// This does not count partial redefines of virtual registers as reads:
+ /// %reg1024:6 = OP.
+ bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const {
+ return findRegisterUseOperandIdx(Reg, false, TRI) != -1;
+ }
+
+ /// readsVirtualRegister - Return true if the MachineInstr reads the specified
+ /// virtual register. Take into account that a partial define is a
+ /// read-modify-write operation.
+ bool readsVirtualRegister(unsigned Reg) const {
+ return readsWritesVirtualRegister(Reg).first;
+ }
+
+ /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
+ /// indicating if this instruction reads or writes Reg. This also considers
+ /// partial defines.
+ /// If Ops is not null, all operand indices for Reg are added.
+ std::pair<bool,bool> readsWritesVirtualRegister(unsigned Reg,
+ SmallVectorImpl<unsigned> *Ops = 0) const;
+
+ /// killsRegister - Return true if the MachineInstr kills the specified
+ /// register. If TargetRegisterInfo is passed, then it also checks if there is
+ /// a kill of a super-register.
+ bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI = NULL) const {
+ return findRegisterUseOperandIdx(Reg, true, TRI) != -1;
+ }
+
+ /// definesRegister - Return true if the MachineInstr fully defines the
+ /// specified register. If TargetRegisterInfo is passed, then it also checks
+ /// if there is a def of a super-register.
+ /// NOTE: It's ignoring subreg indices on virtual registers.
+ bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const {
+ return findRegisterDefOperandIdx(Reg, false, false, TRI) != -1;
+ }
+
+ /// modifiesRegister - Return true if the MachineInstr modifies (fully define
+ /// or partially define) the specified register.
+ /// NOTE: It's ignoring subreg indices on virtual registers.
+ bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const {
+ return findRegisterDefOperandIdx(Reg, false, true, TRI) != -1;
+ }
+
+ /// registerDefIsDead - Returns true if the register is dead in this machine
+ /// instruction. If TargetRegisterInfo is passed, then it also checks
+ /// if there is a dead def of a super-register.
+ bool registerDefIsDead(unsigned Reg,
+ const TargetRegisterInfo *TRI = NULL) const {
+ return findRegisterDefOperandIdx(Reg, true, false, TRI) != -1;
+ }
+
+ /// findRegisterUseOperandIdx() - Returns the operand index that is a use of
+ /// the specific register or -1 if it is not found. It further tightens
+ /// the search criteria to a use that kills the register if isKill is true.
+ int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false,
+ const TargetRegisterInfo *TRI = NULL) const;
+
+ /// findRegisterUseOperand - Wrapper for findRegisterUseOperandIdx, it returns
+ /// a pointer to the MachineOperand rather than an index.
+ MachineOperand *findRegisterUseOperand(unsigned Reg, bool isKill = false,
+ const TargetRegisterInfo *TRI = NULL) {
+ int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI);
+ return (Idx == -1) ? NULL : &getOperand(Idx);
+ }
+
+ /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
+ /// the specified register or -1 if it is not found. If isDead is true, defs
+ /// that are not dead are skipped. If Overlap is true, then it also looks for
+ /// defs that merely overlap the specified register. If TargetRegisterInfo is
+ /// non-null, then it also checks if there is a def of a super-register.
+ /// This may also return a register mask operand when Overlap is true.
+ int findRegisterDefOperandIdx(unsigned Reg,
+ bool isDead = false, bool Overlap = false,
+ const TargetRegisterInfo *TRI = NULL) const;
+
+ /// findRegisterDefOperand - Wrapper for findRegisterDefOperandIdx, it returns
+ /// a pointer to the MachineOperand rather than an index.
+ MachineOperand *findRegisterDefOperand(unsigned Reg, bool isDead = false,
+ const TargetRegisterInfo *TRI = NULL) {
+ int Idx = findRegisterDefOperandIdx(Reg, isDead, false, TRI);
+ return (Idx == -1) ? NULL : &getOperand(Idx);
+ }
+
+ /// findFirstPredOperandIdx() - 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;
+
+ /// findInlineAsmFlagIdx() - Find the index of the flag word operand that
+ /// corresponds to operand OpIdx on an inline asm instruction. Returns -1 if
+ /// getOperand(OpIdx) does not belong to an inline asm operand group.
+ ///
+ /// If GroupNo is not NULL, it will receive the number of the operand group
+ /// containing OpIdx.
+ ///
+ /// The flag operand is an immediate that can be decoded with methods like
+ /// InlineAsm::hasRegClassConstraint().
+ ///
+ int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const;
+
+ /// getRegClassConstraint - Compute the static register class constraint for
+ /// operand OpIdx. For normal instructions, this is derived from the
+ /// MCInstrDesc. For inline assembly it is derived from the flag words.
+ ///
+ /// Returns NULL if the static register classs constraint cannot be
+ /// determined.
+ ///
+ const TargetRegisterClass*
+ getRegClassConstraint(unsigned OpIdx,
+ const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI) const;
+
+ /// isRegTiedToUseOperand - Given the index of a register def operand,
+ /// check if the register def is tied to a source operand, due to either
+ /// two-address elimination or inline assembly constraints. Returns the
+ /// first tied use operand index by reference if UseOpIdx is not null.
+ bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx = 0) const;
+
+ /// isRegTiedToDefOperand - Return true if the use operand of the specified
+ /// index is tied to an def operand. It also returns the def operand index by
+ /// reference if DefOpIdx is not null.
+ bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx = 0) const;
+
+ /// clearKillInfo - Clears kill flags on all operands.
+ ///
+ 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,
+ const TargetRegisterInfo &RegInfo);
+
+ /// addRegisterKilled - We have determined MI kills a register. Look for the
+ /// operand that uses it and mark it as IsKill. If AddIfNotFound is true,
+ /// add a implicit operand if it's not found. Returns true if the operand
+ /// exists / is added.
+ bool addRegisterKilled(unsigned IncomingReg,
+ const TargetRegisterInfo *RegInfo,
+ bool AddIfNotFound = false);
+
+ /// clearRegisterKills - Clear all kill flags affecting Reg. If RegInfo is
+ /// provided, this includes super-register kills.
+ void clearRegisterKills(unsigned Reg, const TargetRegisterInfo *RegInfo);
+
+ /// addRegisterDead - We have determined MI defined a register without a use.
+ /// Look for the operand that defines it and mark it as IsDead. If
+ /// AddIfNotFound is true, add a implicit operand if it's not found. Returns
+ /// true if the operand exists / is added.
+ bool addRegisterDead(unsigned IncomingReg, const TargetRegisterInfo *RegInfo,
+ bool AddIfNotFound = false);
+
+ /// addRegisterDefined - We have determined MI defines a register. Make sure
+ /// there is an operand defining Reg.
+ void addRegisterDefined(unsigned IncomingReg,
+ const TargetRegisterInfo *RegInfo = 0);
+
+ /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as
+ /// dead except those in the UsedRegs list.
+ ///
+ /// On instructions with register mask operands, also add implicit-def
+ /// operands for all registers in UsedRegs.
+ void setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,
+ const TargetRegisterInfo &TRI);
+
+ /// isSafeToMove - Return true if it is safe to move this instruction. If
+ /// SawStore is set to true, it means that there is a store (or call) between
+ /// the instruction's location and its intended destination.
+ bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA,
+ bool &SawStore) const;
+
+ /// isSafeToReMat - Return true if it's safe to rematerialize the specified
+ /// instruction which defined the specified register instead of copying it.
+ bool isSafeToReMat(const TargetInstrInfo *TII, AliasAnalysis *AA,
+ unsigned DstReg) const;
+
+ /// hasVolatileMemoryRef - Return true if this instruction may have a
+ /// volatile memory reference, or if the information describing the
+ /// memory reference is not available. Return false if it is known to
+ /// have no volatile memory references.
+ bool hasVolatileMemoryRef() const;
+
+ /// isInvariantLoad - Return true if this instruction is loading from a
+ /// location whose value is invariant across the function. For example,
+ /// loading a value from the constant pool or from the argument area of
+ /// a function if it does not change. This should only return true of *all*
+ /// loads the instruction does are invariant (if it does multiple loads).
+ bool isInvariantLoad(AliasAnalysis *AA) const;
+
+ /// isConstantValuePHI - If the specified instruction is a PHI that always
+ /// merges together the same virtual register, return the register, otherwise
+ /// return 0.
+ unsigned isConstantValuePHI() const;
+
+ /// hasUnmodeledSideEffects - Return true if this instruction has side
+ /// effects that are not modeled by mayLoad / mayStore, etc.
+ /// For all instructions, the property is encoded in MCInstrDesc::Flags
+ /// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is
+ /// INLINEASM instruction, in which case the side effect property is encoded
+ /// in one of its operands (see InlineAsm::Extra_HasSideEffect).
+ ///
+ bool hasUnmodeledSideEffects() const;
+
+ /// allDefsAreDead - Return true if all the defs of this instruction are dead.
+ ///
+ bool allDefsAreDead() const;
+
+ /// copyImplicitOps - Copy implicit register operands from specified
+ /// instruction to this instruction.
+ void copyImplicitOps(const MachineInstr *MI);
+
+ //
+ // Debugging support
+ //
+ void print(raw_ostream &OS, const TargetMachine *TM = 0) const;
+ void dump() const;
+
+ //===--------------------------------------------------------------------===//
+ // 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
+ /// (before the first implicit operand).
+ void addOperand(const MachineOperand &Op);
+
+ /// setDesc - Replace the instruction descriptor (thus opcode) of
+ /// the current instruction with a new one.
+ ///
+ void setDesc(const MCInstrDesc &tid) { MCID = &tid; }
+
+ /// setDebugLoc - Replace current source information with new such.
+ /// Avoid using this, the constructor argument is preferable.
+ ///
+ void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
+ /// RemoveOperand - Erase an operand from an instruction, leaving it with one
+ /// fewer operand than it started with.
+ ///
+ void RemoveOperand(unsigned i);
+
+ /// addMemOperand - Add a MachineMemOperand to the machine instruction.
+ /// This function should be used only occasionally. The setMemRefs function
+ /// is the primary method for setting up a MachineInstr's MemRefs list.
+ void addMemOperand(MachineFunction &MF, MachineMemOperand *MO);
+
+ /// setMemRefs - Assign this MachineInstr's memory reference descriptor
+ /// list. This does not transfer ownership.
+ void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) {
+ MemRefs = NewMemRefs;
+ NumMemRefs = NewMemRefsEnd - NewMemRefs;
+ }
+
+private:
+ /// getRegInfo - If this instruction is embedded into a MachineFunction,
+ /// return the MachineRegisterInfo object for the current function, otherwise
+ /// return null.
+ MachineRegisterInfo *getRegInfo();
+
+ /// addImplicitDefUseOperands - Add all implicit def and use operands to
+ /// this instruction.
+ void addImplicitDefUseOperands();
+
+ /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
+ /// this instruction from their respective use lists. This requires that the
+ /// operands already be on their use lists.
+ void RemoveRegOperandsFromUseLists();
+
+ /// AddRegOperandsToUseLists - Add all of the register operands in
+ /// this instruction from their respective use lists. This requires that the
+ /// operands not be on their use lists yet.
+ void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo);
+
+ /// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a
+ /// bundle.
+ bool hasPropertyInBundle(unsigned Mask, QueryType Type) const;
+};
+
+/// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare
+/// MachineInstr* by *value* of the instruction rather than by pointer value.
+/// The hashing and equality testing functions ignore definitions so this is
+/// useful for CSE, etc.
+struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> {
+ static inline MachineInstr *getEmptyKey() {
+ return 0;
+ }
+
+ static inline MachineInstr *getTombstoneKey() {
+ return reinterpret_cast<MachineInstr*>(-1);
+ }
+
+ static unsigned getHashValue(const MachineInstr* const &MI);
+
+ static bool isEqual(const MachineInstr* const &LHS,
+ const MachineInstr* const &RHS) {
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
+ LHS == getEmptyKey() || LHS == getTombstoneKey())
+ return LHS == RHS;
+ return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) {
+ MI.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
new file mode 100644
index 000000000000..99849a64c56a
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -0,0 +1,316 @@
+//===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- 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 a function named BuildMI, which is useful for dramatically
+// simplifying how MachineInstr's are created. It allows use of code like this:
+//
+// M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class MCInstrDesc;
+class MDNode;
+
+namespace RegState {
+ enum {
+ Define = 0x2,
+ Implicit = 0x4,
+ Kill = 0x8,
+ Dead = 0x10,
+ Undef = 0x20,
+ EarlyClobber = 0x40,
+ Debug = 0x80,
+ DefineNoRead = Define | Undef,
+ ImplicitDefine = Implicit | Define,
+ ImplicitKill = Implicit | Kill
+ };
+}
+
+class MachineInstrBuilder {
+ MachineInstr *MI;
+public:
+ MachineInstrBuilder() : MI(0) {}
+ explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
+
+ /// Allow automatic conversion to the machine instruction we are working on.
+ ///
+ operator MachineInstr*() const { return MI; }
+ MachineInstr *operator->() const { return MI; }
+ operator MachineBasicBlock::iterator() const { return MI; }
+
+ /// addReg - Add a new virtual register operand...
+ ///
+ const
+ MachineInstrBuilder &addReg(unsigned RegNo, unsigned flags = 0,
+ 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));
+ return *this;
+ }
+
+ /// addImm - Add a new immediate operand.
+ ///
+ const MachineInstrBuilder &addImm(int64_t Val) const {
+ MI->addOperand(MachineOperand::CreateImm(Val));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
+ MI->addOperand(MachineOperand::CreateCImm(Val));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
+ MI->addOperand(MachineOperand::CreateFPImm(Val));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addFrameIndex(int Idx) const {
+ MI->addOperand(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));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(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));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addExternalSymbol(const char *FnName,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
+ MI->addOperand(MachineOperand::CreateRegMask(Mask));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
+ MI->addMemOperand(*MI->getParent()->getParent(), MMO);
+ return *this;
+ }
+
+ const MachineInstrBuilder &setMemRefs(MachineInstr::mmo_iterator b,
+ MachineInstr::mmo_iterator e) const {
+ MI->setMemRefs(b, e);
+ return *this;
+ }
+
+
+ const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
+ MI->addOperand(MO);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
+ MI->addOperand(MachineOperand::CreateMetadata(MD));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
+ MI->addOperand(MachineOperand::CreateMCSymbol(Sym));
+ return *this;
+ }
+
+ const MachineInstrBuilder &setMIFlags(unsigned Flags) const {
+ MI->setFlags(Flags);
+ return *this;
+ }
+
+ const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const {
+ MI->setFlag(Flag);
+ return *this;
+ }
+
+ // Add a displacement from an existing MachineOperand with an added offset.
+ const MachineInstrBuilder &addDisp(const MachineOperand &Disp,
+ int64_t off) 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);
+ }
+ }
+};
+
+/// BuildMI - Builder interface. Specify how to create the initial instruction
+/// itself.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
+}
+
+/// BuildMI - This version of the builder sets up the first operand as a
+/// destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
+ .addReg(DestReg, RegState::Define);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// sets up the first operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::instr_iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineInstr *I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ if (I->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID, DestReg);
+ }
+
+ MachineBasicBlock::iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID, DestReg);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// does NOT take a destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::instr_iterator I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineInstr *I,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ if (I->isInsideBundle()) {
+ MachineBasicBlock::instr_iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID);
+ }
+
+ MachineBasicBlock::iterator MII = I;
+ return BuildMI(BB, MII, DL, MCID);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and does NOT take a
+/// destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ DebugLoc DL,
+ const MCInstrDesc &MCID) {
+ return BuildMI(*BB, BB->end(), DL, MCID);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and sets up the first
+/// operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ DebugLoc DL,
+ const MCInstrDesc &MCID,
+ unsigned DestReg) {
+ return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
+}
+
+inline unsigned getDefRegState(bool B) {
+ return B ? RegState::Define : 0;
+}
+inline unsigned getImplRegState(bool B) {
+ return B ? RegState::Implicit : 0;
+}
+inline unsigned getKillRegState(bool B) {
+ return B ? RegState::Kill : 0;
+}
+inline unsigned getDeadRegState(bool B) {
+ return B ? RegState::Dead : 0;
+}
+inline unsigned getUndefRegState(bool B) {
+ return B ? RegState::Undef : 0;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h
new file mode 100644
index 000000000000..0fb496982276
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineInstrBundle.h
@@ -0,0 +1,203 @@
+//===-- CodeGen/MachineInstBundle.h - MI bundle utilities -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provide utility functions to manipulate machine instruction
+// bundles.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
+#define LLVM_CODEGEN_MACHINEINSTRBUNDLE_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+namespace llvm {
+
+/// finalizeBundle - Finalize a machine instruction bundle which includes
+/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
+/// This routine adds a BUNDLE instruction to represent the bundle, it adds
+/// IsInternalRead markers to MachineOperands which are defined inside the
+/// bundle, and it copies externally visible defs and uses to the BUNDLE
+/// instruction.
+void finalizeBundle(MachineBasicBlock &MBB,
+ MachineBasicBlock::instr_iterator FirstMI,
+ MachineBasicBlock::instr_iterator LastMI);
+
+/// finalizeBundle - Same functionality as the previous finalizeBundle except
+/// the last instruction in the bundle is not provided as an input. This is
+/// used in cases where bundles are pre-determined by marking instructions
+/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
+/// points to the end of the bundle.
+MachineBasicBlock::instr_iterator finalizeBundle(MachineBasicBlock &MBB,
+ MachineBasicBlock::instr_iterator FirstMI);
+
+/// finalizeBundles - Finalize instruction bundles in the specified
+/// MachineFunction. Return true if any bundles are finalized.
+bool finalizeBundles(MachineFunction &MF);
+
+/// getBundleStart - Returns the first instruction in the bundle containing MI.
+///
+static inline MachineInstr *getBundleStart(MachineInstr *MI) {
+ MachineBasicBlock::instr_iterator I = MI;
+ while (I->isInsideBundle())
+ --I;
+ return I;
+}
+
+static inline const MachineInstr *getBundleStart(const MachineInstr *MI) {
+ MachineBasicBlock::const_instr_iterator I = MI;
+ while (I->isInsideBundle())
+ --I;
+ return I;
+}
+
+//===----------------------------------------------------------------------===//
+// MachineOperand iterator
+//
+
+/// MachineOperandIteratorBase - Iterator that can visit all operands on a
+/// MachineInstr, or all operands on a bundle of MachineInstrs. This class is
+/// not intended to be used directly, use one of the sub-classes instead.
+///
+/// Intended use:
+///
+/// for (MIBundleOperands MIO(MI); MIO.isValid(); ++MIO) {
+/// if (!MIO->isReg())
+/// continue;
+/// ...
+/// }
+///
+class MachineOperandIteratorBase {
+ MachineBasicBlock::instr_iterator InstrI, InstrE;
+ MachineInstr::mop_iterator OpI, OpE;
+
+ // If the operands on InstrI are exhausted, advance InstrI to the next
+ // bundled instruction with operands.
+ void advance() {
+ while (OpI == OpE) {
+ // Don't advance off the basic block, or into a new bundle.
+ if (++InstrI == InstrE || !InstrI->isInsideBundle())
+ break;
+ OpI = InstrI->operands_begin();
+ OpE = InstrI->operands_end();
+ }
+ }
+
+protected:
+ /// MachineOperandIteratorBase - Create an iterator that visits all operands
+ /// on MI, or all operands on every instruction in the bundle containing MI.
+ ///
+ /// @param MI The instruction to examine.
+ /// @param WholeBundle When true, visit all operands on the entire bundle.
+ ///
+ explicit MachineOperandIteratorBase(MachineInstr *MI, bool WholeBundle) {
+ if (WholeBundle) {
+ InstrI = getBundleStart(MI);
+ InstrE = MI->getParent()->instr_end();
+ } else {
+ InstrI = InstrE = MI;
+ ++InstrE;
+ }
+ OpI = InstrI->operands_begin();
+ OpE = InstrI->operands_end();
+ if (WholeBundle)
+ advance();
+ }
+
+ MachineOperand &deref() const { return *OpI; }
+
+public:
+ /// isValid - Returns true until all the operands have been visited.
+ bool isValid() const { return OpI != OpE; }
+
+ /// Preincrement. Move to the next operand.
+ void operator++() {
+ assert(isValid() && "Cannot advance MIOperands beyond the last operand");
+ ++OpI;
+ advance();
+ }
+
+ /// getOperandNo - Returns the number of the current operand relative to its
+ /// instruction.
+ ///
+ unsigned getOperandNo() const {
+ return OpI - InstrI->operands_begin();
+ }
+
+ /// RegInfo - Information about a virtual register used by a set of operands.
+ ///
+ struct RegInfo {
+ /// Reads - One of the operands read the virtual register. This does not
+ /// include <undef> or <internal> use operands, see MO::readsReg().
+ bool Reads;
+
+ /// Writes - One of the operands writes the virtual register.
+ bool Writes;
+
+ /// Tied - Uses and defs must use the same register. This can be because of
+ /// a two-address constraint, or there may be a partial redefinition of a
+ /// sub-register.
+ bool Tied;
+ };
+
+ /// 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.
+ ///
+ /// @param Reg The virtual register to analyze.
+ /// @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,
+ SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops = 0);
+};
+
+/// MIOperands - Iterate over operands of a single instruction.
+///
+class MIOperands : public MachineOperandIteratorBase {
+public:
+ MIOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, false) {}
+ MachineOperand &operator* () const { return deref(); }
+ MachineOperand *operator->() const { return &deref(); }
+};
+
+/// ConstMIOperands - Iterate over operands of a single const instruction.
+///
+class ConstMIOperands : public MachineOperandIteratorBase {
+public:
+ ConstMIOperands(const MachineInstr *MI)
+ : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), false) {}
+ const MachineOperand &operator* () const { return deref(); }
+ const MachineOperand *operator->() const { return &deref(); }
+};
+
+/// MIBundleOperands - Iterate over all operands in a bundle of machine
+/// instructions.
+///
+class MIBundleOperands : public MachineOperandIteratorBase {
+public:
+ MIBundleOperands(MachineInstr *MI) : MachineOperandIteratorBase(MI, true) {}
+ MachineOperand &operator* () const { return deref(); }
+ MachineOperand *operator->() const { return &deref(); }
+};
+
+/// ConstMIBundleOperands - Iterate over all operands in a const bundle of
+/// machine instructions.
+///
+class ConstMIBundleOperands : public MachineOperandIteratorBase {
+public:
+ ConstMIBundleOperands(const MachineInstr *MI)
+ : MachineOperandIteratorBase(const_cast<MachineInstr*>(MI), true) {}
+ const MachineOperand &operator* () const { return deref(); }
+ const MachineOperand *operator->() const { return &deref(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h
new file mode 100644
index 000000000000..6bd6682dd39c
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -0,0 +1,130 @@
+//===-- CodeGen/MachineJumpTableInfo.h - Abstract Jump Tables --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MachineJumpTableInfo class keeps track of jump tables referenced by
+// lowered switch instructions in the MachineFunction.
+//
+// Instructions reference the address of these jump tables through the use of
+// MO_JumpTableIndex values. When emitting assembly or machine code, these
+// virtual address references are converted to refer to the address of the
+// function jump tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+#define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class TargetData;
+class raw_ostream;
+
+/// MachineJumpTableEntry - One jump table in the jump table info.
+///
+struct MachineJumpTableEntry {
+ /// MBBs - The vector of basic blocks from which to create the jump table.
+ std::vector<MachineBasicBlock*> MBBs;
+
+ explicit MachineJumpTableEntry(const std::vector<MachineBasicBlock*> &M)
+ : MBBs(M) {}
+};
+
+class MachineJumpTableInfo {
+public:
+ /// JTEntryKind - This enum indicates how each entry of the jump table is
+ /// represented and emitted.
+ enum JTEntryKind {
+ /// EK_BlockAddress - Each entry is a plain address of block, e.g.:
+ /// .word LBB123
+ EK_BlockAddress,
+
+ /// EK_GPRel64BlockAddress - Each entry is an address of block, encoded
+ /// with a relocation as gp-relative, e.g.:
+ /// .gpdword LBB123
+ EK_GPRel64BlockAddress,
+
+ /// EK_GPRel32BlockAddress - Each entry is an address of block, encoded
+ /// with a relocation as gp-relative, e.g.:
+ /// .gprel32 LBB123
+ EK_GPRel32BlockAddress,
+
+ /// EK_LabelDifference32 - Each entry is the address of the block minus
+ /// the address of the jump table. This is used for PIC jump tables where
+ /// gprel32 is not supported. e.g.:
+ /// .word LBB123 - LJTI1_2
+ /// If the .set directive is supported, this is emitted as:
+ /// .set L4_5_set_123, LBB123 - LJTI1_2
+ /// .word L4_5_set_123
+ EK_LabelDifference32,
+
+ /// EK_Inline - Jump table entries are emitted inline at their point of
+ /// use. It is the responsibility of the target to emit the entries.
+ EK_Inline,
+
+ /// EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the
+ /// TargetLowering::LowerCustomJumpTableEntry hook.
+ EK_Custom32
+ };
+private:
+ JTEntryKind EntryKind;
+ std::vector<MachineJumpTableEntry> JumpTables;
+public:
+ explicit MachineJumpTableInfo(JTEntryKind Kind): EntryKind(Kind) {}
+
+ JTEntryKind getEntryKind() const { return EntryKind; }
+
+ /// getEntrySize - Return the size of each entry in the jump table.
+ unsigned getEntrySize(const TargetData &TD) const;
+ /// getEntryAlignment - Return the alignment of each entry in the jump table.
+ unsigned getEntryAlignment(const TargetData &TD) const;
+
+ /// createJumpTableIndex - Create a new jump table.
+ ///
+ unsigned createJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
+
+ /// isEmpty - Return true if there are no jump tables.
+ ///
+ bool isEmpty() const { return JumpTables.empty(); }
+
+ const std::vector<MachineJumpTableEntry> &getJumpTables() const {
+ return JumpTables;
+ }
+
+ /// RemoveJumpTable - Mark the specific index as being dead. This will
+ /// prevent it from being emitted.
+ void RemoveJumpTable(unsigned Idx) {
+ JumpTables[Idx].MBBs.clear();
+ }
+
+ /// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
+ /// the jump tables to branch to New instead.
+ bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+ /// ReplaceMBBInJumpTable - If Old is a target of the jump tables, update
+ /// the jump table to branch to New instead.
+ bool ReplaceMBBInJumpTable(unsigned Idx, MachineBasicBlock *Old,
+ MachineBasicBlock *New);
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// jump tables. Implemented in MachineFunction.cpp
+ ///
+ void print(raw_ostream &OS) const;
+
+ /// dump - Call to stderr.
+ ///
+ void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h
new file mode 100644
index 000000000000..6dd9440500bf
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineLoopInfo.h
@@ -0,0 +1,178 @@
+//===- llvm/CodeGen/MachineLoopInfo.h - Natural Loop Calculator -*- 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 MachineLoopInfo class that is used to identify natural
+// loops and determine the loop depth of various nodes of the CFG. Note that
+// natural loops may actually be several loops that share the same header node.
+//
+// This analysis calculates the nesting structure of loops in a function. For
+// each natural loop identified, this analysis identifies natural loops
+// contained entirely within the loop and the basic blocks the make up the loop.
+//
+// It can calculate on the fly various bits of information, for example:
+//
+// * whether there is a preheader for the loop
+// * the number of back edges to the header
+// * whether or not a particular block branches out of the loop
+// * the successor blocks of the loop
+// * the loop depth
+// * the trip count
+// * etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_LOOP_INFO_H
+#define LLVM_CODEGEN_MACHINE_LOOP_INFO_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Analysis/LoopInfo.h"
+
+namespace llvm {
+
+class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
+public:
+ MachineLoop();
+
+ /// getTopBlock - Return the "top" block in the loop, which is the first
+ /// block in the linear layout, ignoring any parts of the loop not
+ /// contiguous with the part the contains the header.
+ MachineBasicBlock *getTopBlock();
+
+ /// getBottomBlock - Return the "bottom" block in the loop, which is the last
+ /// block in the linear layout, ignoring any parts of the loop not
+ /// contiguous with the part the contains the header.
+ MachineBasicBlock *getBottomBlock();
+
+ void dump() const;
+
+private:
+ friend class LoopInfoBase<MachineBasicBlock, MachineLoop>;
+ explicit MachineLoop(MachineBasicBlock *MBB)
+ : LoopBase<MachineBasicBlock, MachineLoop>(MBB) {}
+};
+
+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
+
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ MachineLoopInfo() : MachineFunctionPass(ID) {
+ initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
+ }
+
+ LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
+
+ /// iterator/begin/end - The interface to the top-level loops in the current
+ /// function.
+ ///
+ typedef LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator iterator;
+ inline iterator begin() const { return LI.begin(); }
+ inline iterator end() const { return LI.end(); }
+ bool empty() const { return LI.empty(); }
+
+ /// getLoopFor - Return the inner most loop that BB lives in. If a basic
+ /// block is in no loop (for example the entry node), null is returned.
+ ///
+ inline MachineLoop *getLoopFor(const MachineBasicBlock *BB) const {
+ return LI.getLoopFor(BB);
+ }
+
+ /// operator[] - same as getLoopFor...
+ ///
+ inline const MachineLoop *operator[](const MachineBasicBlock *BB) const {
+ return LI.getLoopFor(BB);
+ }
+
+ /// getLoopDepth - Return the loop nesting level of the specified block...
+ ///
+ inline unsigned getLoopDepth(const MachineBasicBlock *BB) const {
+ return LI.getLoopDepth(BB);
+ }
+
+ // isLoopHeader - True if the block is a loop header node
+ inline bool isLoopHeader(MachineBasicBlock *BB) const {
+ return LI.isLoopHeader(BB);
+ }
+
+ /// runOnFunction - Calculate the natural loop information.
+ ///
+ virtual bool runOnMachineFunction(MachineFunction &F);
+
+ virtual void releaseMemory() { LI.releaseMemory(); }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// removeLoop - This removes the specified top-level loop from this loop info
+ /// object. The loop is not deleted, as it will presumably be inserted into
+ /// another loop.
+ inline MachineLoop *removeLoop(iterator I) { return LI.removeLoop(I); }
+
+ /// changeLoopFor - Change the top-level loop that contains BB to the
+ /// specified loop. This should be used by transformations that restructure
+ /// the loop hierarchy tree.
+ inline void changeLoopFor(MachineBasicBlock *BB, MachineLoop *L) {
+ LI.changeLoopFor(BB, L);
+ }
+
+ /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+ /// list with the indicated loop.
+ inline void changeTopLevelLoop(MachineLoop *OldLoop, MachineLoop *NewLoop) {
+ LI.changeTopLevelLoop(OldLoop, NewLoop);
+ }
+
+ /// addTopLevelLoop - This adds the specified loop to the collection of
+ /// top-level loops.
+ inline void addTopLevelLoop(MachineLoop *New) {
+ LI.addTopLevelLoop(New);
+ }
+
+ /// removeBlock - This method completely removes BB from all data structures,
+ /// including all of the Loop objects it is nested in and our mapping from
+ /// MachineBasicBlocks to loops.
+ void removeBlock(MachineBasicBlock *BB) {
+ LI.removeBlock(BB);
+ }
+};
+
+
+// Allow clients to walk the list of nested loops...
+template <> struct GraphTraits<const MachineLoop*> {
+ typedef const MachineLoop NodeType;
+ typedef MachineLoopInfo::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const MachineLoop *L) { return L; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+};
+
+template <> struct GraphTraits<MachineLoop*> {
+ typedef MachineLoop NodeType;
+ typedef MachineLoopInfo::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(MachineLoop *L) { return L; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h b/contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h
new file mode 100644
index 000000000000..6a30e8b53c09
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineLoopRanges.h
@@ -0,0 +1,112 @@
+//===- 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/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h b/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h
new file mode 100644
index 000000000000..1ac9080b75d5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineMemOperand.h
@@ -0,0 +1,174 @@
+//==- llvm/CodeGen/MachineMemOperand.h - MachineMemOperand class -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineMemOperand class, which is a
+// description of a memory reference. It is used to help track dependencies
+// in the backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMEMOPERAND_H
+#define LLVM_CODEGEN_MACHINEMEMOPERAND_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class Value;
+class FoldingSetNodeID;
+class MDNode;
+class raw_ostream;
+
+/// MachinePointerInfo - This class contains a discriminated union of
+/// information about pointers in memory operands, relating them back to LLVM IR
+/// or to virtual locations (such as frame indices) that are exposed during
+/// codegen.
+struct MachinePointerInfo {
+ /// V - This is the IR pointer value for the access, or it is null if unknown.
+ /// If this is null, then the access is to a pointer in the default address
+ /// space.
+ const Value *V;
+
+ /// Offset - This is an offset from the base Value*.
+ int64_t Offset;
+
+ explicit MachinePointerInfo(const Value *v = 0, int64_t offset = 0)
+ : V(v), Offset(offset) {}
+
+ MachinePointerInfo getWithOffset(int64_t O) const {
+ if (V == 0) return MachinePointerInfo(0, 0);
+ return MachinePointerInfo(V, Offset+O);
+ }
+
+ /// getAddrSpace - Return the LLVM IR address space number that this pointer
+ /// points into.
+ unsigned getAddrSpace() const;
+
+ /// getConstantPool - Return a MachinePointerInfo record that refers to the
+ /// constant pool.
+ static MachinePointerInfo getConstantPool();
+
+ /// getFixedStack - Return a MachinePointerInfo record that refers to the
+ /// the specified FrameIndex.
+ static MachinePointerInfo getFixedStack(int FI, int64_t offset = 0);
+
+ /// getJumpTable - Return a MachinePointerInfo record that refers to a
+ /// jump table entry.
+ static MachinePointerInfo getJumpTable();
+
+ /// getGOT - Return a MachinePointerInfo record that refers to a
+ /// GOT entry.
+ static MachinePointerInfo getGOT();
+
+ /// getStack - stack pointer relative access.
+ static MachinePointerInfo getStack(int64_t Offset);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// MachineMemOperand - A description of a memory reference used in the backend.
+/// Instead of holding a StoreInst or LoadInst, this class holds the address
+/// Value of the reference along with a byte size and offset. This allows it
+/// to describe lowered loads and stores. Also, the special PseudoSourceValue
+/// objects can be used to represent loads and stores to memory locations
+/// that aren't explicit in the regular LLVM IR.
+///
+class MachineMemOperand {
+ MachinePointerInfo PtrInfo;
+ uint64_t Size;
+ unsigned Flags;
+ const MDNode *TBAAInfo;
+ const MDNode *Ranges;
+
+public:
+ /// Flags values. These may be or'd together.
+ enum MemOperandFlags {
+ /// The memory access reads data.
+ MOLoad = 1,
+ /// The memory access writes data.
+ MOStore = 2,
+ /// The memory access is volatile.
+ MOVolatile = 4,
+ /// The memory access is non-temporal.
+ MONonTemporal = 8,
+ /// The memory access is invariant.
+ MOInvariant = 16,
+ // This is the number of bits we need to represent flags.
+ MOMaxBits = 5
+ };
+
+ /// MachineMemOperand - Construct an MachineMemOperand object with the
+ /// specified PtrInfo, flags, size, and base alignment.
+ MachineMemOperand(MachinePointerInfo PtrInfo, unsigned flags, uint64_t s,
+ unsigned base_alignment, const MDNode *TBAAInfo = 0,
+ const MDNode *Ranges = 0);
+
+ const MachinePointerInfo &getPointerInfo() const { return PtrInfo; }
+
+ /// getValue - Return the base address of the memory access. This may either
+ /// be a normal LLVM IR Value, or one of the special values used in CodeGen.
+ /// Special values are those obtained via
+ /// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, and
+ /// other PseudoSourceValue member functions which return objects which stand
+ /// for frame/stack pointer relative references and other special references
+ /// which are not representable in the high-level IR.
+ const Value *getValue() const { return PtrInfo.V; }
+
+ /// getFlags - Return the raw flags of the source value, \see MemOperandFlags.
+ unsigned int getFlags() const { return Flags & ((1 << MOMaxBits) - 1); }
+
+ /// getOffset - For normal values, this is a byte offset added to the base
+ /// address. For PseudoSourceValue::FPRel values, this is the FrameIndex
+ /// number.
+ int64_t getOffset() const { return PtrInfo.Offset; }
+
+ /// getSize - Return the size in bytes of the memory reference.
+ uint64_t getSize() const { return Size; }
+
+ /// getAlignment - Return the minimum known alignment in bytes of the
+ /// actual memory reference.
+ uint64_t getAlignment() const;
+
+ /// getBaseAlignment - Return the minimum known alignment in bytes of the
+ /// base address, without the offset.
+ uint64_t getBaseAlignment() const { return (1u << (Flags >> MOMaxBits)) >> 1; }
+
+ /// getTBAAInfo - Return the TBAA tag for the memory reference.
+ const MDNode *getTBAAInfo() const { return TBAAInfo; }
+
+ /// getRanges - Return the range tag for the memory reference.
+ const MDNode *getRanges() const { return Ranges; }
+
+ bool isLoad() const { return Flags & MOLoad; }
+ bool isStore() const { return Flags & MOStore; }
+ bool isVolatile() const { return Flags & MOVolatile; }
+ bool isNonTemporal() const { return Flags & MONonTemporal; }
+ bool isInvariant() const { return Flags & MOInvariant; }
+
+ /// refineAlignment - Update this MachineMemOperand to reflect the alignment
+ /// of MMO, if it has a greater alignment. This must only be used when the
+ /// new alignment applies to all users of this MachineMemOperand.
+ void refineAlignment(const MachineMemOperand *MMO);
+
+ /// setValue - Change the SourceValue for this MachineMemOperand. This
+ /// should only be used when an object is being relocated and all references
+ /// to it are being updated.
+ void setValue(const Value *NewSV) { PtrInfo.V = NewSV; }
+ void setOffset(int64_t NewOffset) { PtrInfo.Offset = NewOffset; }
+
+ /// Profile - Gather unique data for the object.
+ ///
+ void Profile(FoldingSetNodeID &ID) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
new file mode 100644
index 000000000000..6b88d4a9499b
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -0,0 +1,405 @@
+//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect meta information for a module. This information should be in a
+// neutral form that can be used by different debugging and exception handling
+// schemes.
+//
+// The organization of information is primarily clustered around the source
+// compile units. The main exception is source line correspondence where
+// inlining may interleave code from various compile units.
+//
+// The following information can be retrieved from the MachineModuleInfo.
+//
+// -- Source directories - Directories are uniqued based on their canonical
+// string and assigned a sequential numeric ID (base 1.)
+// -- Source files - Files are also uniqued based on their name and directory
+// ID. A file ID is sequential number (base 1.)
+// -- Source line correspondence - A vector of file ID, line#, column# triples.
+// A DEBUG_LOCATION instruction is generated by the DAG Legalizer
+// corresponding to each entry in the source line list. This allows a debug
+// emitter to generate labels referenced by debug information tables.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+class Constant;
+class GlobalVariable;
+class MDNode;
+class MMIAddrLabelMap;
+class MachineBasicBlock;
+class MachineFunction;
+class Module;
+class PointerType;
+class StructType;
+
+//===----------------------------------------------------------------------===//
+/// LandingPadInfo - This structure is used to retain landing pad info for
+/// the current function.
+///
+struct LandingPadInfo {
+ MachineBasicBlock *LandingPadBlock; // Landing pad block.
+ SmallVector<MCSymbol*, 1> BeginLabels; // Labels prior to invoke.
+ SmallVector<MCSymbol*, 1> EndLabels; // Labels after invoke.
+ MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
+ const Function *Personality; // Personality function.
+ std::vector<int> TypeIds; // List of type ids (filters negative)
+
+ explicit LandingPadInfo(MachineBasicBlock *MBB)
+ : LandingPadBlock(MBB), LandingPadLabel(0), Personality(0) {}
+};
+
+//===----------------------------------------------------------------------===//
+/// MachineModuleInfoImpl - This class can be derived from and used by targets
+/// to hold private target-specific information for each Module. Objects of
+/// type are accessed/created with MMI::getInfo and destroyed when the
+/// MachineModuleInfo is destroyed.
+///
+class MachineModuleInfoImpl {
+public:
+ typedef PointerIntPair<MCSymbol*, 1, bool> StubValueTy;
+ virtual ~MachineModuleInfoImpl();
+ typedef std::vector<std::pair<MCSymbol*, StubValueTy> > SymbolListTy;
+protected:
+ static SymbolListTy GetSortedStubs(const DenseMap<MCSymbol*, StubValueTy>&);
+};
+
+//===----------------------------------------------------------------------===//
+/// MachineModuleInfo - This class contains meta information specific to a
+/// module. Queries can be made by different debugging and exception handling
+/// schemes and reformated for specific use.
+///
+class MachineModuleInfo : public ImmutablePass {
+ /// Context - This is the MCContext used for the entire code generator.
+ MCContext Context;
+
+ /// TheModule - This is the LLVM Module being worked on.
+ const Module *TheModule;
+
+ /// ObjFileMMI - This is the object-file-format-specific implementation of
+ /// MachineModuleInfoImpl, which lets targets accumulate whatever info they
+ /// want.
+ MachineModuleInfoImpl *ObjFileMMI;
+
+ /// FrameMoves - List of moves done by a function's prolog. Used to construct
+ /// frame maps by debug and exception handling consumers.
+ std::vector<MachineMove> FrameMoves;
+
+ /// CompactUnwindEncoding - If the target supports it, this is the compact
+ /// unwind encoding. It replaces a function's CIE and FDE.
+ uint32_t CompactUnwindEncoding;
+
+ /// LandingPads - List of LandingPadInfo describing the landing pad
+ /// information in the current function.
+ std::vector<LandingPadInfo> LandingPads;
+
+ /// LPadToCallSiteMap - Map a landing pad's EH symbol to the call site
+ /// indexes.
+ DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap;
+
+ /// CallSiteMap - Map of invoke call site index values to associated begin
+ /// EH_LABEL for the current function.
+ DenseMap<MCSymbol*, unsigned> CallSiteMap;
+
+ /// CurCallSite - The current call site index being processed, if any. 0 if
+ /// none.
+ unsigned CurCallSite;
+
+ /// TypeInfos - List of C++ TypeInfo used in the current function.
+ std::vector<const GlobalVariable *> TypeInfos;
+
+ /// FilterIds - List of typeids encoding filters used in the current function.
+ std::vector<unsigned> FilterIds;
+
+ /// FilterEnds - List of the indices in FilterIds corresponding to filter
+ /// terminators.
+ std::vector<unsigned> FilterEnds;
+
+ /// Personalities - Vector of all personality functions ever seen. Used to
+ /// emit common EH frames.
+ std::vector<const Function *> Personalities;
+
+ /// UsedFunctions - The functions in the @llvm.used list in a more easily
+ /// searchable format. This does not include the functions in
+ /// llvm.compiler.used.
+ SmallPtrSet<const Function *, 32> UsedFunctions;
+
+ /// AddrLabelSymbols - This map keeps track of which symbol is being used for
+ /// the specified basic block's address of label.
+ MMIAddrLabelMap *AddrLabelSymbols;
+
+ bool CallsEHReturn;
+ bool CallsUnwindInit;
+
+ /// DbgInfoAvailable - True if debugging information is available
+ /// in this module.
+ bool DbgInfoAvailable;
+
+ /// UsesVAFloatArgument - True if this module calls VarArg function with
+ /// floating-point arguments. This is used to emit an undefined reference
+ /// to _fltused on Windows targets.
+ bool UsesVAFloatArgument;
+
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ typedef std::pair<unsigned, DebugLoc> UnsignedDebugLocPair;
+ typedef SmallVector<std::pair<TrackingVH<MDNode>, UnsignedDebugLocPair>, 4>
+ VariableDbgInfoMapTy;
+ VariableDbgInfoMapTy VariableDbgInfo;
+
+ MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL.
+ // Real constructor.
+ MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
+ const MCObjectFileInfo *MOFI);
+ ~MachineModuleInfo();
+
+ bool doInitialization();
+ bool doFinalization();
+
+ /// EndFunction - Discard function meta information.
+ ///
+ void EndFunction();
+
+ const MCContext &getContext() const { return Context; }
+ MCContext &getContext() { return Context; }
+
+ void setModule(const Module *M) { TheModule = M; }
+ const Module *getModule() const { return TheModule; }
+
+ /// getInfo - Keep track of various per-function pieces of information for
+ /// backends that would like to do so.
+ ///
+ template<typename Ty>
+ Ty &getObjFileInfo() {
+ if (ObjFileMMI == 0)
+ ObjFileMMI = new Ty(*this);
+ return *static_cast<Ty*>(ObjFileMMI);
+ }
+
+ template<typename Ty>
+ const Ty &getObjFileInfo() const {
+ return const_cast<MachineModuleInfo*>(this)->getObjFileInfo<Ty>();
+ }
+
+ /// AnalyzeModule - Scan the module for global debug information.
+ ///
+ void AnalyzeModule(const Module &M);
+
+ /// hasDebugInfo - Returns true if valid debug info is present.
+ ///
+ bool hasDebugInfo() const { return DbgInfoAvailable; }
+ void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
+
+ bool callsEHReturn() const { return CallsEHReturn; }
+ void setCallsEHReturn(bool b) { CallsEHReturn = b; }
+
+ bool callsUnwindInit() const { return CallsUnwindInit; }
+ void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
+
+ bool usesVAFloatArgument() const {
+ return UsesVAFloatArgument;
+ }
+
+ void setUsesVAFloatArgument(bool b) {
+ UsesVAFloatArgument = b;
+ }
+
+ /// getFrameMoves - Returns a reference to a list of moves done in the current
+ /// function's prologue. Used to construct frame maps for debug and exception
+ /// handling comsumers.
+ std::vector<MachineMove> &getFrameMoves() { return FrameMoves; }
+
+ /// getCompactUnwindEncoding - Returns the compact unwind encoding for a
+ /// function if the target supports the encoding. This encoding replaces a
+ /// function's CIE and FDE.
+ uint32_t getCompactUnwindEncoding() const { return CompactUnwindEncoding; }
+
+ /// setCompactUnwindEncoding - Set the compact unwind encoding for a function
+ /// if the target supports the encoding.
+ void setCompactUnwindEncoding(uint32_t Enc) { CompactUnwindEncoding = Enc; }
+
+ /// getAddrLabelSymbol - Return the symbol to be used for the specified basic
+ /// block when its address is taken. This cannot be its normal LBB label
+ /// because the block may be accessed outside its containing function.
+ MCSymbol *getAddrLabelSymbol(const BasicBlock *BB);
+
+ /// getAddrLabelSymbolToEmit - Return the symbol to be used for the specified
+ /// basic block when its address is taken. If other blocks were RAUW'd to
+ /// this one, we may have to emit them as well, return the whole set.
+ std::vector<MCSymbol*> getAddrLabelSymbolToEmit(const BasicBlock *BB);
+
+ /// takeDeletedSymbolsForFunction - If the specified function has had any
+ /// references to address-taken blocks generated, but the block got deleted,
+ /// return the symbol now so we can emit it. This prevents emitting a
+ /// reference to a symbol that has no definition.
+ void takeDeletedSymbolsForFunction(const Function *F,
+ std::vector<MCSymbol*> &Result);
+
+
+ //===- EH ---------------------------------------------------------------===//
+
+ /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
+ /// specified MachineBasicBlock.
+ LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
+
+ /// addInvoke - Provide the begin and end labels of an invoke style call and
+ /// associate it with a try landing pad block.
+ void addInvoke(MachineBasicBlock *LandingPad,
+ MCSymbol *BeginLabel, MCSymbol *EndLabel);
+
+ /// addLandingPad - Add a new panding pad. Returns the label ID for the
+ /// landing pad entry.
+ MCSymbol *addLandingPad(MachineBasicBlock *LandingPad);
+
+ /// addPersonality - Provide the personality function for the exception
+ /// information.
+ void addPersonality(MachineBasicBlock *LandingPad,
+ const Function *Personality);
+
+ /// getPersonalityIndex - Get index of the current personality function inside
+ /// Personalitites array
+ unsigned getPersonalityIndex() const;
+
+ /// getPersonalities - Return array of personality functions ever seen.
+ const std::vector<const Function *>& getPersonalities() const {
+ return Personalities;
+ }
+
+ /// isUsedFunction - Return true if the functions in the llvm.used list. This
+ /// does not return true for things in llvm.compiler.used unless they are also
+ /// in llvm.used.
+ bool isUsedFunction(const Function *F) {
+ return UsedFunctions.count(F);
+ }
+
+ /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
+ ///
+ void addCatchTypeInfo(MachineBasicBlock *LandingPad,
+ ArrayRef<const GlobalVariable *> TyInfo);
+
+ /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
+ ///
+ void addFilterTypeInfo(MachineBasicBlock *LandingPad,
+ ArrayRef<const GlobalVariable *> TyInfo);
+
+ /// addCleanup - Add a cleanup action for a landing pad.
+ ///
+ void addCleanup(MachineBasicBlock *LandingPad);
+
+ /// getTypeIDFor - Return the type id for the specified typeinfo. This is
+ /// function wide.
+ unsigned getTypeIDFor(const GlobalVariable *TI);
+
+ /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is
+ /// function wide.
+ int getFilterIDFor(std::vector<unsigned> &TyIds);
+
+ /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
+ /// pads.
+ void TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = 0);
+
+ /// getLandingPads - Return a reference to the landing pad info for the
+ /// current function.
+ const std::vector<LandingPadInfo> &getLandingPads() const {
+ return LandingPads;
+ }
+
+ /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call
+ /// site indexes.
+ void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
+
+ /// getCallSiteLandingPad - Get the call site indexes for a landing pad EH
+ /// symbol.
+ SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
+ assert(hasCallSiteLandingPad(Sym) &&
+ "missing call site number for landing pad!");
+ return LPadToCallSiteMap[Sym];
+ }
+
+ /// hasCallSiteLandingPad - Return true if the landing pad Eh symbol has an
+ /// associated call site.
+ bool hasCallSiteLandingPad(MCSymbol *Sym) {
+ return !LPadToCallSiteMap[Sym].empty();
+ }
+
+ /// setCallSiteBeginLabel - Map the begin label for a call site.
+ void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) {
+ CallSiteMap[BeginLabel] = Site;
+ }
+
+ /// getCallSiteBeginLabel - Get the call site number for a begin label.
+ unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) {
+ assert(hasCallSiteBeginLabel(BeginLabel) &&
+ "Missing call site number for EH_LABEL!");
+ return CallSiteMap[BeginLabel];
+ }
+
+ /// hasCallSiteBeginLabel - Return true if the begin label has a call site
+ /// number associated with it.
+ bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) {
+ return CallSiteMap[BeginLabel] != 0;
+ }
+
+ /// setCurrentCallSite - Set the call site currently being processed.
+ void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
+
+ /// getCurrentCallSite - Get the call site currently being processed, if any.
+ /// return zero if none.
+ unsigned getCurrentCallSite(void) { return CurCallSite; }
+
+ /// getTypeInfos - Return a reference to the C++ typeinfo for the current
+ /// function.
+ const std::vector<const GlobalVariable *> &getTypeInfos() const {
+ return TypeInfos;
+ }
+
+ /// getFilterIds - Return a reference to the typeids encoding filters used in
+ /// the current function.
+ const std::vector<unsigned> &getFilterIds() const {
+ return FilterIds;
+ }
+
+ /// getPersonality - Return a personality function if available. The presence
+ /// of one is required to emit exception handling info.
+ const Function *getPersonality() const;
+
+ /// setVariableDbgInfo - Collect information used to emit debugging
+ /// information of a variable.
+ void setVariableDbgInfo(MDNode *N, unsigned Slot, DebugLoc Loc) {
+ VariableDbgInfo.push_back(std::make_pair(N, std::make_pair(Slot, Loc)));
+ }
+
+ VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; }
+
+}; // End class MachineModuleInfo
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
new file mode 100644
index 000000000000..9401ffd199d4
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -0,0 +1,97 @@
+//===-- llvm/CodeGen/MachineModuleInfoImpls.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 defines object-file format specific implementations of
+// MachineModuleInfoImpl.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMODULEINFOIMPLS_H
+#define LLVM_CODEGEN_MACHINEMODULEINFOIMPLS_H
+
+#include "llvm/CodeGen/MachineModuleInfo.h"
+
+namespace llvm {
+ class MCSymbol;
+
+ /// MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation
+ /// for MachO targets.
+ class MachineModuleInfoMachO : public MachineModuleInfoImpl {
+ /// FnStubs - Darwin '$stub' stubs. The key is something like "Lfoo$stub",
+ /// the value is something like "_foo".
+ DenseMap<MCSymbol*, StubValueTy> FnStubs;
+
+ /// GVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
+ /// "Lfoo$non_lazy_ptr", the value is something like "_foo". The extra bit
+ /// is true if this GV is external.
+ DenseMap<MCSymbol*, StubValueTy> GVStubs;
+
+ /// HiddenGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something like
+ /// "Lfoo$non_lazy_ptr", the value is something like "_foo". Unlike GVStubs
+ /// these are for things with hidden visibility. The extra bit is true if
+ /// this GV is external.
+ DenseMap<MCSymbol*, StubValueTy> HiddenGVStubs;
+
+ virtual void Anchor(); // Out of line virtual method.
+ public:
+ MachineModuleInfoMachO(const MachineModuleInfo &) {}
+
+ StubValueTy &getFnStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return FnStubs[Sym];
+ }
+
+ StubValueTy &getGVStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return GVStubs[Sym];
+ }
+
+ StubValueTy &getHiddenGVStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return HiddenGVStubs[Sym];
+ }
+
+ /// Accessor methods to return the set of stubs in sorted order.
+ SymbolListTy GetFnStubList() const {
+ return GetSortedStubs(FnStubs);
+ }
+ SymbolListTy GetGVStubList() const {
+ return GetSortedStubs(GVStubs);
+ }
+ SymbolListTy GetHiddenGVStubList() const {
+ return GetSortedStubs(HiddenGVStubs);
+ }
+ };
+
+ /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
+ /// for ELF targets.
+ class MachineModuleInfoELF : public MachineModuleInfoImpl {
+ /// GVStubs - These stubs are used to materialize global addresses in PIC
+ /// mode.
+ DenseMap<MCSymbol*, StubValueTy> GVStubs;
+
+ virtual void Anchor(); // Out of line virtual method.
+ public:
+ MachineModuleInfoELF(const MachineModuleInfo &) {}
+
+ StubValueTy &getGVStubEntry(MCSymbol *Sym) {
+ assert(Sym && "Key cannot be null");
+ return GVStubs[Sym];
+ }
+
+ /// Accessor methods to return the set of stubs in sorted order.
+
+ SymbolListTy GetGVStubList() const {
+ return GetSortedStubs(GVStubs);
+ }
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineOperand.h b/contrib/llvm/include/llvm/CodeGen/MachineOperand.h
new file mode 100644
index 000000000000..d244dd92103d
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -0,0 +1,674 @@
+//===-- llvm/CodeGen/MachineOperand.h - MachineOperand class ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineOperand class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEOPERAND_H
+#define LLVM_CODEGEN_MACHINEOPERAND_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+class BlockAddress;
+class ConstantFP;
+class ConstantInt;
+class GlobalValue;
+class MachineBasicBlock;
+class MachineInstr;
+class MachineRegisterInfo;
+class MDNode;
+class TargetMachine;
+class TargetRegisterInfo;
+class raw_ostream;
+class MCSymbol;
+
+/// MachineOperand class - Representation of each machine instruction operand.
+///
+class MachineOperand {
+public:
+ enum MachineOperandType {
+ MO_Register, ///< Register operand.
+ MO_Immediate, ///< Immediate operand
+ MO_CImmediate, ///< Immediate >64bit operand
+ MO_FPImmediate, ///< Floating-point immediate operand
+ MO_MachineBasicBlock, ///< MachineBasicBlock reference
+ MO_FrameIndex, ///< Abstract Stack Frame Index
+ MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool
+ MO_JumpTableIndex, ///< Address of indexed Jump Table for switch
+ MO_ExternalSymbol, ///< Name of external global symbol
+ MO_GlobalAddress, ///< Address of a global value
+ MO_BlockAddress, ///< Address of a basic block
+ MO_RegisterMask, ///< Mask of preserved registers.
+ MO_Metadata, ///< Metadata reference (for debug info)
+ MO_MCSymbol ///< MCSymbol reference (for debug/eh info)
+ };
+
+private:
+ /// OpKind - Specify what kind of operand this is. This discriminates the
+ /// union.
+ unsigned char OpKind; // MachineOperandType
+
+ /// 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;
+
+ /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register
+ /// operands.
+
+ /// IsDef - True if this is a def, false if this is a use of the register.
+ ///
+ bool IsDef : 1;
+
+ /// IsImp - True if this is an implicit def or use, false if it is explicit.
+ ///
+ bool IsImp : 1;
+
+ /// IsKill - True if this instruction is the last use of the register on this
+ /// path through the function. This is only valid on uses of registers.
+ bool IsKill : 1;
+
+ /// IsDead - True if this register is never used by a subsequent instruction.
+ /// This is only valid on definitions of registers.
+ bool IsDead : 1;
+
+ /// IsUndef - True if this register operand reads an "undef" value, i.e. the
+ /// read value doesn't matter. This flag can be set on both use and def
+ /// operands. On a sub-register def operand, it refers to the part of the
+ /// register that isn't written. On a full-register def operand, it is a
+ /// noop. See readsReg().
+ ///
+ /// This is only valid on registers.
+ ///
+ /// Note that an instruction may have multiple <undef> operands referring to
+ /// the same register. In that case, the instruction may depend on those
+ /// operands reading the same dont-care value. For example:
+ ///
+ /// %vreg1<def> = XOR %vreg2<undef>, %vreg2<undef>
+ ///
+ /// Any register can be used for %vreg2, and its value doesn't matter, but
+ /// the two operands must be the same register.
+ ///
+ bool IsUndef : 1;
+
+ /// IsInternalRead - True if this operand reads a value that was defined
+ /// inside the same instruction or bundle. This flag can be set on both use
+ /// and def operands. On a sub-register def operand, it refers to the part
+ /// of the register that isn't written. On a full-register def operand, it
+ /// is a noop.
+ ///
+ /// When this flag is set, the instruction bundle must contain at least one
+ /// other def of the register. If multiple instructions in the bundle define
+ /// the register, the meaning is target-defined.
+ bool IsInternalRead : 1;
+
+ /// IsEarlyClobber - True if this MO_Register 'def' operand is written to
+ /// by the MachineInstr before all input registers are read. This is used to
+ /// model the GCC inline asm '&' constraint modifier.
+ bool IsEarlyClobber : 1;
+
+ /// IsDebug - True if this MO_Register 'use' operand is in a debug pseudo,
+ /// not a real instruction. Such uses should be ignored during codegen.
+ bool IsDebug : 1;
+
+ /// SmallContents - This really should be part of the Contents union, but
+ /// lives out here so we can get a better packed struct.
+ /// MO_Register: Register number.
+ /// OffsetedInfo: Low bits of offset.
+ union {
+ unsigned RegNo; // For MO_Register.
+ unsigned OffsetLo; // Matches Contents.OffsetedInfo.OffsetHi.
+ } SmallContents;
+
+ /// ParentMI - This is the instruction that this operand is embedded into.
+ /// This is valid for all operand types, when the operand is in an instr.
+ MachineInstr *ParentMI;
+
+ /// Contents union - This contains the payload for the various operand types.
+ union {
+ MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
+ const ConstantFP *CFP; // For MO_FPImmediate.
+ const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
+ int64_t ImmVal; // For MO_Immediate.
+ const uint32_t *RegMask; // For MO_RegisterMask.
+ const MDNode *MD; // For MO_Metadata.
+ MCSymbol *Sym; // For MO_MCSymbol
+
+ struct { // For MO_Register.
+ // Register number is in SmallContents.RegNo.
+ MachineOperand **Prev; // Access list for register.
+ MachineOperand *Next;
+ } Reg;
+
+ /// OffsetedInfo - This struct contains the offset and an object identifier.
+ /// this represent the object as with an optional offset from it.
+ struct {
+ union {
+ int Index; // For MO_*Index - The index itself.
+ const char *SymbolName; // For MO_ExternalSymbol.
+ const GlobalValue *GV; // For MO_GlobalAddress.
+ const BlockAddress *BA; // For MO_BlockAddress.
+ } Val;
+ // Low bits of offset are in SmallContents.OffsetLo.
+ int OffsetHi; // An offset from the object, high 32 bits.
+ } OffsetedInfo;
+ } Contents;
+
+ explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {
+ TargetFlags = 0;
+ }
+public:
+ /// getType - Returns the MachineOperandType for this operand.
+ ///
+ MachineOperandType getType() const { return (MachineOperandType)OpKind; }
+
+ unsigned char getTargetFlags() const { return TargetFlags; }
+ void setTargetFlags(unsigned char F) { TargetFlags = F; }
+ void addTargetFlag(unsigned char F) { TargetFlags |= F; }
+
+
+ /// getParent - Return the instruction that this operand belongs to.
+ ///
+ MachineInstr *getParent() { return ParentMI; }
+ const MachineInstr *getParent() const { return ParentMI; }
+
+ /// clearParent - Reset the parent pointer.
+ ///
+ /// The MachineOperand copy constructor also copies ParentMI, expecting the
+ /// original to be deleted. If a MachineOperand is ever stored outside a
+ /// MachineInstr, the parent pointer must be cleared.
+ ///
+ /// Never call clearParent() on an operand in a MachineInstr.
+ ///
+ void clearParent() { ParentMI = 0; }
+
+ void print(raw_ostream &os, const TargetMachine *TM = 0) const;
+
+ //===--------------------------------------------------------------------===//
+ // Accessors that tell you what kind of MachineOperand you're looking at.
+ //===--------------------------------------------------------------------===//
+
+ /// isReg - Tests if this is a MO_Register operand.
+ bool isReg() const { return OpKind == MO_Register; }
+ /// isImm - Tests if this is a MO_Immediate operand.
+ bool isImm() const { return OpKind == MO_Immediate; }
+ /// isCImm - Test if t his is a MO_CImmediate operand.
+ bool isCImm() const { return OpKind == MO_CImmediate; }
+ /// isFPImm - Tests if this is a MO_FPImmediate operand.
+ bool isFPImm() const { return OpKind == MO_FPImmediate; }
+ /// isMBB - Tests if this is a MO_MachineBasicBlock operand.
+ bool isMBB() const { return OpKind == MO_MachineBasicBlock; }
+ /// isFI - Tests if this is a MO_FrameIndex operand.
+ bool isFI() const { return OpKind == MO_FrameIndex; }
+ /// isCPI - Tests if this is a MO_ConstantPoolIndex operand.
+ bool isCPI() const { return OpKind == MO_ConstantPoolIndex; }
+ /// isJTI - Tests if this is a MO_JumpTableIndex operand.
+ bool isJTI() const { return OpKind == MO_JumpTableIndex; }
+ /// isGlobal - Tests if this is a MO_GlobalAddress operand.
+ bool isGlobal() const { return OpKind == MO_GlobalAddress; }
+ /// isSymbol - Tests if this is a MO_ExternalSymbol operand.
+ bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
+ /// isBlockAddress - Tests if this is a MO_BlockAddress operand.
+ bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
+ /// isRegMask - Tests if this is a MO_RegisterMask operand.
+ bool isRegMask() const { return OpKind == MO_RegisterMask; }
+ /// isMetadata - Tests if this is a MO_Metadata operand.
+ bool isMetadata() const { return OpKind == MO_Metadata; }
+ bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
+
+
+ //===--------------------------------------------------------------------===//
+ // Accessors for Register Operands
+ //===--------------------------------------------------------------------===//
+
+ /// getReg - Returns the register number.
+ unsigned getReg() const {
+ assert(isReg() && "This is not a register operand!");
+ return SmallContents.RegNo;
+ }
+
+ unsigned getSubReg() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return (unsigned)SubReg;
+ }
+
+ bool isUse() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return !IsDef;
+ }
+
+ bool isDef() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsDef;
+ }
+
+ bool isImplicit() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsImp;
+ }
+
+ bool isDead() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsDead;
+ }
+
+ bool isKill() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsKill;
+ }
+
+ bool isUndef() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsUndef;
+ }
+
+ bool isInternalRead() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsInternalRead;
+ }
+
+ bool isEarlyClobber() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsEarlyClobber;
+ }
+
+ bool isDebug() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return IsDebug;
+ }
+
+ /// readsReg - Returns true if this operand reads the previous value of its
+ /// register. A use operand with the <undef> flag set doesn't read its
+ /// register. A sub-register def implicitly reads the other parts of the
+ /// register being redefined unless the <undef> flag is set.
+ ///
+ /// This refers to reading the register value from before the current
+ /// instruction or bundle. Internal bundle reads are not included.
+ bool readsReg() const {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ return !isUndef() && !isInternalRead() && (isUse() || getSubReg());
+ }
+
+ /// getNextOperandForReg - Return the next MachineOperand in the function that
+ /// uses or defines this register.
+ MachineOperand *getNextOperandForReg() const {
+ assert(isReg() && "This is not a register operand!");
+ return Contents.Reg.Next;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Mutators for Register Operands
+ //===--------------------------------------------------------------------===//
+
+ /// Change the register this operand corresponds to.
+ ///
+ void setReg(unsigned Reg);
+
+ void setSubReg(unsigned subReg) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ SubReg = (unsigned char)subReg;
+ }
+
+ /// substVirtReg - Substitute the current register with the virtual
+ /// subregister Reg:SubReg. Take any existing SubReg index into account,
+ /// using TargetRegisterInfo to compose the subreg indices if necessary.
+ /// Reg must be a virtual register, SubIdx can be 0.
+ ///
+ void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo&);
+
+ /// substPhysReg - Substitute the current register with the physical register
+ /// Reg, taking any existing SubReg into account. For instance,
+ /// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL.
+ ///
+ void substPhysReg(unsigned Reg, const TargetRegisterInfo&);
+
+ void setIsUse(bool Val = true) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ assert((Val || !isDebug()) && "Marking a debug operation as def");
+ IsDef = !Val;
+ }
+
+ void setIsDef(bool Val = true) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ assert((!Val || !isDebug()) && "Marking a debug operation as def");
+ IsDef = Val;
+ }
+
+ void setImplicit(bool Val = true) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ IsImp = Val;
+ }
+
+ void setIsKill(bool Val = true) {
+ assert(isReg() && !IsDef && "Wrong MachineOperand accessor");
+ assert((!Val || !isDebug()) && "Marking a debug operation as kill");
+ IsKill = Val;
+ }
+
+ void setIsDead(bool Val = true) {
+ assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+ IsDead = Val;
+ }
+
+ void setIsUndef(bool Val = true) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ IsUndef = Val;
+ }
+
+ void setIsInternalRead(bool Val = true) {
+ assert(isReg() && "Wrong MachineOperand accessor");
+ IsInternalRead = Val;
+ }
+
+ void setIsEarlyClobber(bool Val = true) {
+ assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+ IsEarlyClobber = Val;
+ }
+
+ void setIsDebug(bool Val = true) {
+ assert(isReg() && IsDef && "Wrong MachineOperand accessor");
+ IsDebug = Val;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors for various operand types.
+ //===--------------------------------------------------------------------===//
+
+ int64_t getImm() const {
+ assert(isImm() && "Wrong MachineOperand accessor");
+ return Contents.ImmVal;
+ }
+
+ const ConstantInt *getCImm() const {
+ assert(isCImm() && "Wrong MachineOperand accessor");
+ return Contents.CI;
+ }
+
+ const ConstantFP *getFPImm() const {
+ assert(isFPImm() && "Wrong MachineOperand accessor");
+ return Contents.CFP;
+ }
+
+ MachineBasicBlock *getMBB() const {
+ assert(isMBB() && "Wrong MachineOperand accessor");
+ return Contents.MBB;
+ }
+
+ int getIndex() const {
+ assert((isFI() || isCPI() || isJTI()) &&
+ "Wrong MachineOperand accessor");
+ return Contents.OffsetedInfo.Val.Index;
+ }
+
+ const GlobalValue *getGlobal() const {
+ assert(isGlobal() && "Wrong MachineOperand accessor");
+ return Contents.OffsetedInfo.Val.GV;
+ }
+
+ const BlockAddress *getBlockAddress() const {
+ assert(isBlockAddress() && "Wrong MachineOperand accessor");
+ return Contents.OffsetedInfo.Val.BA;
+ }
+
+ MCSymbol *getMCSymbol() const {
+ assert(isMCSymbol() && "Wrong MachineOperand accessor");
+ return Contents.Sym;
+ }
+
+ /// getOffset - Return the offset from the symbol in this operand. This always
+ /// returns 0 for ExternalSymbol operands.
+ int64_t getOffset() const {
+ assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
+ "Wrong MachineOperand accessor");
+ return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
+ SmallContents.OffsetLo;
+ }
+
+ const char *getSymbolName() const {
+ assert(isSymbol() && "Wrong MachineOperand accessor");
+ return Contents.OffsetedInfo.Val.SymbolName;
+ }
+
+ /// clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
+ /// It is sometimes necessary to detach the register mask pointer from its
+ /// machine operand. This static method can be used for such detached bit
+ /// mask pointers.
+ static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg) {
+ // See TargetRegisterInfo.h.
+ assert(PhysReg < (1u << 30) && "Not a physical register");
+ return !(RegMask[PhysReg / 32] & (1u << PhysReg % 32));
+ }
+
+ /// clobbersPhysReg - Returns true if this RegMask operand clobbers PhysReg.
+ bool clobbersPhysReg(unsigned PhysReg) const {
+ return clobbersPhysReg(getRegMask(), PhysReg);
+ }
+
+ /// getRegMask - Returns a bit mask of registers preserved by this RegMask
+ /// operand.
+ const uint32_t *getRegMask() const {
+ assert(isRegMask() && "Wrong MachineOperand accessor");
+ return Contents.RegMask;
+ }
+
+ const MDNode *getMetadata() const {
+ assert(isMetadata() && "Wrong MachineOperand accessor");
+ return Contents.MD;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Mutators for various operand types.
+ //===--------------------------------------------------------------------===//
+
+ void setImm(int64_t immVal) {
+ assert(isImm() && "Wrong MachineOperand mutator");
+ Contents.ImmVal = immVal;
+ }
+
+ void setOffset(int64_t Offset) {
+ assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) &&
+ "Wrong MachineOperand accessor");
+ SmallContents.OffsetLo = unsigned(Offset);
+ Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
+ }
+
+ void setIndex(int Idx) {
+ assert((isFI() || isCPI() || isJTI()) &&
+ "Wrong MachineOperand accessor");
+ Contents.OffsetedInfo.Val.Index = Idx;
+ }
+
+ void setMBB(MachineBasicBlock *MBB) {
+ assert(isMBB() && "Wrong MachineOperand accessor");
+ Contents.MBB = MBB;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other methods.
+ //===--------------------------------------------------------------------===//
+
+ /// isIdenticalTo - Return true if this operand is identical to the specified
+ /// operand. Note: This method ignores isKill and isDead properties.
+ bool isIdenticalTo(const MachineOperand &Other) const;
+
+ /// ChangeToImmediate - Replace this operand with a new immediate operand of
+ /// the specified value. If an operand is known to be an immediate already,
+ /// the setImm method should be used.
+ void ChangeToImmediate(int64_t ImmVal);
+
+ /// ChangeToRegister - Replace this operand with a new register operand of
+ /// the specified value. If an operand is known to be an register already,
+ /// the setReg method should be used.
+ void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+ bool isKill = false, bool isDead = false,
+ bool isUndef = false, bool isDebug = false);
+
+ //===--------------------------------------------------------------------===//
+ // Construction methods.
+ //===--------------------------------------------------------------------===//
+
+ static MachineOperand CreateImm(int64_t Val) {
+ MachineOperand Op(MachineOperand::MO_Immediate);
+ Op.setImm(Val);
+ return Op;
+ }
+
+ static MachineOperand CreateCImm(const ConstantInt *CI) {
+ MachineOperand Op(MachineOperand::MO_CImmediate);
+ Op.Contents.CI = CI;
+ return Op;
+ }
+
+ static MachineOperand CreateFPImm(const ConstantFP *CFP) {
+ MachineOperand Op(MachineOperand::MO_FPImmediate);
+ Op.Contents.CFP = CFP;
+ return Op;
+ }
+
+ static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false,
+ bool isKill = false, bool isDead = false,
+ bool isUndef = false,
+ bool isEarlyClobber = false,
+ unsigned SubReg = 0,
+ bool isDebug = false) {
+ MachineOperand Op(MachineOperand::MO_Register);
+ Op.IsDef = isDef;
+ Op.IsImp = isImp;
+ Op.IsKill = isKill;
+ Op.IsDead = isDead;
+ Op.IsUndef = isUndef;
+ Op.IsInternalRead = false;
+ Op.IsEarlyClobber = isEarlyClobber;
+ Op.IsDebug = isDebug;
+ Op.SmallContents.RegNo = Reg;
+ Op.Contents.Reg.Prev = 0;
+ Op.Contents.Reg.Next = 0;
+ Op.SubReg = SubReg;
+ return Op;
+ }
+ static MachineOperand CreateMBB(MachineBasicBlock *MBB,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
+ Op.setMBB(MBB);
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+ static MachineOperand CreateFI(int Idx) {
+ MachineOperand Op(MachineOperand::MO_FrameIndex);
+ Op.setIndex(Idx);
+ return Op;
+ }
+ static MachineOperand CreateCPI(unsigned Idx, int Offset,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
+ Op.setIndex(Idx);
+ Op.setOffset(Offset);
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+ static MachineOperand CreateJTI(unsigned Idx,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_JumpTableIndex);
+ Op.setIndex(Idx);
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+ static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_GlobalAddress);
+ Op.Contents.OffsetedInfo.Val.GV = GV;
+ Op.setOffset(Offset);
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+ static MachineOperand CreateES(const char *SymName,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_ExternalSymbol);
+ Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
+ Op.setOffset(0); // Offset is always 0.
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+ static MachineOperand CreateBA(const BlockAddress *BA,
+ unsigned char TargetFlags = 0) {
+ MachineOperand Op(MachineOperand::MO_BlockAddress);
+ Op.Contents.OffsetedInfo.Val.BA = BA;
+ Op.setOffset(0); // Offset is always 0.
+ Op.setTargetFlags(TargetFlags);
+ return Op;
+ }
+ /// CreateRegMask - Creates a register mask operand referencing Mask. The
+ /// operand does not take ownership of the memory referenced by Mask, it must
+ /// remain valid for the lifetime of the operand.
+ ///
+ /// A RegMask operand represents a set of non-clobbered physical registers on
+ /// an instruction that clobbers many registers, typically a call. The bit
+ /// mask has a bit set for each physreg that is preserved by this
+ /// instruction, as described in the documentation for
+ /// TargetRegisterInfo::getCallPreservedMask().
+ ///
+ /// Any physreg with a 0 bit in the mask is clobbered by the instruction.
+ ///
+ static MachineOperand CreateRegMask(const uint32_t *Mask) {
+ assert(Mask && "Missing register mask");
+ MachineOperand Op(MachineOperand::MO_RegisterMask);
+ Op.Contents.RegMask = Mask;
+ return Op;
+ }
+ static MachineOperand CreateMetadata(const MDNode *Meta) {
+ MachineOperand Op(MachineOperand::MO_Metadata);
+ Op.Contents.MD = Meta;
+ return Op;
+ }
+
+ static MachineOperand CreateMCSymbol(MCSymbol *Sym) {
+ MachineOperand Op(MachineOperand::MO_MCSymbol);
+ Op.Contents.Sym = Sym;
+ return Op;
+ }
+
+ friend class MachineInstr;
+ friend class MachineRegisterInfo;
+private:
+ //===--------------------------------------------------------------------===//
+ // Methods for handling register use/def lists.
+ //===--------------------------------------------------------------------===//
+
+ /// isOnRegUseList - Return true if this operand is on a register use/def list
+ /// or false if not. This can only be called for register operands that are
+ /// part of a machine instruction.
+ bool isOnRegUseList() const {
+ assert(isReg() && "Can only add reg operand to use lists");
+ return Contents.Reg.Prev != 0;
+ }
+
+ /// AddRegOperandToRegInfo - Add this register operand to the specified
+ /// MachineRegisterInfo. If it is null, then the next/prev fields should be
+ /// explicitly nulled out.
+ void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo);
+
+ /// RemoveRegOperandFromRegInfo - Remove this register operand from the
+ /// MachineRegisterInfo it is linked with.
+ void RemoveRegOperandFromRegInfo();
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) {
+ MO.print(OS, 0);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h b/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h
new file mode 100644
index 000000000000..c41e8e26d66a
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachinePassRegistry.h
@@ -0,0 +1,157 @@
+//===-- llvm/CodeGen/MachinePassRegistry.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 the mechanics for machine function pass registries. A
+// function pass registry (MachinePassRegistry) is auto filled by the static
+// constructors of MachinePassRegistryNode. Further there is a command line
+// parser (RegisterPassParser) which listens to each registry for additions
+// and deletions, so that the appropriate command option is updated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+#define LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+typedef void *(*MachinePassCtor)();
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryListener - Listener to adds and removals of nodes in
+/// registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryListener {
+ virtual void anchor();
+public:
+ MachinePassRegistryListener() {}
+ virtual ~MachinePassRegistryListener() {}
+ virtual void NotifyAdd(const char *N, MachinePassCtor C, const char *D) = 0;
+ virtual void NotifyRemove(const char *N) = 0;
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryNode - Machine pass node stored in registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryNode {
+
+private:
+
+ MachinePassRegistryNode *Next; // Next function pass in list.
+ const char *Name; // Name of function pass.
+ const char *Description; // Description string.
+ MachinePassCtor Ctor; // Function pass creator.
+
+public:
+
+ MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
+ : Next(NULL)
+ , Name(N)
+ , Description(D)
+ , Ctor(C)
+ {}
+
+ // Accessors
+ MachinePassRegistryNode *getNext() const { return Next; }
+ MachinePassRegistryNode **getNextAddress() { return &Next; }
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
+ MachinePassCtor getCtor() const { return Ctor; }
+ void setNext(MachinePassRegistryNode *N) { Next = N; }
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistry - Track the registration of machine passes.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistry {
+
+private:
+
+ MachinePassRegistryNode *List; // List of registry nodes.
+ MachinePassCtor Default; // Default function pass creator.
+ MachinePassRegistryListener* Listener;// Listener for list adds are removes.
+
+public:
+
+ // NO CONSTRUCTOR - we don't want static constructor ordering to mess
+ // with the registry.
+
+ // Accessors.
+ //
+ MachinePassRegistryNode *getList() { return List; }
+ MachinePassCtor getDefault() { return Default; }
+ void setDefault(MachinePassCtor C) { Default = C; }
+ void setListener(MachinePassRegistryListener *L) { Listener = L; }
+
+ /// Add - Adds a function pass to the registration list.
+ ///
+ void Add(MachinePassRegistryNode *Node);
+
+ /// Remove - Removes a function pass from the registration list.
+ ///
+ void Remove(MachinePassRegistryNode *Node);
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterPassParser class - Handle the addition of new machine passes.
+///
+//===----------------------------------------------------------------------===//
+template<class RegistryClass>
+class RegisterPassParser : public MachinePassRegistryListener,
+ public cl::parser<typename RegistryClass::FunctionPassCtor> {
+public:
+ RegisterPassParser() {}
+ ~RegisterPassParser() { RegistryClass::setListener(NULL); }
+
+ void initialize(cl::Option &O) {
+ cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O);
+
+ // Add existing passes to option.
+ for (RegistryClass *Node = RegistryClass::getList();
+ Node; Node = Node->getNext()) {
+ this->addLiteralOption(Node->getName(),
+ (typename RegistryClass::FunctionPassCtor)Node->getCtor(),
+ Node->getDescription());
+ }
+
+ // Make sure we listen for list changes.
+ RegistryClass::setListener(this);
+ }
+
+ // Implement the MachinePassRegistryListener callbacks.
+ //
+ virtual void NotifyAdd(const char *N,
+ MachinePassCtor C,
+ const char *D) {
+ this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
+ }
+ virtual void NotifyRemove(const char *N) {
+ this->removeLiteralOption(N);
+ }
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
new file mode 100644
index 000000000000..3272fbd78ff5
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -0,0 +1,545 @@
+//===-- llvm/CodeGen/MachineRegisterInfo.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 defines the MachineRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#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 <vector>
+
+namespace llvm {
+
+/// MachineRegisterInfo - Keep track of information for virtual and physical
+/// registers, including vreg register classes, use/def chains for registers,
+/// etc.
+class MachineRegisterInfo {
+ const TargetRegisterInfo *const TRI;
+
+ /// IsSSA - True when the machine function is in SSA form and virtual
+ /// registers have a single def.
+ bool IsSSA;
+
+ /// TracksLiveness - True while register liveness is being tracked accurately.
+ /// Basic block live-in lists, kill flags, and implicit defs may not be
+ /// accurate when after this flag is cleared.
+ bool TracksLiveness;
+
+ /// VRegInfo - Information we keep for each virtual register.
+ ///
+ /// Each element in this list contains the register class of the vreg and the
+ /// start of the use/def list for the register.
+ IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
+ VirtReg2IndexFunctor> VRegInfo;
+
+ /// RegAllocHints - This vector records register allocation hints for virtual
+ /// registers. For each virtual register, it keeps a register and hint type
+ /// pair making up the allocation hint. Hint type is target specific except
+ /// for the value 0 which means the second value of the pair is the preferred
+ /// register for allocation. For example, if the hint is <0, 1024>, it means
+ /// the allocator should prefer the physical register allocated to the virtual
+ /// register of the hint.
+ IndexedMap<std::pair<unsigned, unsigned>, VirtReg2IndexFunctor> RegAllocHints;
+
+ /// PhysRegUseDefLists - This is an array of the head of the use/def list for
+ /// physical registers.
+ MachineOperand **PhysRegUseDefLists;
+
+ /// UsedPhysRegs - 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.
+ BitVector UsedPhysRegMask;
+
+ /// ReservedRegs - This is a bit vector of reserved registers. The target
+ /// may change its mind about which registers should be reserved. This
+ /// vector is the frozen set of reserved registers when register allocation
+ /// 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.
+ /// LiveIn values are allowed to have virtual registers associated with them,
+ /// stored in the second element.
+ std::vector<std::pair<unsigned, unsigned> > LiveIns;
+ std::vector<unsigned> LiveOuts;
+
+ MachineRegisterInfo(const MachineRegisterInfo&); // DO NOT IMPLEMENT
+ void operator=(const MachineRegisterInfo&); // DO NOT IMPLEMENT
+public:
+ explicit MachineRegisterInfo(const TargetRegisterInfo &TRI);
+ ~MachineRegisterInfo();
+
+ //===--------------------------------------------------------------------===//
+ // Function State
+ //===--------------------------------------------------------------------===//
+
+ // isSSA - Returns true when the machine function is in SSA form. Early
+ // passes require the machine function to be in SSA form where every virtual
+ // register has a single defining instruction.
+ //
+ // The TwoAddressInstructionPass and PHIElimination passes take the machine
+ // function out of SSA form when they introduce multiple defs per virtual
+ // register.
+ bool isSSA() const { return IsSSA; }
+
+ // leaveSSA - Indicates that the machine function is no longer in SSA form.
+ void leaveSSA() { IsSSA = false; }
+
+ /// tracksLiveness - Returns true when tracking register liveness accurately.
+ ///
+ /// While this flag is true, register liveness information in basic block
+ /// live-in lists and machine instruction operands is accurate. This means it
+ /// can be used to change the code in ways that affect the values in
+ /// registers, for example by the register scavenger.
+ ///
+ /// When this flag is false, liveness is no longer reliable.
+ bool tracksLiveness() const { return TracksLiveness; }
+
+ /// invalidateLiveness - Indicates that register liveness is no longer being
+ /// tracked accurately.
+ ///
+ /// This should be called by late passes that invalidate the liveness
+ /// information.
+ void invalidateLiveness() { TracksLiveness = false; }
+
+ //===--------------------------------------------------------------------===//
+ // Register Info
+ //===--------------------------------------------------------------------===//
+
+ /// 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.
+ template<bool Uses, bool Defs, bool SkipDebug>
+ class defusechain_iterator;
+
+ /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
+ /// register.
+ typedef defusechain_iterator<true,true,false> reg_iterator;
+ reg_iterator reg_begin(unsigned RegNo) const {
+ return reg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_iterator reg_end() { return reg_iterator(0); }
+
+ /// reg_empty - Return true if there are no instructions using or defining the
+ /// specified register (it may be live-in).
+ bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
+
+ /// reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses
+ /// of the specified register, skipping those marked as Debug.
+ typedef defusechain_iterator<true,true,true> reg_nodbg_iterator;
+ reg_nodbg_iterator reg_nodbg_begin(unsigned RegNo) const {
+ return reg_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_nodbg_iterator reg_nodbg_end() { return reg_nodbg_iterator(0); }
+
+ /// reg_nodbg_empty - Return true if the only instructions using or defining
+ /// Reg are Debug instructions.
+ bool reg_nodbg_empty(unsigned RegNo) const {
+ return reg_nodbg_begin(RegNo) == reg_nodbg_end();
+ }
+
+ /// def_iterator/def_begin/def_end - Walk all defs of the specified register.
+ typedef defusechain_iterator<false,true,false> def_iterator;
+ def_iterator def_begin(unsigned RegNo) const {
+ return def_iterator(getRegUseDefListHead(RegNo));
+ }
+ static def_iterator def_end() { return def_iterator(0); }
+
+ /// def_empty - Return true if there are no instructions defining the
+ /// specified register (it may be live-in).
+ bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
+
+ /// use_iterator/use_begin/use_end - Walk all uses of the specified register.
+ typedef defusechain_iterator<true,false,false> use_iterator;
+ use_iterator use_begin(unsigned RegNo) const {
+ return use_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_iterator use_end() { return use_iterator(0); }
+
+ /// use_empty - Return true if there are no instructions using the specified
+ /// register.
+ bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
+
+ /// hasOneUse - Return true if there is exactly one instruction using the
+ /// specified register.
+ bool hasOneUse(unsigned RegNo) const;
+
+ /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the
+ /// specified register, skipping those marked as Debug.
+ typedef defusechain_iterator<true,false,true> use_nodbg_iterator;
+ use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
+ return use_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_nodbg_iterator use_nodbg_end() { return use_nodbg_iterator(0); }
+
+ /// use_nodbg_empty - Return true if there are no non-Debug instructions
+ /// using the specified register.
+ bool use_nodbg_empty(unsigned RegNo) const {
+ return use_nodbg_begin(RegNo) == use_nodbg_end();
+ }
+
+ /// hasOneNonDBGUse - Return true if there is exactly one non-Debug
+ /// instruction using the specified register.
+ bool hasOneNonDBGUse(unsigned RegNo) const;
+
+ /// replaceRegWith - Replace all instances of FromReg with ToReg in the
+ /// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
+ /// except that it also changes any definitions of the register as well.
+ ///
+ /// Note that it is usually necessary to first constrain ToReg's register
+ /// class to match the FromReg constraints using:
+ ///
+ /// constrainRegClass(ToReg, getRegClass(FromReg))
+ ///
+ /// That function will return NULL if the virtual registers have incompatible
+ /// constraints.
+ void replaceRegWith(unsigned FromReg, unsigned ToReg);
+
+ /// getRegUseDefListHead - Return the head pointer for the register use/def
+ /// list for the specified virtual or physical register.
+ MachineOperand *&getRegUseDefListHead(unsigned RegNo) {
+ if (TargetRegisterInfo::isVirtualRegister(RegNo))
+ return VRegInfo[RegNo].second;
+ return PhysRegUseDefLists[RegNo];
+ }
+
+ MachineOperand *getRegUseDefListHead(unsigned RegNo) const {
+ if (TargetRegisterInfo::isVirtualRegister(RegNo))
+ return VRegInfo[RegNo].second;
+ return PhysRegUseDefLists[RegNo];
+ }
+
+ /// getVRegDef - Return the machine instr that defines the specified virtual
+ /// register or null if none is found. This assumes that the code is in SSA
+ /// form, so there should only be one definition.
+ MachineInstr *getVRegDef(unsigned Reg) const;
+
+ /// clearKillFlags - Iterate over all the uses of the given register and
+ /// clear the kill flag from the MachineOperand. This function is used by
+ /// optimization passes which extend register lifetimes and need only
+ /// preserve conservative kill flag information.
+ void clearKillFlags(unsigned Reg) const;
+
+#ifndef NDEBUG
+ void dumpUses(unsigned RegNo) const;
+#endif
+
+ /// isConstantPhysReg - Returns true if PhysReg is unallocatable and constant
+ /// throughout the function. It is safe to move instructions that read such
+ /// a physreg.
+ bool isConstantPhysReg(unsigned PhysReg, const MachineFunction &MF) const;
+
+ //===--------------------------------------------------------------------===//
+ // Virtual Register Info
+ //===--------------------------------------------------------------------===//
+
+ /// getRegClass - Return the register class of the specified virtual register.
+ ///
+ const TargetRegisterClass *getRegClass(unsigned Reg) const {
+ return VRegInfo[Reg].first;
+ }
+
+ /// setRegClass - Set the register class of the specified virtual register.
+ ///
+ void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
+
+ /// constrainRegClass - Constrain the register class of the specified virtual
+ /// register to be a common subclass of RC and the current register class,
+ /// but only if the new class has at least MinNumRegs registers. Return the
+ /// new register class, or NULL if no such class exists.
+ /// This should only be used when the constraint is known to be trivial, like
+ /// GR32 -> GR32_NOSP. Beware of increasing register pressure.
+ ///
+ const TargetRegisterClass *constrainRegClass(unsigned Reg,
+ const TargetRegisterClass *RC,
+ unsigned MinNumRegs = 0);
+
+ /// recomputeRegClass - Try to find a legal super-class of Reg's register
+ /// class that still satisfies the constraints from the instructions using
+ /// Reg. Returns true if Reg was upgraded.
+ ///
+ /// This method can be used after constraints have been removed from a
+ /// virtual register, for example after removing instructions or splitting
+ /// the live range.
+ ///
+ bool recomputeRegClass(unsigned Reg, const TargetMachine&);
+
+ /// createVirtualRegister - Create and return a new virtual register in the
+ /// function with the specified register class.
+ ///
+ unsigned createVirtualRegister(const TargetRegisterClass *RegClass);
+
+ /// getNumVirtRegs - Return the number of virtual registers created.
+ ///
+ unsigned getNumVirtRegs() const { return VRegInfo.size(); }
+
+ /// clearVirtRegs - Remove all virtual registers (after physreg assignment).
+ void clearVirtRegs();
+
+ /// setRegAllocationHint - Specify a register allocation hint for the
+ /// specified virtual register.
+ void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
+ RegAllocHints[Reg].first = Type;
+ RegAllocHints[Reg].second = PrefReg;
+ }
+
+ /// getRegAllocationHint - Return the register allocation hint for the
+ /// specified virtual register.
+ std::pair<unsigned, unsigned>
+ getRegAllocationHint(unsigned Reg) const {
+ return RegAllocHints[Reg];
+ }
+
+ /// getSimpleHint - Return the preferred register allocation hint, or 0 if a
+ /// standard simple hint (Type == 0) is not set.
+ unsigned getSimpleHint(unsigned Reg) const {
+ std::pair<unsigned, unsigned> Hint = getRegAllocationHint(Reg);
+ return Hint.first ? 0 : Hint.second;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Physical Register Use Info
+ //===--------------------------------------------------------------------===//
+
+ /// isPhysRegUsed - Return true if the specified register is used in this
+ /// function. This only works after register allocation.
+ 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 (const uint16_t *AI = TRI->getOverlaps(Reg); *AI; ++AI)
+ if (UsedPhysRegs.test(*AI))
+ 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; }
+
+ /// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
+ /// This corresponds to the bit mask attached to register mask operands.
+ void addPhysRegsUsedFromRegMask(const uint32_t *RegMask) {
+ UsedPhysRegMask.setBitsNotInMask(RegMask);
+ }
+
+ /// 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);
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Reserved Register Info
+ //===--------------------------------------------------------------------===//
+ //
+ // The set of reserved registers must be invariant during register
+ // allocation. For example, the target cannot suddenly decide it needs a
+ // frame pointer when the register allocator has already used the frame
+ // pointer register for something else.
+ //
+ // These methods can be used by target hooks like hasFP() to avoid changing
+ // the reserved register set during register allocation.
+
+ /// freezeReservedRegs - Called by the register allocator to freeze the set
+ /// of reserved registers before allocation begins.
+ void freezeReservedRegs(const MachineFunction&);
+
+ /// reservedRegsFrozen - Returns true after freezeReservedRegs() was called
+ /// to ensure the set of reserved registers stays constant.
+ bool reservedRegsFrozen() const {
+ return !ReservedRegs.empty();
+ }
+
+ /// canReserveReg - Returns true if PhysReg can be used as a reserved
+ /// register. Any register can be reserved before freezeReservedRegs() is
+ /// called.
+ bool canReserveReg(unsigned PhysReg) const {
+ return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // LiveIn/LiveOut Management
+ //===--------------------------------------------------------------------===//
+
+ /// addLiveIn/Out - Add the specified register as a live in/out. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg, unsigned vreg = 0) {
+ LiveIns.push_back(std::make_pair(Reg, vreg));
+ }
+ void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); }
+
+ // Iteration support for live in/out sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator
+ livein_iterator;
+ typedef std::vector<unsigned>::const_iterator liveout_iterator;
+ livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+ liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
+ liveout_iterator liveout_end() const { return LiveOuts.end(); }
+ bool liveout_empty() const { return LiveOuts.empty(); }
+
+ bool isLiveIn(unsigned Reg) const;
+ bool isLiveOut(unsigned Reg) const;
+
+ /// getLiveInPhysReg - If VReg is a live-in virtual register, return the
+ /// corresponding live-in physical register.
+ unsigned getLiveInPhysReg(unsigned VReg) const;
+
+ /// getLiveInVirtReg - If PReg is a live-in physical register, return the
+ /// corresponding live-in physical register.
+ unsigned getLiveInVirtReg(unsigned PReg) const;
+
+ /// EmitLiveInCopies - Emit copies to initialize livein virtual registers
+ /// into the given entry block.
+ void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
+ const TargetRegisterInfo &TRI,
+ const TargetInstrInfo &TII);
+
+private:
+ void HandleVRegListReallocation();
+
+public:
+ /// defusechain_iterator - This class provides iterator support for machine
+ /// operands in the function that use or define a specific register. If
+ /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it
+ /// returns defs. If neither are true then you are silly and it always
+ /// returns end(). If SkipDebug is true it skips uses marked Debug
+ /// when incrementing.
+ template<bool ReturnUses, bool ReturnDefs, bool SkipDebug>
+ class defusechain_iterator
+ : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
+ MachineOperand *Op;
+ explicit defusechain_iterator(MachineOperand *op) : Op(op) {
+ // If the first node isn't one we're interested in, advance to one that
+ // we are interested in.
+ if (op) {
+ if ((!ReturnUses && op->isUse()) ||
+ (!ReturnDefs && op->isDef()) ||
+ (SkipDebug && op->isDebug()))
+ ++*this;
+ }
+ }
+ friend class MachineRegisterInfo;
+ public:
+ typedef std::iterator<std::forward_iterator_tag,
+ MachineInstr, ptrdiff_t>::reference reference;
+ typedef std::iterator<std::forward_iterator_tag,
+ MachineInstr, ptrdiff_t>::pointer pointer;
+
+ defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {}
+ defusechain_iterator() : Op(0) {}
+
+ bool operator==(const defusechain_iterator &x) const {
+ return Op == x.Op;
+ }
+ bool operator!=(const defusechain_iterator &x) const {
+ return !operator==(x);
+ }
+
+ /// atEnd - return true if this iterator is equal to reg_end() on the value.
+ bool atEnd() const { return Op == 0; }
+
+ // Iterator traversal: forward iteration only
+ defusechain_iterator &operator++() { // Preincrement
+ assert(Op && "Cannot increment end iterator!");
+ Op = Op->getNextOperandForReg();
+
+ // If this is an operand we don't care about, skip it.
+ while (Op && ((!ReturnUses && Op->isUse()) ||
+ (!ReturnDefs && Op->isDef()) ||
+ (SkipDebug && Op->isDebug())))
+ Op = Op->getNextOperandForReg();
+
+ return *this;
+ }
+ defusechain_iterator operator++(int) { // Postincrement
+ defusechain_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ /// skipInstruction - move forward until reaching a different instruction.
+ /// Return the skipped instruction that is no longer pointed to, or NULL if
+ /// already pointing to end().
+ MachineInstr *skipInstruction() {
+ if (!Op) return 0;
+ MachineInstr *MI = Op->getParent();
+ do ++*this;
+ while (Op && Op->getParent() == MI);
+ return MI;
+ }
+
+ MachineInstr *skipBundle() {
+ if (!Op) return 0;
+ MachineInstr *MI = getBundleStart(Op->getParent());
+ do ++*this;
+ while (Op && getBundleStart(Op->getParent()) == MI);
+ return MI;
+ }
+
+ MachineOperand &getOperand() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return *Op;
+ }
+
+ /// getOperandNo - Return the operand # of this MachineOperand in its
+ /// MachineInstr.
+ unsigned getOperandNo() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return Op - &Op->getParent()->getOperand(0);
+ }
+
+ // Retrieve a reference to the current operand.
+ MachineInstr &operator*() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return *Op->getParent();
+ }
+
+ MachineInstr *operator->() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return Op->getParent();
+ }
+ };
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineRelocation.h b/contrib/llvm/include/llvm/CodeGen/MachineRelocation.h
new file mode 100644
index 000000000000..244b466e1728
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineRelocation.h
@@ -0,0 +1,342 @@
+//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- 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 MachineRelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
+#define LLVM_CODEGEN_MACHINERELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class GlobalValue;
+class MachineBasicBlock;
+
+/// MachineRelocation - This represents a target-specific relocation value,
+/// produced by the code emitter. This relocation is resolved after the has
+/// been emitted, either to an object file or to memory, when the target of the
+/// relocation can be resolved.
+///
+/// A relocation is made up of the following logical portions:
+/// 1. An offset in the machine code buffer, the location to modify.
+/// 2. A target specific relocation type (a number from 0 to 63).
+/// 3. A symbol being referenced, either as a GlobalValue* or as a string.
+/// 4. An optional constant value to be added to the reference.
+/// 5. A bit, CanRewrite, which indicates to the JIT that a function stub is
+/// not needed for the relocation.
+/// 6. An index into the GOT, if the target uses a GOT
+///
+class MachineRelocation {
+ enum AddressType {
+ isResult, // Relocation has be transformed into its result pointer.
+ isGV, // The Target.GV field is valid.
+ isIndirectSym, // Relocation of an indirect symbol.
+ isBB, // Relocation of BB address.
+ isExtSym, // The Target.ExtSym field is valid.
+ isConstPool, // Relocation of constant pool address.
+ isJumpTable, // Relocation of jump table address.
+ isGOTIndex // The Target.GOTIndex field is valid.
+ };
+
+ /// Offset - This is the offset from the start of the code buffer of the
+ /// relocation to perform.
+ uintptr_t Offset;
+
+ /// ConstantVal - A field that may be used by the target relocation type.
+ intptr_t ConstantVal;
+
+ union {
+ void *Result; // If this has been resolved to a resolved pointer
+ GlobalValue *GV; // If this is a pointer to a GV or an indirect ref.
+ MachineBasicBlock *MBB; // If this is a pointer to a LLVM BB
+ const char *ExtSym; // If this is a pointer to a named symbol
+ unsigned Index; // Constant pool / jump table index
+ unsigned GOTIndex; // Index in the GOT of this symbol/global
+ } Target;
+
+ unsigned TargetReloType : 6; // The target relocation ID
+ AddressType AddrType : 4; // The field of Target to use
+ bool MayNeedFarStub : 1; // True if this relocation may require a far-stub
+ bool GOTRelative : 1; // Should this relocation be relative to the GOT?
+ bool TargetResolve : 1; // True if target should resolve the address
+
+public:
+ // Relocation types used in a generic implementation. Currently, relocation
+ // entries for all things use the generic VANILLA type until they are refined
+ // into target relocation types.
+ enum RelocationType {
+ VANILLA
+ };
+
+ /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
+ ///
+ static MachineRelocation getGV(uintptr_t offset, unsigned RelocationType,
+ GlobalValue *GV, intptr_t cst = 0,
+ bool MayNeedFarStub = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isGV;
+ Result.MayNeedFarStub = MayNeedFarStub;
+ Result.GOTRelative = GOTrelative;
+ Result.TargetResolve = false;
+ Result.Target.GV = GV;
+ return Result;
+ }
+
+ /// MachineRelocation::getIndirectSymbol - Return a relocation entry for an
+ /// indirect symbol.
+ static MachineRelocation getIndirectSymbol(uintptr_t offset,
+ unsigned RelocationType,
+ GlobalValue *GV, intptr_t cst = 0,
+ bool MayNeedFarStub = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isIndirectSym;
+ Result.MayNeedFarStub = MayNeedFarStub;
+ Result.GOTRelative = GOTrelative;
+ Result.TargetResolve = false;
+ Result.Target.GV = GV;
+ return Result;
+ }
+
+ /// MachineRelocation::getBB - Return a relocation entry for a BB.
+ ///
+ static MachineRelocation getBB(uintptr_t offset,unsigned RelocationType,
+ MachineBasicBlock *MBB, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isBB;
+ Result.MayNeedFarStub = false;
+ Result.GOTRelative = false;
+ Result.TargetResolve = false;
+ Result.Target.MBB = MBB;
+ return Result;
+ }
+
+ /// MachineRelocation::getExtSym - Return a relocation entry for an external
+ /// symbol, like "free".
+ ///
+ static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType,
+ const char *ES, intptr_t cst = 0,
+ bool GOTrelative = 0,
+ bool NeedStub = true) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isExtSym;
+ Result.MayNeedFarStub = NeedStub;
+ Result.GOTRelative = GOTrelative;
+ Result.TargetResolve = false;
+ Result.Target.ExtSym = ES;
+ return Result;
+ }
+
+ /// MachineRelocation::getConstPool - Return a relocation entry for a constant
+ /// pool entry.
+ ///
+ static MachineRelocation getConstPool(uintptr_t offset,unsigned RelocationType,
+ unsigned CPI, intptr_t cst = 0,
+ bool letTargetResolve = false) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isConstPool;
+ Result.MayNeedFarStub = false;
+ Result.GOTRelative = false;
+ Result.TargetResolve = letTargetResolve;
+ Result.Target.Index = CPI;
+ return Result;
+ }
+
+ /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
+ /// table entry.
+ ///
+ static MachineRelocation getJumpTable(uintptr_t offset,unsigned RelocationType,
+ unsigned JTI, intptr_t cst = 0,
+ bool letTargetResolve = false) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isJumpTable;
+ Result.MayNeedFarStub = false;
+ Result.GOTRelative = false;
+ Result.TargetResolve = letTargetResolve;
+ Result.Target.Index = JTI;
+ return Result;
+ }
+
+ /// getMachineCodeOffset - Return the offset into the code buffer that the
+ /// relocation should be performed.
+ intptr_t getMachineCodeOffset() const {
+ return Offset;
+ }
+
+ /// getRelocationType - Return the target-specific relocation ID for this
+ /// relocation.
+ unsigned getRelocationType() const {
+ return TargetReloType;
+ }
+
+ /// getConstantVal - Get the constant value associated with this relocation.
+ /// This is often an offset from the symbol.
+ ///
+ intptr_t getConstantVal() const {
+ return ConstantVal;
+ }
+
+ /// setConstantVal - Set the constant value associated with this relocation.
+ /// This is often an offset from the symbol.
+ ///
+ void setConstantVal(intptr_t val) {
+ ConstantVal = val;
+ }
+
+ /// isGlobalValue - Return true if this relocation is a GlobalValue, as
+ /// opposed to a constant string.
+ bool isGlobalValue() const {
+ return AddrType == isGV;
+ }
+
+ /// isIndirectSymbol - Return true if this relocation is the address an
+ /// indirect symbol
+ bool isIndirectSymbol() const {
+ return AddrType == isIndirectSym;
+ }
+
+ /// isBasicBlock - Return true if this relocation is a basic block reference.
+ ///
+ bool isBasicBlock() const {
+ return AddrType == isBB;
+ }
+
+ /// isExternalSymbol - Return true if this is a constant string.
+ ///
+ bool isExternalSymbol() const {
+ return AddrType == isExtSym;
+ }
+
+ /// isConstantPoolIndex - Return true if this is a constant pool reference.
+ ///
+ bool isConstantPoolIndex() const {
+ return AddrType == isConstPool;
+ }
+
+ /// isJumpTableIndex - Return true if this is a jump table reference.
+ ///
+ bool isJumpTableIndex() const {
+ return AddrType == isJumpTable;
+ }
+
+ /// isGOTRelative - Return true the target wants the index into the GOT of
+ /// the symbol rather than the address of the symbol.
+ bool isGOTRelative() const {
+ return GOTRelative;
+ }
+
+ /// mayNeedFarStub - This function returns true if the JIT for this target may
+ /// need either a stub function or an indirect global-variable load to handle
+ /// the relocated GlobalValue reference. For example, the x86-64 call
+ /// instruction can only call functions within +/-2GB of the call site.
+ /// Anything farther away needs a longer mov+call sequence, which can't just
+ /// be written on top of the existing call.
+ bool mayNeedFarStub() const {
+ return MayNeedFarStub;
+ }
+
+ /// letTargetResolve - Return true if the target JITInfo is usually
+ /// responsible for resolving the address of this relocation.
+ bool letTargetResolve() const {
+ return TargetResolve;
+ }
+
+ /// getGlobalValue - If this is a global value reference, return the
+ /// referenced global.
+ GlobalValue *getGlobalValue() const {
+ assert((isGlobalValue() || isIndirectSymbol()) &&
+ "This is not a global value reference!");
+ return Target.GV;
+ }
+
+ MachineBasicBlock *getBasicBlock() const {
+ assert(isBasicBlock() && "This is not a basic block reference!");
+ return Target.MBB;
+ }
+
+ /// getString - If this is a string value, return the string reference.
+ ///
+ const char *getExternalSymbol() const {
+ assert(isExternalSymbol() && "This is not an external symbol reference!");
+ return Target.ExtSym;
+ }
+
+ /// getConstantPoolIndex - If this is a const pool reference, return
+ /// the index into the constant pool.
+ unsigned getConstantPoolIndex() const {
+ assert(isConstantPoolIndex() && "This is not a constant pool reference!");
+ return Target.Index;
+ }
+
+ /// getJumpTableIndex - If this is a jump table reference, return
+ /// the index into the jump table.
+ unsigned getJumpTableIndex() const {
+ assert(isJumpTableIndex() && "This is not a jump table reference!");
+ return Target.Index;
+ }
+
+ /// getResultPointer - Once this has been resolved to point to an actual
+ /// address, this returns the pointer.
+ void *getResultPointer() const {
+ assert(AddrType == isResult && "Result pointer isn't set yet!");
+ return Target.Result;
+ }
+
+ /// setResultPointer - Set the result to the specified pointer value.
+ ///
+ void setResultPointer(void *Ptr) {
+ Target.Result = Ptr;
+ AddrType = isResult;
+ }
+
+ /// setGOTIndex - Set the GOT index to a specific value.
+ void setGOTIndex(unsigned idx) {
+ AddrType = isGOTIndex;
+ Target.GOTIndex = idx;
+ }
+
+ /// getGOTIndex - Once this has been resolved to an entry in the GOT,
+ /// this returns that index. The index is from the lowest address entry
+ /// in the GOT.
+ unsigned getGOTIndex() const {
+ assert(AddrType == isGOTIndex);
+ return Target.GOTIndex;
+ }
+};
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineSSAUpdater.h b/contrib/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
new file mode 100644
index 000000000000..cbb45a71275c
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -0,0 +1,115 @@
+//===-- MachineSSAUpdater.h - Unstructured SSA Update Tool ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MachineSSAUpdater class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H
+#define LLVM_CODEGEN_MACHINESSAUPDATER_H
+
+namespace llvm {
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class MachineOperand;
+ class MachineRegisterInfo;
+ class TargetInstrInfo;
+ class TargetRegisterClass;
+ template<typename T> class SmallVectorImpl;
+ template<typename T> class SSAUpdaterTraits;
+ class BumpPtrAllocator;
+
+/// MachineSSAUpdater - This class updates SSA form for a set of virtual
+/// registers defined in multiple blocks. This is used when code duplication
+/// or another unstructured transformation wants to rewrite a set of uses of one
+/// vreg with uses of a set of vregs.
+class MachineSSAUpdater {
+ friend class SSAUpdaterTraits<MachineSSAUpdater>;
+
+private:
+ /// AvailableVals - This keeps track of which value to use on a per-block
+ /// basis. When we insert PHI nodes, we keep track of them here.
+ //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
+ void *AV;
+
+ /// VR - Current virtual register whose uses are being updated.
+ unsigned VR;
+
+ /// VRC - Register class of the current virtual register.
+ const TargetRegisterClass *VRC;
+
+ /// InsertedPHIs - If this is non-null, the MachineSSAUpdater adds all PHI
+ /// nodes that it creates to the vector.
+ SmallVectorImpl<MachineInstr*> *InsertedPHIs;
+
+ const TargetInstrInfo *TII;
+ MachineRegisterInfo *MRI;
+public:
+ /// MachineSSAUpdater constructor. If InsertedPHIs is specified, it will be
+ /// filled in with all PHI Nodes created by rewriting.
+ explicit MachineSSAUpdater(MachineFunction &MF,
+ SmallVectorImpl<MachineInstr*> *InsertedPHIs = 0);
+ ~MachineSSAUpdater();
+
+ /// Initialize - Reset this object to get ready for a new set of SSA
+ /// updates.
+ void Initialize(unsigned V);
+
+ /// AddAvailableValue - Indicate that a rewritten value is available at the
+ /// end of the specified block with the specified value.
+ void AddAvailableValue(MachineBasicBlock *BB, unsigned V);
+
+ /// HasValueForBlock - Return true if the MachineSSAUpdater already has a
+ /// value for the specified block.
+ bool HasValueForBlock(MachineBasicBlock *BB) const;
+
+ /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
+ /// live at the end of the specified block.
+ unsigned GetValueAtEndOfBlock(MachineBasicBlock *BB);
+
+ /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
+ /// is live in the middle of the specified block.
+ ///
+ /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
+ /// important case: if there is a definition of the rewritten value after the
+ /// 'use' in BB. Consider code like this:
+ ///
+ /// X1 = ...
+ /// SomeBB:
+ /// use(X)
+ /// X2 = ...
+ /// br Cond, SomeBB, OutBB
+ ///
+ /// In this case, there are two values (X1 and X2) added to the AvailableVals
+ /// set by the client of the rewriter, and those values are both live out of
+ /// their respective blocks. However, the use of X happens in the *middle* of
+ /// a block. Because of this, we need to insert a new PHI node in SomeBB to
+ /// merge the appropriate values, and this value isn't live out of the block.
+ ///
+ unsigned GetValueInMiddleOfBlock(MachineBasicBlock *BB);
+
+ /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
+ /// which use their value in the corresponding predecessor. Note that this
+ /// will not work if the use is supposed to be rewritten to a value defined in
+ /// the same block as the use, but above it. Any 'AddAvailableValue's added
+ /// for the use's block will be considered to be below it.
+ void RewriteUse(MachineOperand &U);
+
+private:
+ void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
+ unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
+
+ void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT
+ MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h
new file mode 100644
index 000000000000..e852009f7e8b
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -0,0 +1,91 @@
+//==- MachineScheduler.h - MachineInstr Scheduling Pass ----------*- 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 MachineSchedRegistry for registering alternative machine
+// schedulers. A Target may provide an alternative scheduler implementation by
+// implementing the following boilerplate:
+//
+// static ScheduleDAGInstrs *createCustomMachineSched(MachineSchedContext *C) {
+// return new CustomMachineScheduler(C);
+// }
+// static MachineSchedRegistry
+// SchedCustomRegistry("custom", "Run my target's custom scheduler",
+// createCustomMachineSched);
+//
+// Inside <Target>PassConfig:
+// enablePass(MachineSchedulerID);
+// MachineSchedRegistry::setDefault(createCustomMachineSched);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MACHINESCHEDULER_H
+#define MACHINESCHEDULER_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class LiveIntervals;
+class MachineDominatorTree;
+class MachineLoopInfo;
+class ScheduleDAGInstrs;
+
+/// MachineSchedContext provides enough context from the MachineScheduler pass
+/// for the target to instantiate a scheduler.
+struct MachineSchedContext {
+ MachineFunction *MF;
+ const MachineLoopInfo *MLI;
+ const MachineDominatorTree *MDT;
+ const TargetPassConfig *PassConfig;
+ AliasAnalysis *AA;
+ LiveIntervals *LIS;
+
+ MachineSchedContext(): MF(0), MLI(0), MDT(0), PassConfig(0), AA(0), LIS(0) {}
+};
+
+/// MachineSchedRegistry provides a selection of available machine instruction
+/// schedulers.
+class MachineSchedRegistry : public MachinePassRegistryNode {
+public:
+ typedef ScheduleDAGInstrs *(*ScheduleDAGCtor)(MachineSchedContext *);
+
+ // RegisterPassParser requires a (misnamed) FunctionPassCtor type.
+ typedef ScheduleDAGCtor FunctionPassCtor;
+
+ static MachinePassRegistry Registry;
+
+ MachineSchedRegistry(const char *N, const char *D, ScheduleDAGCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C) {
+ Registry.Add(this);
+ }
+ ~MachineSchedRegistry() { Registry.Remove(this); }
+
+ // Accessors.
+ //
+ MachineSchedRegistry *getNext() const {
+ return (MachineSchedRegistry *)MachinePassRegistryNode::getNext();
+ }
+ static MachineSchedRegistry *getList() {
+ return (MachineSchedRegistry *)Registry.getList();
+ }
+ static ScheduleDAGCtor getDefault() {
+ return (ScheduleDAGCtor)Registry.getDefault();
+ }
+ static void setDefault(ScheduleDAGCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h
new file mode 100644
index 000000000000..a5d8b0dbd6a7
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Graph.h
@@ -0,0 +1,461 @@
+//===-------------------- Graph.h - PBQP Graph ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// PBQP Graph class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_PBQP_GRAPH_H
+#define LLVM_CODEGEN_PBQP_GRAPH_H
+
+#include "Math.h"
+
+#include <list>
+#include <map>
+
+namespace PBQP {
+
+ /// PBQP Graph class.
+ /// Instances of this class describe PBQP problems.
+ class Graph {
+ private:
+
+ // ----- TYPEDEFS -----
+ class NodeEntry;
+ class EdgeEntry;
+
+ typedef std::list<NodeEntry> NodeList;
+ typedef std::list<EdgeEntry> EdgeList;
+
+ public:
+
+ typedef NodeList::iterator NodeItr;
+ typedef NodeList::const_iterator ConstNodeItr;
+
+ typedef EdgeList::iterator EdgeItr;
+ typedef EdgeList::const_iterator ConstEdgeItr;
+
+ private:
+
+ typedef std::list<EdgeItr> AdjEdgeList;
+
+ public:
+
+ typedef AdjEdgeList::iterator AdjEdgeItr;
+
+ private:
+
+ class NodeEntry {
+ private:
+ Vector costs;
+ AdjEdgeList adjEdges;
+ unsigned degree;
+ void *data;
+ public:
+ NodeEntry(const Vector &costs) : costs(costs), degree(0) {}
+ Vector& getCosts() { return costs; }
+ const Vector& getCosts() const { return costs; }
+ unsigned getDegree() const { return degree; }
+ AdjEdgeItr edgesBegin() { return adjEdges.begin(); }
+ AdjEdgeItr edgesEnd() { return adjEdges.end(); }
+ AdjEdgeItr addEdge(EdgeItr e) {
+ ++degree;
+ return adjEdges.insert(adjEdges.end(), e);
+ }
+ void removeEdge(AdjEdgeItr ae) {
+ --degree;
+ adjEdges.erase(ae);
+ }
+ void setData(void *data) { this->data = data; }
+ void* getData() { return data; }
+ };
+
+ class EdgeEntry {
+ private:
+ NodeItr node1, node2;
+ Matrix costs;
+ AdjEdgeItr node1AEItr, node2AEItr;
+ void *data;
+ public:
+ EdgeEntry(NodeItr node1, NodeItr node2, const Matrix &costs)
+ : node1(node1), node2(node2), costs(costs) {}
+ NodeItr getNode1() const { return node1; }
+ NodeItr getNode2() const { return node2; }
+ Matrix& getCosts() { return costs; }
+ const Matrix& getCosts() const { return costs; }
+ void setNode1AEItr(AdjEdgeItr ae) { node1AEItr = ae; }
+ AdjEdgeItr getNode1AEItr() { return node1AEItr; }
+ void setNode2AEItr(AdjEdgeItr ae) { node2AEItr = ae; }
+ AdjEdgeItr getNode2AEItr() { return node2AEItr; }
+ void setData(void *data) { this->data = data; }
+ void *getData() { return data; }
+ };
+
+ // ----- MEMBERS -----
+
+ NodeList nodes;
+ unsigned numNodes;
+
+ EdgeList edges;
+ unsigned numEdges;
+
+ // ----- INTERNAL METHODS -----
+
+ NodeEntry& getNode(NodeItr nItr) { return *nItr; }
+ const NodeEntry& getNode(ConstNodeItr nItr) const { return *nItr; }
+
+ EdgeEntry& getEdge(EdgeItr eItr) { return *eItr; }
+ const EdgeEntry& getEdge(ConstEdgeItr eItr) const { return *eItr; }
+
+ NodeItr addConstructedNode(const NodeEntry &n) {
+ ++numNodes;
+ return nodes.insert(nodes.end(), n);
+ }
+
+ EdgeItr addConstructedEdge(const EdgeEntry &e) {
+ assert(findEdge(e.getNode1(), e.getNode2()) == edges.end() &&
+ "Attempt to add duplicate edge.");
+ ++numEdges;
+ EdgeItr edgeItr = edges.insert(edges.end(), e);
+ EdgeEntry &ne = getEdge(edgeItr);
+ NodeEntry &n1 = getNode(ne.getNode1());
+ NodeEntry &n2 = getNode(ne.getNode2());
+ // Sanity check on matrix dimensions:
+ assert((n1.getCosts().getLength() == ne.getCosts().getRows()) &&
+ (n2.getCosts().getLength() == ne.getCosts().getCols()) &&
+ "Edge cost dimensions do not match node costs dimensions.");
+ ne.setNode1AEItr(n1.addEdge(edgeItr));
+ ne.setNode2AEItr(n2.addEdge(edgeItr));
+ return edgeItr;
+ }
+
+ inline void copyFrom(const Graph &other);
+ public:
+
+ /// \brief Construct an empty PBQP graph.
+ Graph() : numNodes(0), numEdges(0) {}
+
+ /// \brief Copy construct this graph from "other". Note: Does not copy node
+ /// and edge data, only graph structure and costs.
+ /// @param other Source graph to copy from.
+ Graph(const Graph &other) : numNodes(0), numEdges(0) {
+ copyFrom(other);
+ }
+
+ /// \brief Make this graph a copy of "other". Note: Does not copy node and
+ /// edge data, only graph structure and costs.
+ /// @param other The graph to copy from.
+ /// @return A reference to this graph.
+ ///
+ /// This will clear the current graph, erasing any nodes and edges added,
+ /// before copying from other.
+ Graph& operator=(const Graph &other) {
+ clear();
+ copyFrom(other);
+ return *this;
+ }
+
+ /// \brief Add a node with the given costs.
+ /// @param costs Cost vector for the new node.
+ /// @return Node iterator for the added node.
+ NodeItr addNode(const Vector &costs) {
+ return addConstructedNode(NodeEntry(costs));
+ }
+
+ /// \brief Add an edge between the given nodes with the given costs.
+ /// @param n1Itr First node.
+ /// @param n2Itr Second node.
+ /// @return Edge iterator for the added edge.
+ EdgeItr addEdge(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr,
+ const Matrix &costs) {
+ assert(getNodeCosts(n1Itr).getLength() == costs.getRows() &&
+ getNodeCosts(n2Itr).getLength() == costs.getCols() &&
+ "Matrix dimensions mismatch.");
+ return addConstructedEdge(EdgeEntry(n1Itr, n2Itr, costs));
+ }
+
+ /// \brief Get the number of nodes in the graph.
+ /// @return Number of nodes in the graph.
+ unsigned getNumNodes() const { return numNodes; }
+
+ /// \brief Get the number of edges in the graph.
+ /// @return Number of edges in the graph.
+ unsigned getNumEdges() const { return numEdges; }
+
+ /// \brief Get a node's cost vector.
+ /// @param nItr Node iterator.
+ /// @return Node cost vector.
+ Vector& getNodeCosts(NodeItr nItr) { return getNode(nItr).getCosts(); }
+
+ /// \brief Get a node's cost vector (const version).
+ /// @param nItr Node iterator.
+ /// @return Node cost vector.
+ const Vector& getNodeCosts(ConstNodeItr nItr) const {
+ return getNode(nItr).getCosts();
+ }
+
+ /// \brief Set a node's data pointer.
+ /// @param nItr Node iterator.
+ /// @param data Pointer to node data.
+ ///
+ /// Typically used by a PBQP solver to attach data to aid in solution.
+ void setNodeData(NodeItr nItr, void *data) { getNode(nItr).setData(data); }
+
+ /// \brief Get the node's data pointer.
+ /// @param nItr Node iterator.
+ /// @return Pointer to node data.
+ void* getNodeData(NodeItr nItr) { return getNode(nItr).getData(); }
+
+ /// \brief Get an edge's cost matrix.
+ /// @param eItr Edge iterator.
+ /// @return Edge cost matrix.
+ Matrix& getEdgeCosts(EdgeItr eItr) { return getEdge(eItr).getCosts(); }
+
+ /// \brief Get an edge's cost matrix (const version).
+ /// @param eItr Edge iterator.
+ /// @return Edge cost matrix.
+ const Matrix& getEdgeCosts(ConstEdgeItr eItr) const {
+ return getEdge(eItr).getCosts();
+ }
+
+ /// \brief Set an edge's data pointer.
+ /// @param eItr Edge iterator.
+ /// @param data Pointer to edge data.
+ ///
+ /// Typically used by a PBQP solver to attach data to aid in solution.
+ void setEdgeData(EdgeItr eItr, void *data) { getEdge(eItr).setData(data); }
+
+ /// \brief Get an edge's data pointer.
+ /// @param eItr Edge iterator.
+ /// @return Pointer to edge data.
+ void* getEdgeData(EdgeItr eItr) { return getEdge(eItr).getData(); }
+
+ /// \brief Get a node's degree.
+ /// @param nItr Node iterator.
+ /// @return The degree of the node.
+ unsigned getNodeDegree(NodeItr nItr) const {
+ return getNode(nItr).getDegree();
+ }
+
+ /// \brief Begin iterator for node set.
+ NodeItr nodesBegin() { return nodes.begin(); }
+
+ /// \brief Begin const iterator for node set.
+ ConstNodeItr nodesBegin() const { return nodes.begin(); }
+
+ /// \brief End iterator for node set.
+ NodeItr nodesEnd() { return nodes.end(); }
+
+ /// \brief End const iterator for node set.
+ ConstNodeItr nodesEnd() const { return nodes.end(); }
+
+ /// \brief Begin iterator for edge set.
+ EdgeItr edgesBegin() { return edges.begin(); }
+
+ /// \brief End iterator for edge set.
+ EdgeItr edgesEnd() { return edges.end(); }
+
+ /// \brief Get begin iterator for adjacent edge set.
+ /// @param nItr Node iterator.
+ /// @return Begin iterator for the set of edges connected to the given node.
+ AdjEdgeItr adjEdgesBegin(NodeItr nItr) {
+ return getNode(nItr).edgesBegin();
+ }
+
+ /// \brief Get end iterator for adjacent edge set.
+ /// @param nItr Node iterator.
+ /// @return End iterator for the set of edges connected to the given node.
+ AdjEdgeItr adjEdgesEnd(NodeItr nItr) {
+ return getNode(nItr).edgesEnd();
+ }
+
+ /// \brief Get the first node connected to this edge.
+ /// @param eItr Edge iterator.
+ /// @return The first node connected to the given edge.
+ NodeItr getEdgeNode1(EdgeItr eItr) {
+ return getEdge(eItr).getNode1();
+ }
+
+ /// \brief Get the second node connected to this edge.
+ /// @param eItr Edge iterator.
+ /// @return The second node connected to the given edge.
+ NodeItr getEdgeNode2(EdgeItr eItr) {
+ return getEdge(eItr).getNode2();
+ }
+
+ /// \brief Get the "other" node connected to this edge.
+ /// @param eItr Edge iterator.
+ /// @param nItr Node iterator for the "given" node.
+ /// @return The iterator for the "other" node connected to this edge.
+ NodeItr getEdgeOtherNode(EdgeItr eItr, NodeItr nItr) {
+ EdgeEntry &e = getEdge(eItr);
+ if (e.getNode1() == nItr) {
+ return e.getNode2();
+ } // else
+ return e.getNode1();
+ }
+
+ /// \brief Get the edge connecting two nodes.
+ /// @param n1Itr First node iterator.
+ /// @param n2Itr Second node iterator.
+ /// @return An iterator for edge (n1Itr, n2Itr) if such an edge exists,
+ /// otherwise returns edgesEnd().
+ EdgeItr findEdge(NodeItr n1Itr, NodeItr n2Itr) {
+ for (AdjEdgeItr aeItr = adjEdgesBegin(n1Itr), aeEnd = adjEdgesEnd(n1Itr);
+ aeItr != aeEnd; ++aeItr) {
+ if ((getEdgeNode1(*aeItr) == n2Itr) ||
+ (getEdgeNode2(*aeItr) == n2Itr)) {
+ return *aeItr;
+ }
+ }
+ return edges.end();
+ }
+
+ /// \brief Remove a node from the graph.
+ /// @param nItr Node iterator.
+ void removeNode(NodeItr nItr) {
+ NodeEntry &n = getNode(nItr);
+ for (AdjEdgeItr itr = n.edgesBegin(), end = n.edgesEnd(); itr != end;) {
+ EdgeItr eItr = *itr;
+ ++itr;
+ removeEdge(eItr);
+ }
+ nodes.erase(nItr);
+ --numNodes;
+ }
+
+ /// \brief Remove an edge from the graph.
+ /// @param eItr Edge iterator.
+ void removeEdge(EdgeItr eItr) {
+ EdgeEntry &e = getEdge(eItr);
+ NodeEntry &n1 = getNode(e.getNode1());
+ NodeEntry &n2 = getNode(e.getNode2());
+ n1.removeEdge(e.getNode1AEItr());
+ n2.removeEdge(e.getNode2AEItr());
+ edges.erase(eItr);
+ --numEdges;
+ }
+
+ /// \brief Remove all nodes and edges from the graph.
+ void clear() {
+ nodes.clear();
+ edges.clear();
+ numNodes = numEdges = 0;
+ }
+
+ /// \brief Dump a graph to an output stream.
+ template <typename OStream>
+ void dump(OStream &os) {
+ os << getNumNodes() << " " << getNumEdges() << "\n";
+
+ for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
+ nodeItr != nodeEnd; ++nodeItr) {
+ const Vector& v = getNodeCosts(nodeItr);
+ os << "\n" << v.getLength() << "\n";
+ assert(v.getLength() != 0 && "Empty vector in graph.");
+ os << v[0];
+ for (unsigned i = 1; i < v.getLength(); ++i) {
+ os << " " << v[i];
+ }
+ os << "\n";
+ }
+
+ for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
+ edgeItr != edgeEnd; ++edgeItr) {
+ unsigned n1 = std::distance(nodesBegin(), getEdgeNode1(edgeItr));
+ unsigned n2 = std::distance(nodesBegin(), getEdgeNode2(edgeItr));
+ assert(n1 != n2 && "PBQP graphs shound not have self-edges.");
+ const Matrix& m = getEdgeCosts(edgeItr);
+ os << "\n" << n1 << " " << n2 << "\n"
+ << m.getRows() << " " << m.getCols() << "\n";
+ assert(m.getRows() != 0 && "No rows in matrix.");
+ assert(m.getCols() != 0 && "No cols in matrix.");
+ for (unsigned i = 0; i < m.getRows(); ++i) {
+ os << m[i][0];
+ for (unsigned j = 1; j < m.getCols(); ++j) {
+ os << " " << m[i][j];
+ }
+ os << "\n";
+ }
+ }
+ }
+
+ /// \brief Print a representation of this graph in DOT format.
+ /// @param os Output stream to print on.
+ template <typename OStream>
+ void printDot(OStream &os) {
+
+ os << "graph {\n";
+
+ for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
+ nodeItr != nodeEnd; ++nodeItr) {
+
+ os << " node" << nodeItr << " [ label=\""
+ << nodeItr << ": " << getNodeCosts(nodeItr) << "\" ]\n";
+ }
+
+ os << " edge [ len=" << getNumNodes() << " ]\n";
+
+ for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
+ edgeItr != edgeEnd; ++edgeItr) {
+
+ os << " node" << getEdgeNode1(edgeItr)
+ << " -- node" << getEdgeNode2(edgeItr)
+ << " [ label=\"";
+
+ const Matrix &edgeCosts = getEdgeCosts(edgeItr);
+
+ for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
+ os << edgeCosts.getRowAsVector(i) << "\\n";
+ }
+ os << "\" ]\n";
+ }
+ os << "}\n";
+ }
+
+ };
+
+ class NodeItrComparator {
+ public:
+ bool operator()(Graph::NodeItr n1, Graph::NodeItr n2) const {
+ return &*n1 < &*n2;
+ }
+
+ bool operator()(Graph::ConstNodeItr n1, Graph::ConstNodeItr n2) const {
+ return &*n1 < &*n2;
+ }
+ };
+
+ class EdgeItrCompartor {
+ public:
+ bool operator()(Graph::EdgeItr e1, Graph::EdgeItr e2) const {
+ return &*e1 < &*e2;
+ }
+
+ bool operator()(Graph::ConstEdgeItr e1, Graph::ConstEdgeItr e2) const {
+ return &*e1 < &*e2;
+ }
+ };
+
+ void Graph::copyFrom(const Graph &other) {
+ std::map<Graph::ConstNodeItr, Graph::NodeItr,
+ NodeItrComparator> nodeMap;
+
+ for (Graph::ConstNodeItr nItr = other.nodesBegin(),
+ nEnd = other.nodesEnd();
+ nItr != nEnd; ++nItr) {
+ nodeMap[nItr] = addNode(other.getNodeCosts(nItr));
+ }
+
+ }
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_GRAPH_HPP
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicBase.h b/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicBase.h
new file mode 100644
index 000000000000..3fee18cc42d9
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicBase.h
@@ -0,0 +1,246 @@
+//===-- HeuristcBase.h --- Heuristic base class for PBQP --------*- 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_PBQP_HEURISTICBASE_H
+#define LLVM_CODEGEN_PBQP_HEURISTICBASE_H
+
+#include "HeuristicSolver.h"
+
+namespace PBQP {
+
+ /// \brief Abstract base class for heuristic implementations.
+ ///
+ /// This class provides a handy base for heuristic implementations with common
+ /// solver behaviour implemented for a number of methods.
+ ///
+ /// To implement your own heuristic using this class as a base you'll have to
+ /// implement, as a minimum, the following methods:
+ /// <ul>
+ /// <li> void addToHeuristicList(Graph::NodeItr) : Add a node to the
+ /// heuristic reduction list.
+ /// <li> void heuristicReduce() : Perform a single heuristic reduction.
+ /// <li> void preUpdateEdgeCosts(Graph::EdgeItr) : Handle the (imminent)
+ /// change to the cost matrix on the given edge (by R2).
+ /// <li> void postUpdateEdgeCostts(Graph::EdgeItr) : Handle the new
+ /// costs on the given edge.
+ /// <li> void handleAddEdge(Graph::EdgeItr) : Handle the addition of a new
+ /// edge into the PBQP graph (by R2).
+ /// <li> void handleRemoveEdge(Graph::EdgeItr, Graph::NodeItr) : Handle the
+ /// disconnection of the given edge from the given node.
+ /// <li> A constructor for your derived class : to pass back a reference to
+ /// the solver which is using this heuristic.
+ /// </ul>
+ ///
+ /// These methods are implemented in this class for documentation purposes,
+ /// but will assert if called.
+ ///
+ /// Note that this class uses the curiously recursive template idiom to
+ /// forward calls to the derived class. These methods need not be made
+ /// virtual, and indeed probably shouldn't for performance reasons.
+ ///
+ /// You'll also need to provide NodeData and EdgeData structs in your class.
+ /// These can be used to attach data relevant to your heuristic to each
+ /// node/edge in the PBQP graph.
+
+ template <typename HImpl>
+ class HeuristicBase {
+ private:
+
+ typedef std::list<Graph::NodeItr> OptimalList;
+
+ HeuristicSolverImpl<HImpl> &s;
+ Graph &g;
+ OptimalList optimalList;
+
+ // Return a reference to the derived heuristic.
+ HImpl& impl() { return static_cast<HImpl&>(*this); }
+
+ // Add the given node to the optimal reductions list. Keep an iterator to
+ // its location for fast removal.
+ void addToOptimalReductionList(Graph::NodeItr nItr) {
+ optimalList.insert(optimalList.end(), nItr);
+ }
+
+ public:
+
+ /// \brief Construct an instance with a reference to the given solver.
+ /// @param solver The solver which is using this heuristic instance.
+ HeuristicBase(HeuristicSolverImpl<HImpl> &solver)
+ : s(solver), g(s.getGraph()) { }
+
+ /// \brief Get the solver which is using this heuristic instance.
+ /// @return The solver which is using this heuristic instance.
+ ///
+ /// You can use this method to get access to the solver in your derived
+ /// heuristic implementation.
+ HeuristicSolverImpl<HImpl>& getSolver() { return s; }
+
+ /// \brief Get the graph representing the problem to be solved.
+ /// @return The graph representing the problem to be solved.
+ Graph& getGraph() { return g; }
+
+ /// \brief Tell the solver to simplify the graph before the reduction phase.
+ /// @return Whether or not the solver should run a simplification phase
+ /// prior to the main setup and reduction.
+ ///
+ /// HeuristicBase returns true from this method as it's a sensible default,
+ /// however you can over-ride it in your derived class if you want different
+ /// behaviour.
+ bool solverRunSimplify() const { return true; }
+
+ /// \brief Decide whether a node should be optimally or heuristically
+ /// reduced.
+ /// @return Whether or not the given node should be listed for optimal
+ /// reduction (via R0, R1 or R2).
+ ///
+ /// HeuristicBase returns true for any node with degree less than 3. This is
+ /// sane and sensible for many situations, but not all. You can over-ride
+ /// this method in your derived class if you want a different selection
+ /// criteria. Note however that your criteria for selecting optimal nodes
+ /// should be <i>at least</i> as strong as this. I.e. Nodes of degree 3 or
+ /// higher should not be selected under any circumstances.
+ bool shouldOptimallyReduce(Graph::NodeItr nItr) {
+ if (g.getNodeDegree(nItr) < 3)
+ return true;
+ // else
+ return false;
+ }
+
+ /// \brief Add the given node to the list of nodes to be optimally reduced.
+ /// @return nItr Node iterator to be added.
+ ///
+ /// You probably don't want to over-ride this, except perhaps to record
+ /// statistics before calling this implementation. HeuristicBase relies on
+ /// its behaviour.
+ void addToOptimalReduceList(Graph::NodeItr nItr) {
+ optimalList.push_back(nItr);
+ }
+
+ /// \brief Initialise the heuristic.
+ ///
+ /// HeuristicBase iterates over all nodes in the problem and adds them to
+ /// the appropriate list using addToOptimalReduceList or
+ /// addToHeuristicReduceList based on the result of shouldOptimallyReduce.
+ ///
+ /// This behaviour should be fine for most situations.
+ void setup() {
+ for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
+ nItr != nEnd; ++nItr) {
+ if (impl().shouldOptimallyReduce(nItr)) {
+ addToOptimalReduceList(nItr);
+ } else {
+ impl().addToHeuristicReduceList(nItr);
+ }
+ }
+ }
+
+ /// \brief Optimally reduce one of the nodes in the optimal reduce list.
+ /// @return True if a reduction takes place, false if the optimal reduce
+ /// list is empty.
+ ///
+ /// Selects a node from the optimal reduce list and removes it, applying
+ /// R0, R1 or R2 as appropriate based on the selected node's degree.
+ bool optimalReduce() {
+ if (optimalList.empty())
+ return false;
+
+ Graph::NodeItr nItr = optimalList.front();
+ optimalList.pop_front();
+
+ switch (s.getSolverDegree(nItr)) {
+ case 0: s.applyR0(nItr); break;
+ case 1: s.applyR1(nItr); break;
+ case 2: s.applyR2(nItr); break;
+ default: llvm_unreachable(
+ "Optimal reductions of degree > 2 nodes is invalid.");
+ }
+
+ return true;
+ }
+
+ /// \brief Perform the PBQP reduction process.
+ ///
+ /// Reduces the problem to the empty graph by repeated application of the
+ /// reduction rules R0, R1, R2 and RN.
+ /// R0, R1 or R2 are always applied if possible before RN is used.
+ void reduce() {
+ bool finished = false;
+
+ while (!finished) {
+ if (!optimalReduce()) {
+ if (impl().heuristicReduce()) {
+ getSolver().recordRN();
+ } else {
+ finished = true;
+ }
+ }
+ }
+ }
+
+ /// \brief Add a node to the heuristic reduce list.
+ /// @param nItr Node iterator to add to the heuristic reduce list.
+ void addToHeuristicList(Graph::NodeItr nItr) {
+ llvm_unreachable("Must be implemented in derived class.");
+ }
+
+ /// \brief Heuristically reduce one of the nodes in the heuristic
+ /// reduce list.
+ /// @return True if a reduction takes place, false if the heuristic reduce
+ /// list is empty.
+ void heuristicReduce() {
+ llvm_unreachable("Must be implemented in derived class.");
+ }
+
+ /// \brief Prepare a change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void preUpdateEdgeCosts(Graph::EdgeItr eItr) {
+ llvm_unreachable("Must be implemented in derived class.");
+ }
+
+ /// \brief Handle the change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void postUpdateEdgeCostts(Graph::EdgeItr eItr) {
+ llvm_unreachable("Must be implemented in derived class.");
+ }
+
+ /// \brief Handle the addition of a new edge into the PBQP graph.
+ /// @param eItr Edge iterator for the added edge.
+ void handleAddEdge(Graph::EdgeItr eItr) {
+ llvm_unreachable("Must be implemented in derived class.");
+ }
+
+ /// \brief Handle disconnection of an edge from a node.
+ /// @param eItr Edge iterator for edge being disconnected.
+ /// @param nItr Node iterator for the node being disconnected from.
+ ///
+ /// Edges are frequently removed due to the removal of a node. This
+ /// method allows for the effect to be computed only for the remaining
+ /// node in the graph.
+ void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ llvm_unreachable("Must be implemented in derived class.");
+ }
+
+ /// \brief Clean up any structures used by HeuristicBase.
+ ///
+ /// At present this just performs a sanity check: that the optimal reduce
+ /// list is empty now that reduction has completed.
+ ///
+ /// If your derived class has more complex structures which need tearing
+ /// down you should over-ride this method but include a call back to this
+ /// implementation.
+ void cleanup() {
+ assert(optimalList.empty() && "Nodes left over in optimal reduce list?");
+ }
+
+ };
+
+}
+
+
+#endif // LLVM_CODEGEN_PBQP_HEURISTICBASE_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h b/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h
new file mode 100644
index 000000000000..35514f967478
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/HeuristicSolver.h
@@ -0,0 +1,616 @@
+//===-- HeuristicSolver.h - Heuristic PBQP Solver --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Heuristic PBQP solver. This solver is able to perform optimal reductions for
+// nodes of degree 0, 1 or 2. For nodes of degree >2 a plugable heuristic is
+// used to select a node for reduction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
+#define LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
+
+#include "Graph.h"
+#include "Solution.h"
+#include <vector>
+#include <limits>
+
+namespace PBQP {
+
+ /// \brief Heuristic PBQP solver implementation.
+ ///
+ /// This class should usually be created (and destroyed) indirectly via a call
+ /// to HeuristicSolver<HImpl>::solve(Graph&).
+ /// See the comments for HeuristicSolver.
+ ///
+ /// HeuristicSolverImpl provides the R0, R1 and R2 reduction rules,
+ /// backpropagation phase, and maintains the internal copy of the graph on
+ /// which the reduction is carried out (the original being kept to facilitate
+ /// backpropagation).
+ template <typename HImpl>
+ class HeuristicSolverImpl {
+ private:
+
+ typedef typename HImpl::NodeData HeuristicNodeData;
+ typedef typename HImpl::EdgeData HeuristicEdgeData;
+
+ typedef std::list<Graph::EdgeItr> SolverEdges;
+
+ public:
+
+ /// \brief Iterator type for edges in the solver graph.
+ typedef SolverEdges::iterator SolverEdgeItr;
+
+ private:
+
+ class NodeData {
+ public:
+ NodeData() : solverDegree(0) {}
+
+ HeuristicNodeData& getHeuristicData() { return hData; }
+
+ SolverEdgeItr addSolverEdge(Graph::EdgeItr eItr) {
+ ++solverDegree;
+ return solverEdges.insert(solverEdges.end(), eItr);
+ }
+
+ void removeSolverEdge(SolverEdgeItr seItr) {
+ --solverDegree;
+ solverEdges.erase(seItr);
+ }
+
+ SolverEdgeItr solverEdgesBegin() { return solverEdges.begin(); }
+ SolverEdgeItr solverEdgesEnd() { return solverEdges.end(); }
+ unsigned getSolverDegree() const { return solverDegree; }
+ void clearSolverEdges() {
+ solverDegree = 0;
+ solverEdges.clear();
+ }
+
+ private:
+ HeuristicNodeData hData;
+ unsigned solverDegree;
+ SolverEdges solverEdges;
+ };
+
+ class EdgeData {
+ public:
+ HeuristicEdgeData& getHeuristicData() { return hData; }
+
+ void setN1SolverEdgeItr(SolverEdgeItr n1SolverEdgeItr) {
+ this->n1SolverEdgeItr = n1SolverEdgeItr;
+ }
+
+ SolverEdgeItr getN1SolverEdgeItr() { return n1SolverEdgeItr; }
+
+ void setN2SolverEdgeItr(SolverEdgeItr n2SolverEdgeItr){
+ this->n2SolverEdgeItr = n2SolverEdgeItr;
+ }
+
+ SolverEdgeItr getN2SolverEdgeItr() { return n2SolverEdgeItr; }
+
+ private:
+
+ HeuristicEdgeData hData;
+ SolverEdgeItr n1SolverEdgeItr, n2SolverEdgeItr;
+ };
+
+ Graph &g;
+ HImpl h;
+ Solution s;
+ std::vector<Graph::NodeItr> stack;
+
+ typedef std::list<NodeData> NodeDataList;
+ NodeDataList nodeDataList;
+
+ typedef std::list<EdgeData> EdgeDataList;
+ EdgeDataList edgeDataList;
+
+ public:
+
+ /// \brief Construct a heuristic solver implementation to solve the given
+ /// graph.
+ /// @param g The graph representing the problem instance to be solved.
+ HeuristicSolverImpl(Graph &g) : g(g), h(*this) {}
+
+ /// \brief Get the graph being solved by this solver.
+ /// @return The graph representing the problem instance being solved by this
+ /// solver.
+ Graph& getGraph() { return g; }
+
+ /// \brief Get the heuristic data attached to the given node.
+ /// @param nItr Node iterator.
+ /// @return The heuristic data attached to the given node.
+ HeuristicNodeData& getHeuristicNodeData(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).getHeuristicData();
+ }
+
+ /// \brief Get the heuristic data attached to the given edge.
+ /// @param eItr Edge iterator.
+ /// @return The heuristic data attached to the given node.
+ HeuristicEdgeData& getHeuristicEdgeData(Graph::EdgeItr eItr) {
+ return getSolverEdgeData(eItr).getHeuristicData();
+ }
+
+ /// \brief Begin iterator for the set of edges adjacent to the given node in
+ /// the solver graph.
+ /// @param nItr Node iterator.
+ /// @return Begin iterator for the set of edges adjacent to the given node
+ /// in the solver graph.
+ SolverEdgeItr solverEdgesBegin(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).solverEdgesBegin();
+ }
+
+ /// \brief End iterator for the set of edges adjacent to the given node in
+ /// the solver graph.
+ /// @param nItr Node iterator.
+ /// @return End iterator for the set of edges adjacent to the given node in
+ /// the solver graph.
+ SolverEdgeItr solverEdgesEnd(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).solverEdgesEnd();
+ }
+
+ /// \brief Remove a node from the solver graph.
+ /// @param eItr Edge iterator for edge to be removed.
+ ///
+ /// Does <i>not</i> notify the heuristic of the removal. That should be
+ /// done manually if necessary.
+ void removeSolverEdge(Graph::EdgeItr eItr) {
+ EdgeData &eData = getSolverEdgeData(eItr);
+ NodeData &n1Data = getSolverNodeData(g.getEdgeNode1(eItr)),
+ &n2Data = getSolverNodeData(g.getEdgeNode2(eItr));
+
+ n1Data.removeSolverEdge(eData.getN1SolverEdgeItr());
+ n2Data.removeSolverEdge(eData.getN2SolverEdgeItr());
+ }
+
+ /// \brief Compute a solution to the PBQP problem instance with which this
+ /// heuristic solver was constructed.
+ /// @return A solution to the PBQP problem.
+ ///
+ /// Performs the full PBQP heuristic solver algorithm, including setup,
+ /// calls to the heuristic (which will call back to the reduction rules in
+ /// this class), and cleanup.
+ Solution computeSolution() {
+ setup();
+ h.setup();
+ h.reduce();
+ backpropagate();
+ h.cleanup();
+ cleanup();
+ return s;
+ }
+
+ /// \brief Add to the end of the stack.
+ /// @param nItr Node iterator to add to the reduction stack.
+ void pushToStack(Graph::NodeItr nItr) {
+ getSolverNodeData(nItr).clearSolverEdges();
+ stack.push_back(nItr);
+ }
+
+ /// \brief Returns the solver degree of the given node.
+ /// @param nItr Node iterator for which degree is requested.
+ /// @return Node degree in the <i>solver</i> graph (not the original graph).
+ unsigned getSolverDegree(Graph::NodeItr nItr) {
+ return getSolverNodeData(nItr).getSolverDegree();
+ }
+
+ /// \brief Set the solution of the given node.
+ /// @param nItr Node iterator to set solution for.
+ /// @param selection Selection for node.
+ void setSolution(const Graph::NodeItr &nItr, unsigned selection) {
+ s.setSelection(nItr, selection);
+
+ for (Graph::AdjEdgeItr aeItr = g.adjEdgesBegin(nItr),
+ aeEnd = g.adjEdgesEnd(nItr);
+ aeItr != aeEnd; ++aeItr) {
+ Graph::EdgeItr eItr(*aeItr);
+ Graph::NodeItr anItr(g.getEdgeOtherNode(eItr, nItr));
+ getSolverNodeData(anItr).addSolverEdge(eItr);
+ }
+ }
+
+ /// \brief Apply rule R0.
+ /// @param nItr Node iterator for node to apply R0 to.
+ ///
+ /// Node will be automatically pushed to the solver stack.
+ void applyR0(Graph::NodeItr nItr) {
+ assert(getSolverNodeData(nItr).getSolverDegree() == 0 &&
+ "R0 applied to node with degree != 0.");
+
+ // Nothing to do. Just push the node onto the reduction stack.
+ pushToStack(nItr);
+
+ s.recordR0();
+ }
+
+ /// \brief Apply rule R1.
+ /// @param xnItr Node iterator for node to apply R1 to.
+ ///
+ /// Node will be automatically pushed to the solver stack.
+ void applyR1(Graph::NodeItr xnItr) {
+ NodeData &nd = getSolverNodeData(xnItr);
+ assert(nd.getSolverDegree() == 1 &&
+ "R1 applied to node with degree != 1.");
+
+ Graph::EdgeItr eItr = *nd.solverEdgesBegin();
+
+ const Matrix &eCosts = g.getEdgeCosts(eItr);
+ const Vector &xCosts = g.getNodeCosts(xnItr);
+
+ // Duplicate a little to avoid transposing matrices.
+ if (xnItr == g.getEdgeNode1(eItr)) {
+ Graph::NodeItr ynItr = g.getEdgeNode2(eItr);
+ Vector &yCosts = g.getNodeCosts(ynItr);
+ for (unsigned j = 0; j < yCosts.getLength(); ++j) {
+ PBQPNum min = eCosts[0][j] + xCosts[0];
+ for (unsigned i = 1; i < xCosts.getLength(); ++i) {
+ PBQPNum c = eCosts[i][j] + xCosts[i];
+ if (c < min)
+ min = c;
+ }
+ yCosts[j] += min;
+ }
+ h.handleRemoveEdge(eItr, ynItr);
+ } else {
+ Graph::NodeItr ynItr = g.getEdgeNode1(eItr);
+ Vector &yCosts = g.getNodeCosts(ynItr);
+ for (unsigned i = 0; i < yCosts.getLength(); ++i) {
+ PBQPNum min = eCosts[i][0] + xCosts[0];
+ for (unsigned j = 1; j < xCosts.getLength(); ++j) {
+ PBQPNum c = eCosts[i][j] + xCosts[j];
+ if (c < min)
+ min = c;
+ }
+ yCosts[i] += min;
+ }
+ h.handleRemoveEdge(eItr, ynItr);
+ }
+ removeSolverEdge(eItr);
+ assert(nd.getSolverDegree() == 0 &&
+ "Degree 1 with edge removed should be 0.");
+ pushToStack(xnItr);
+ s.recordR1();
+ }
+
+ /// \brief Apply rule R2.
+ /// @param xnItr Node iterator for node to apply R2 to.
+ ///
+ /// Node will be automatically pushed to the solver stack.
+ void applyR2(Graph::NodeItr xnItr) {
+ assert(getSolverNodeData(xnItr).getSolverDegree() == 2 &&
+ "R2 applied to node with degree != 2.");
+
+ NodeData &nd = getSolverNodeData(xnItr);
+ const Vector &xCosts = g.getNodeCosts(xnItr);
+
+ SolverEdgeItr aeItr = nd.solverEdgesBegin();
+ Graph::EdgeItr yxeItr = *aeItr,
+ zxeItr = *(++aeItr);
+
+ Graph::NodeItr ynItr = g.getEdgeOtherNode(yxeItr, xnItr),
+ znItr = g.getEdgeOtherNode(zxeItr, xnItr);
+
+ bool flipEdge1 = (g.getEdgeNode1(yxeItr) == xnItr),
+ flipEdge2 = (g.getEdgeNode1(zxeItr) == xnItr);
+
+ const Matrix *yxeCosts = flipEdge1 ?
+ new Matrix(g.getEdgeCosts(yxeItr).transpose()) :
+ &g.getEdgeCosts(yxeItr);
+
+ const Matrix *zxeCosts = flipEdge2 ?
+ new Matrix(g.getEdgeCosts(zxeItr).transpose()) :
+ &g.getEdgeCosts(zxeItr);
+
+ unsigned xLen = xCosts.getLength(),
+ yLen = yxeCosts->getRows(),
+ zLen = zxeCosts->getRows();
+
+ Matrix delta(yLen, zLen);
+
+ for (unsigned i = 0; i < yLen; ++i) {
+ for (unsigned j = 0; j < zLen; ++j) {
+ PBQPNum min = (*yxeCosts)[i][0] + (*zxeCosts)[j][0] + xCosts[0];
+ for (unsigned k = 1; k < xLen; ++k) {
+ PBQPNum c = (*yxeCosts)[i][k] + (*zxeCosts)[j][k] + xCosts[k];
+ if (c < min) {
+ min = c;
+ }
+ }
+ delta[i][j] = min;
+ }
+ }
+
+ if (flipEdge1)
+ delete yxeCosts;
+
+ if (flipEdge2)
+ delete zxeCosts;
+
+ Graph::EdgeItr yzeItr = g.findEdge(ynItr, znItr);
+ bool addedEdge = false;
+
+ if (yzeItr == g.edgesEnd()) {
+ yzeItr = g.addEdge(ynItr, znItr, delta);
+ addedEdge = true;
+ } else {
+ Matrix &yzeCosts = g.getEdgeCosts(yzeItr);
+ h.preUpdateEdgeCosts(yzeItr);
+ if (ynItr == g.getEdgeNode1(yzeItr)) {
+ yzeCosts += delta;
+ } else {
+ yzeCosts += delta.transpose();
+ }
+ }
+
+ bool nullCostEdge = tryNormaliseEdgeMatrix(yzeItr);
+
+ if (!addedEdge) {
+ // If we modified the edge costs let the heuristic know.
+ h.postUpdateEdgeCosts(yzeItr);
+ }
+
+ if (nullCostEdge) {
+ // If this edge ended up null remove it.
+ if (!addedEdge) {
+ // We didn't just add it, so we need to notify the heuristic
+ // and remove it from the solver.
+ h.handleRemoveEdge(yzeItr, ynItr);
+ h.handleRemoveEdge(yzeItr, znItr);
+ removeSolverEdge(yzeItr);
+ }
+ g.removeEdge(yzeItr);
+ } else if (addedEdge) {
+ // If the edge was added, and non-null, finish setting it up, add it to
+ // the solver & notify heuristic.
+ edgeDataList.push_back(EdgeData());
+ g.setEdgeData(yzeItr, &edgeDataList.back());
+ addSolverEdge(yzeItr);
+ h.handleAddEdge(yzeItr);
+ }
+
+ h.handleRemoveEdge(yxeItr, ynItr);
+ removeSolverEdge(yxeItr);
+ h.handleRemoveEdge(zxeItr, znItr);
+ removeSolverEdge(zxeItr);
+
+ pushToStack(xnItr);
+ s.recordR2();
+ }
+
+ /// \brief Record an application of the RN rule.
+ ///
+ /// For use by the HeuristicBase.
+ void recordRN() { s.recordRN(); }
+
+ private:
+
+ NodeData& getSolverNodeData(Graph::NodeItr nItr) {
+ return *static_cast<NodeData*>(g.getNodeData(nItr));
+ }
+
+ EdgeData& getSolverEdgeData(Graph::EdgeItr eItr) {
+ return *static_cast<EdgeData*>(g.getEdgeData(eItr));
+ }
+
+ void addSolverEdge(Graph::EdgeItr eItr) {
+ EdgeData &eData = getSolverEdgeData(eItr);
+ NodeData &n1Data = getSolverNodeData(g.getEdgeNode1(eItr)),
+ &n2Data = getSolverNodeData(g.getEdgeNode2(eItr));
+
+ eData.setN1SolverEdgeItr(n1Data.addSolverEdge(eItr));
+ eData.setN2SolverEdgeItr(n2Data.addSolverEdge(eItr));
+ }
+
+ void setup() {
+ if (h.solverRunSimplify()) {
+ simplify();
+ }
+
+ // Create node data objects.
+ for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
+ nItr != nEnd; ++nItr) {
+ nodeDataList.push_back(NodeData());
+ g.setNodeData(nItr, &nodeDataList.back());
+ }
+
+ // Create edge data objects.
+ for (Graph::EdgeItr eItr = g.edgesBegin(), eEnd = g.edgesEnd();
+ eItr != eEnd; ++eItr) {
+ edgeDataList.push_back(EdgeData());
+ g.setEdgeData(eItr, &edgeDataList.back());
+ addSolverEdge(eItr);
+ }
+ }
+
+ void simplify() {
+ disconnectTrivialNodes();
+ eliminateIndependentEdges();
+ }
+
+ // Eliminate trivial nodes.
+ void disconnectTrivialNodes() {
+ unsigned numDisconnected = 0;
+
+ for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
+ nItr != nEnd; ++nItr) {
+
+ if (g.getNodeCosts(nItr).getLength() == 1) {
+
+ std::vector<Graph::EdgeItr> edgesToRemove;
+
+ for (Graph::AdjEdgeItr aeItr = g.adjEdgesBegin(nItr),
+ aeEnd = g.adjEdgesEnd(nItr);
+ aeItr != aeEnd; ++aeItr) {
+
+ Graph::EdgeItr eItr = *aeItr;
+
+ if (g.getEdgeNode1(eItr) == nItr) {
+ Graph::NodeItr otherNodeItr = g.getEdgeNode2(eItr);
+ g.getNodeCosts(otherNodeItr) +=
+ g.getEdgeCosts(eItr).getRowAsVector(0);
+ }
+ else {
+ Graph::NodeItr otherNodeItr = g.getEdgeNode1(eItr);
+ g.getNodeCosts(otherNodeItr) +=
+ g.getEdgeCosts(eItr).getColAsVector(0);
+ }
+
+ edgesToRemove.push_back(eItr);
+ }
+
+ if (!edgesToRemove.empty())
+ ++numDisconnected;
+
+ while (!edgesToRemove.empty()) {
+ g.removeEdge(edgesToRemove.back());
+ edgesToRemove.pop_back();
+ }
+ }
+ }
+ }
+
+ void eliminateIndependentEdges() {
+ std::vector<Graph::EdgeItr> edgesToProcess;
+ unsigned numEliminated = 0;
+
+ for (Graph::EdgeItr eItr = g.edgesBegin(), eEnd = g.edgesEnd();
+ eItr != eEnd; ++eItr) {
+ edgesToProcess.push_back(eItr);
+ }
+
+ while (!edgesToProcess.empty()) {
+ if (tryToEliminateEdge(edgesToProcess.back()))
+ ++numEliminated;
+ edgesToProcess.pop_back();
+ }
+ }
+
+ bool tryToEliminateEdge(Graph::EdgeItr eItr) {
+ if (tryNormaliseEdgeMatrix(eItr)) {
+ g.removeEdge(eItr);
+ return true;
+ }
+ return false;
+ }
+
+ bool tryNormaliseEdgeMatrix(Graph::EdgeItr &eItr) {
+
+ const PBQPNum infinity = std::numeric_limits<PBQPNum>::infinity();
+
+ Matrix &edgeCosts = g.getEdgeCosts(eItr);
+ Vector &uCosts = g.getNodeCosts(g.getEdgeNode1(eItr)),
+ &vCosts = g.getNodeCosts(g.getEdgeNode2(eItr));
+
+ for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
+ PBQPNum rowMin = infinity;
+
+ for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
+ if (vCosts[c] != infinity && edgeCosts[r][c] < rowMin)
+ rowMin = edgeCosts[r][c];
+ }
+
+ uCosts[r] += rowMin;
+
+ if (rowMin != infinity) {
+ edgeCosts.subFromRow(r, rowMin);
+ }
+ else {
+ edgeCosts.setRow(r, 0);
+ }
+ }
+
+ for (unsigned c = 0; c < edgeCosts.getCols(); ++c) {
+ PBQPNum colMin = infinity;
+
+ for (unsigned r = 0; r < edgeCosts.getRows(); ++r) {
+ if (uCosts[r] != infinity && edgeCosts[r][c] < colMin)
+ colMin = edgeCosts[r][c];
+ }
+
+ vCosts[c] += colMin;
+
+ if (colMin != infinity) {
+ edgeCosts.subFromCol(c, colMin);
+ }
+ else {
+ edgeCosts.setCol(c, 0);
+ }
+ }
+
+ return edgeCosts.isZero();
+ }
+
+ void backpropagate() {
+ while (!stack.empty()) {
+ computeSolution(stack.back());
+ stack.pop_back();
+ }
+ }
+
+ void computeSolution(Graph::NodeItr nItr) {
+
+ NodeData &nodeData = getSolverNodeData(nItr);
+
+ Vector v(g.getNodeCosts(nItr));
+
+ // Solve based on existing solved edges.
+ for (SolverEdgeItr solvedEdgeItr = nodeData.solverEdgesBegin(),
+ solvedEdgeEnd = nodeData.solverEdgesEnd();
+ solvedEdgeItr != solvedEdgeEnd; ++solvedEdgeItr) {
+
+ Graph::EdgeItr eItr(*solvedEdgeItr);
+ Matrix &edgeCosts = g.getEdgeCosts(eItr);
+
+ if (nItr == g.getEdgeNode1(eItr)) {
+ Graph::NodeItr adjNode(g.getEdgeNode2(eItr));
+ unsigned adjSolution = s.getSelection(adjNode);
+ v += edgeCosts.getColAsVector(adjSolution);
+ }
+ else {
+ Graph::NodeItr adjNode(g.getEdgeNode1(eItr));
+ unsigned adjSolution = s.getSelection(adjNode);
+ v += edgeCosts.getRowAsVector(adjSolution);
+ }
+
+ }
+
+ setSolution(nItr, v.minIndex());
+ }
+
+ void cleanup() {
+ h.cleanup();
+ nodeDataList.clear();
+ edgeDataList.clear();
+ }
+ };
+
+ /// \brief PBQP heuristic solver class.
+ ///
+ /// Given a PBQP Graph g representing a PBQP problem, you can find a solution
+ /// by calling
+ /// <tt>Solution s = HeuristicSolver<H>::solve(g);</tt>
+ ///
+ /// The choice of heuristic for the H parameter will affect both the solver
+ /// speed and solution quality. The heuristic should be chosen based on the
+ /// nature of the problem being solved.
+ /// Currently the only solver included with LLVM is the Briggs heuristic for
+ /// register allocation.
+ template <typename HImpl>
+ class HeuristicSolver {
+ public:
+ static Solution solve(Graph &g) {
+ HeuristicSolverImpl<HImpl> hs(g);
+ return hs.computeSolution();
+ }
+ };
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_HEURISTICSOLVER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
new file mode 100644
index 000000000000..a859e5899f06
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
@@ -0,0 +1,469 @@
+//===-- Briggs.h --- Briggs Heuristic for PBQP ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements the Briggs test for "allocability" of nodes in a
+// PBQP graph representing a register allocation problem. Nodes which can be
+// proven allocable (by a safe and relatively accurate test) are removed from
+// the PBQP graph first. If no provably allocable node is present in the graph
+// then the node with the minimal spill-cost to degree ratio is removed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
+#define LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
+
+#include "../HeuristicSolver.h"
+#include "../HeuristicBase.h"
+
+#include <limits>
+
+namespace PBQP {
+ namespace Heuristics {
+
+ /// \brief PBQP Heuristic which applies an allocability test based on
+ /// Briggs.
+ ///
+ /// This heuristic assumes that the elements of cost vectors in the PBQP
+ /// problem represent storage options, with the first being the spill
+ /// option and subsequent elements representing legal registers for the
+ /// corresponding node. Edge cost matrices are likewise assumed to represent
+ /// register constraints.
+ /// If one or more nodes can be proven allocable by this heuristic (by
+ /// inspection of their constraint matrices) then the allocable node of
+ /// highest degree is selected for the next reduction and pushed to the
+ /// solver stack. If no nodes can be proven allocable then the node with
+ /// the lowest estimated spill cost is selected and push to the solver stack
+ /// instead.
+ ///
+ /// This implementation is built on top of HeuristicBase.
+ class Briggs : public HeuristicBase<Briggs> {
+ private:
+
+ class LinkDegreeComparator {
+ public:
+ LinkDegreeComparator(HeuristicSolverImpl<Briggs> &s) : s(&s) {}
+ bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const {
+ if (s->getSolverDegree(n1Itr) > s->getSolverDegree(n2Itr))
+ return true;
+ return false;
+ }
+ private:
+ HeuristicSolverImpl<Briggs> *s;
+ };
+
+ class SpillCostComparator {
+ public:
+ SpillCostComparator(HeuristicSolverImpl<Briggs> &s)
+ : s(&s), g(&s.getGraph()) {}
+ bool operator()(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr) const {
+ const PBQP::Vector &cv1 = g->getNodeCosts(n1Itr);
+ const PBQP::Vector &cv2 = g->getNodeCosts(n2Itr);
+
+ PBQPNum cost1 = cv1[0] / s->getSolverDegree(n1Itr);
+ PBQPNum cost2 = cv2[0] / s->getSolverDegree(n2Itr);
+
+ if (cost1 < cost2)
+ return true;
+ return false;
+ }
+
+ private:
+ HeuristicSolverImpl<Briggs> *s;
+ Graph *g;
+ };
+
+ typedef std::list<Graph::NodeItr> RNAllocableList;
+ typedef RNAllocableList::iterator RNAllocableListItr;
+
+ typedef std::list<Graph::NodeItr> RNUnallocableList;
+ typedef RNUnallocableList::iterator RNUnallocableListItr;
+
+ public:
+
+ struct NodeData {
+ typedef std::vector<unsigned> UnsafeDegreesArray;
+ bool isHeuristic, isAllocable, isInitialized;
+ unsigned numDenied, numSafe;
+ UnsafeDegreesArray unsafeDegrees;
+ RNAllocableListItr rnaItr;
+ RNUnallocableListItr rnuItr;
+
+ NodeData()
+ : isHeuristic(false), isAllocable(false), isInitialized(false),
+ numDenied(0), numSafe(0) { }
+ };
+
+ struct EdgeData {
+ typedef std::vector<unsigned> UnsafeArray;
+ unsigned worst, reverseWorst;
+ UnsafeArray unsafe, reverseUnsafe;
+ bool isUpToDate;
+
+ EdgeData() : worst(0), reverseWorst(0), isUpToDate(false) {}
+ };
+
+ /// \brief Construct an instance of the Briggs heuristic.
+ /// @param solver A reference to the solver which is using this heuristic.
+ Briggs(HeuristicSolverImpl<Briggs> &solver) :
+ HeuristicBase<Briggs>(solver) {}
+
+ /// \brief Determine whether a node should be reduced using optimal
+ /// reduction.
+ /// @param nItr Node iterator to be considered.
+ /// @return True if the given node should be optimally reduced, false
+ /// otherwise.
+ ///
+ /// Selects nodes of degree 0, 1 or 2 for optimal reduction, with one
+ /// exception. Nodes whose spill cost (element 0 of their cost vector) is
+ /// infinite are checked for allocability first. Allocable nodes may be
+ /// optimally reduced, but nodes whose allocability cannot be proven are
+ /// selected for heuristic reduction instead.
+ bool shouldOptimallyReduce(Graph::NodeItr nItr) {
+ if (getSolver().getSolverDegree(nItr) < 3) {
+ return true;
+ }
+ // else
+ return false;
+ }
+
+ /// \brief Add a node to the heuristic reduce list.
+ /// @param nItr Node iterator to add to the heuristic reduce list.
+ void addToHeuristicReduceList(Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+ initializeNode(nItr);
+ nd.isHeuristic = true;
+ if (nd.isAllocable) {
+ nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nItr);
+ } else {
+ nd.rnuItr = rnUnallocableList.insert(rnUnallocableList.end(), nItr);
+ }
+ }
+
+ /// \brief Heuristically reduce one of the nodes in the heuristic
+ /// reduce list.
+ /// @return True if a reduction takes place, false if the heuristic reduce
+ /// list is empty.
+ ///
+ /// If the list of allocable nodes is non-empty a node is selected
+ /// from it and pushed to the stack. Otherwise if the non-allocable list
+ /// is non-empty a node is selected from it and pushed to the stack.
+ /// If both lists are empty the method simply returns false with no action
+ /// taken.
+ bool heuristicReduce() {
+ if (!rnAllocableList.empty()) {
+ RNAllocableListItr rnaItr =
+ min_element(rnAllocableList.begin(), rnAllocableList.end(),
+ LinkDegreeComparator(getSolver()));
+ Graph::NodeItr nItr = *rnaItr;
+ rnAllocableList.erase(rnaItr);
+ handleRemoveNode(nItr);
+ getSolver().pushToStack(nItr);
+ return true;
+ } else if (!rnUnallocableList.empty()) {
+ RNUnallocableListItr rnuItr =
+ min_element(rnUnallocableList.begin(), rnUnallocableList.end(),
+ SpillCostComparator(getSolver()));
+ Graph::NodeItr nItr = *rnuItr;
+ rnUnallocableList.erase(rnuItr);
+ handleRemoveNode(nItr);
+ getSolver().pushToStack(nItr);
+ return true;
+ }
+ // else
+ return false;
+ }
+
+ /// \brief Prepare a change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void preUpdateEdgeCosts(Graph::EdgeItr eItr) {
+ Graph &g = getGraph();
+ Graph::NodeItr n1Itr = g.getEdgeNode1(eItr),
+ n2Itr = g.getEdgeNode2(eItr);
+ NodeData &n1 = getHeuristicNodeData(n1Itr),
+ &n2 = getHeuristicNodeData(n2Itr);
+
+ if (n1.isHeuristic)
+ subtractEdgeContributions(eItr, getGraph().getEdgeNode1(eItr));
+ if (n2.isHeuristic)
+ subtractEdgeContributions(eItr, getGraph().getEdgeNode2(eItr));
+
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+ ed.isUpToDate = false;
+ }
+
+ /// \brief Handle the change in the costs on the given edge.
+ /// @param eItr Edge iterator.
+ void postUpdateEdgeCosts(Graph::EdgeItr eItr) {
+ // This is effectively the same as adding a new edge now, since
+ // we've factored out the costs of the old one.
+ handleAddEdge(eItr);
+ }
+
+ /// \brief Handle the addition of a new edge into the PBQP graph.
+ /// @param eItr Edge iterator for the added edge.
+ ///
+ /// Updates allocability of any nodes connected by this edge which are
+ /// being managed by the heuristic. If allocability changes they are
+ /// moved to the appropriate list.
+ void handleAddEdge(Graph::EdgeItr eItr) {
+ Graph &g = getGraph();
+ Graph::NodeItr n1Itr = g.getEdgeNode1(eItr),
+ n2Itr = g.getEdgeNode2(eItr);
+ NodeData &n1 = getHeuristicNodeData(n1Itr),
+ &n2 = getHeuristicNodeData(n2Itr);
+
+ // If neither node is managed by the heuristic there's nothing to be
+ // done.
+ if (!n1.isHeuristic && !n2.isHeuristic)
+ return;
+
+ // Ok - we need to update at least one node.
+ computeEdgeContributions(eItr);
+
+ // Update node 1 if it's managed by the heuristic.
+ if (n1.isHeuristic) {
+ bool n1WasAllocable = n1.isAllocable;
+ addEdgeContributions(eItr, n1Itr);
+ updateAllocability(n1Itr);
+ if (n1WasAllocable && !n1.isAllocable) {
+ rnAllocableList.erase(n1.rnaItr);
+ n1.rnuItr =
+ rnUnallocableList.insert(rnUnallocableList.end(), n1Itr);
+ }
+ }
+
+ // Likewise for node 2.
+ if (n2.isHeuristic) {
+ bool n2WasAllocable = n2.isAllocable;
+ addEdgeContributions(eItr, n2Itr);
+ updateAllocability(n2Itr);
+ if (n2WasAllocable && !n2.isAllocable) {
+ rnAllocableList.erase(n2.rnaItr);
+ n2.rnuItr =
+ rnUnallocableList.insert(rnUnallocableList.end(), n2Itr);
+ }
+ }
+ }
+
+ /// \brief Handle disconnection of an edge from a node.
+ /// @param eItr Edge iterator for edge being disconnected.
+ /// @param nItr Node iterator for the node being disconnected from.
+ ///
+ /// Updates allocability of the given node and, if appropriate, moves the
+ /// node to a new list.
+ void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+
+ // If the node is not managed by the heuristic there's nothing to be
+ // done.
+ if (!nd.isHeuristic)
+ return;
+
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+ (void)ed;
+ assert(ed.isUpToDate && "Edge data is not up to date.");
+
+ // Update node.
+ bool ndWasAllocable = nd.isAllocable;
+ subtractEdgeContributions(eItr, nItr);
+ updateAllocability(nItr);
+
+ // If the node has gone optimal...
+ if (shouldOptimallyReduce(nItr)) {
+ nd.isHeuristic = false;
+ addToOptimalReduceList(nItr);
+ if (ndWasAllocable) {
+ rnAllocableList.erase(nd.rnaItr);
+ } else {
+ rnUnallocableList.erase(nd.rnuItr);
+ }
+ } else {
+ // Node didn't go optimal, but we might have to move it
+ // from "unallocable" to "allocable".
+ if (!ndWasAllocable && nd.isAllocable) {
+ rnUnallocableList.erase(nd.rnuItr);
+ nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nItr);
+ }
+ }
+ }
+
+ private:
+
+ NodeData& getHeuristicNodeData(Graph::NodeItr nItr) {
+ return getSolver().getHeuristicNodeData(nItr);
+ }
+
+ EdgeData& getHeuristicEdgeData(Graph::EdgeItr eItr) {
+ return getSolver().getHeuristicEdgeData(eItr);
+ }
+
+ // Work out what this edge will contribute to the allocability of the
+ // nodes connected to it.
+ void computeEdgeContributions(Graph::EdgeItr eItr) {
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+
+ if (ed.isUpToDate)
+ return; // Edge data is already up to date.
+
+ Matrix &eCosts = getGraph().getEdgeCosts(eItr);
+
+ unsigned numRegs = eCosts.getRows() - 1,
+ numReverseRegs = eCosts.getCols() - 1;
+
+ std::vector<unsigned> rowInfCounts(numRegs, 0),
+ colInfCounts(numReverseRegs, 0);
+
+ ed.worst = 0;
+ ed.reverseWorst = 0;
+ ed.unsafe.clear();
+ ed.unsafe.resize(numRegs, 0);
+ ed.reverseUnsafe.clear();
+ ed.reverseUnsafe.resize(numReverseRegs, 0);
+
+ for (unsigned i = 0; i < numRegs; ++i) {
+ for (unsigned j = 0; j < numReverseRegs; ++j) {
+ if (eCosts[i + 1][j + 1] ==
+ std::numeric_limits<PBQPNum>::infinity()) {
+ ed.unsafe[i] = 1;
+ ed.reverseUnsafe[j] = 1;
+ ++rowInfCounts[i];
+ ++colInfCounts[j];
+
+ if (colInfCounts[j] > ed.worst) {
+ ed.worst = colInfCounts[j];
+ }
+
+ if (rowInfCounts[i] > ed.reverseWorst) {
+ ed.reverseWorst = rowInfCounts[i];
+ }
+ }
+ }
+ }
+
+ ed.isUpToDate = true;
+ }
+
+ // Add the contributions of the given edge to the given node's
+ // numDenied and safe members. No action is taken other than to update
+ // these member values. Once updated these numbers can be used by clients
+ // to update the node's allocability.
+ void addEdgeContributions(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+
+ assert(ed.isUpToDate && "Using out-of-date edge numbers.");
+
+ NodeData &nd = getHeuristicNodeData(nItr);
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+
+ bool nIsNode1 = nItr == getGraph().getEdgeNode1(eItr);
+ EdgeData::UnsafeArray &unsafe =
+ nIsNode1 ? ed.unsafe : ed.reverseUnsafe;
+ nd.numDenied += nIsNode1 ? ed.worst : ed.reverseWorst;
+
+ for (unsigned r = 0; r < numRegs; ++r) {
+ if (unsafe[r]) {
+ if (nd.unsafeDegrees[r]==0) {
+ --nd.numSafe;
+ }
+ ++nd.unsafeDegrees[r];
+ }
+ }
+ }
+
+ // Subtract the contributions of the given edge to the given node's
+ // numDenied and safe members. No action is taken other than to update
+ // these member values. Once updated these numbers can be used by clients
+ // to update the node's allocability.
+ void subtractEdgeContributions(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
+ EdgeData &ed = getHeuristicEdgeData(eItr);
+
+ assert(ed.isUpToDate && "Using out-of-date edge numbers.");
+
+ NodeData &nd = getHeuristicNodeData(nItr);
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+
+ bool nIsNode1 = nItr == getGraph().getEdgeNode1(eItr);
+ EdgeData::UnsafeArray &unsafe =
+ nIsNode1 ? ed.unsafe : ed.reverseUnsafe;
+ nd.numDenied -= nIsNode1 ? ed.worst : ed.reverseWorst;
+
+ for (unsigned r = 0; r < numRegs; ++r) {
+ if (unsafe[r]) {
+ if (nd.unsafeDegrees[r] == 1) {
+ ++nd.numSafe;
+ }
+ --nd.unsafeDegrees[r];
+ }
+ }
+ }
+
+ void updateAllocability(Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+ nd.isAllocable = nd.numDenied < numRegs || nd.numSafe > 0;
+ }
+
+ void initializeNode(Graph::NodeItr nItr) {
+ NodeData &nd = getHeuristicNodeData(nItr);
+
+ if (nd.isInitialized)
+ return; // Node data is already up to date.
+
+ unsigned numRegs = getGraph().getNodeCosts(nItr).getLength() - 1;
+
+ nd.numDenied = 0;
+ const Vector& nCosts = getGraph().getNodeCosts(nItr);
+ for (unsigned i = 1; i < nCosts.getLength(); ++i) {
+ if (nCosts[i] == std::numeric_limits<PBQPNum>::infinity())
+ ++nd.numDenied;
+ }
+
+ nd.numSafe = numRegs;
+ nd.unsafeDegrees.resize(numRegs, 0);
+
+ typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr;
+
+ for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(nItr),
+ aeEnd = getSolver().solverEdgesEnd(nItr);
+ aeItr != aeEnd; ++aeItr) {
+
+ Graph::EdgeItr eItr = *aeItr;
+ computeEdgeContributions(eItr);
+ addEdgeContributions(eItr, nItr);
+ }
+
+ updateAllocability(nItr);
+ nd.isInitialized = true;
+ }
+
+ void handleRemoveNode(Graph::NodeItr xnItr) {
+ typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr;
+ std::vector<Graph::EdgeItr> edgesToRemove;
+ for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(xnItr),
+ aeEnd = getSolver().solverEdgesEnd(xnItr);
+ aeItr != aeEnd; ++aeItr) {
+ Graph::NodeItr ynItr = getGraph().getEdgeOtherNode(*aeItr, xnItr);
+ handleRemoveEdge(*aeItr, ynItr);
+ edgesToRemove.push_back(*aeItr);
+ }
+ while (!edgesToRemove.empty()) {
+ getSolver().removeSolverEdge(edgesToRemove.back());
+ edgesToRemove.pop_back();
+ }
+ }
+
+ RNAllocableList rnAllocableList;
+ RNUnallocableList rnUnallocableList;
+ };
+
+ }
+}
+
+
+#endif // LLVM_CODEGEN_PBQP_HEURISTICS_BRIGGS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h
new file mode 100644
index 000000000000..e7598bf3e3f1
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Math.h
@@ -0,0 +1,288 @@
+//===------ Math.h - PBQP Vector and Matrix classes -------------*- 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_PBQP_MATH_H
+#define LLVM_CODEGEN_PBQP_MATH_H
+
+#include <cassert>
+#include <algorithm>
+#include <functional>
+
+namespace PBQP {
+
+typedef float PBQPNum;
+
+/// \brief PBQP Vector class.
+class Vector {
+ public:
+
+ /// \brief Construct a PBQP vector of the given size.
+ explicit Vector(unsigned length) :
+ length(length), data(new PBQPNum[length]) {
+ }
+
+ /// \brief Construct a PBQP vector with initializer.
+ Vector(unsigned length, PBQPNum initVal) :
+ length(length), data(new PBQPNum[length]) {
+ std::fill(data, data + length, initVal);
+ }
+
+ /// \brief Copy construct a PBQP vector.
+ Vector(const Vector &v) :
+ length(v.length), data(new PBQPNum[length]) {
+ std::copy(v.data, v.data + length, data);
+ }
+
+ /// \brief Destroy this vector, return its memory.
+ ~Vector() { delete[] data; }
+
+ /// \brief Assignment operator.
+ Vector& operator=(const Vector &v) {
+ delete[] data;
+ length = v.length;
+ data = new PBQPNum[length];
+ std::copy(v.data, v.data + length, data);
+ return *this;
+ }
+
+ /// \brief Return the length of the vector
+ unsigned getLength() const {
+ return length;
+ }
+
+ /// \brief Element access.
+ PBQPNum& operator[](unsigned index) {
+ assert(index < length && "Vector element access out of bounds.");
+ return data[index];
+ }
+
+ /// \brief Const element access.
+ const PBQPNum& operator[](unsigned index) const {
+ assert(index < length && "Vector element access out of bounds.");
+ return data[index];
+ }
+
+ /// \brief Add another vector to this one.
+ Vector& operator+=(const Vector &v) {
+ assert(length == v.length && "Vector length mismatch.");
+ std::transform(data, data + length, v.data, data, std::plus<PBQPNum>());
+ return *this;
+ }
+
+ /// \brief Subtract another vector from this one.
+ Vector& operator-=(const Vector &v) {
+ assert(length == v.length && "Vector length mismatch.");
+ std::transform(data, data + length, v.data, data, std::minus<PBQPNum>());
+ return *this;
+ }
+
+ /// \brief Returns the index of the minimum value in this vector
+ unsigned minIndex() const {
+ return std::min_element(data, data + length) - data;
+ }
+
+ private:
+ unsigned length;
+ PBQPNum *data;
+};
+
+/// \brief Output a textual representation of the given vector on the given
+/// output stream.
+template <typename OStream>
+OStream& operator<<(OStream &os, const Vector &v) {
+ assert((v.getLength() != 0) && "Zero-length vector badness.");
+
+ os << "[ " << v[0];
+ for (unsigned i = 1; i < v.getLength(); ++i) {
+ os << ", " << v[i];
+ }
+ os << " ]";
+
+ return os;
+}
+
+
+/// \brief PBQP Matrix class
+class Matrix {
+ public:
+
+ /// \brief Construct a PBQP Matrix with the given dimensions.
+ Matrix(unsigned rows, unsigned cols) :
+ rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
+ }
+
+ /// \brief Construct a PBQP Matrix with the given dimensions and initial
+ /// value.
+ Matrix(unsigned rows, unsigned cols, PBQPNum initVal) :
+ rows(rows), cols(cols), data(new PBQPNum[rows * cols]) {
+ std::fill(data, data + (rows * cols), initVal);
+ }
+
+ /// \brief Copy construct a PBQP matrix.
+ Matrix(const Matrix &m) :
+ rows(m.rows), cols(m.cols), data(new PBQPNum[rows * cols]) {
+ std::copy(m.data, m.data + (rows * cols), data);
+ }
+
+ /// \brief Destroy this matrix, return its memory.
+ ~Matrix() { delete[] data; }
+
+ /// \brief Assignment operator.
+ Matrix& operator=(const Matrix &m) {
+ delete[] data;
+ rows = m.rows; cols = m.cols;
+ data = new PBQPNum[rows * cols];
+ std::copy(m.data, m.data + (rows * cols), data);
+ return *this;
+ }
+
+ /// \brief Return the number of rows in this matrix.
+ unsigned getRows() const { return rows; }
+
+ /// \brief Return the number of cols in this matrix.
+ unsigned getCols() const { return cols; }
+
+ /// \brief Matrix element access.
+ PBQPNum* operator[](unsigned r) {
+ assert(r < rows && "Row out of bounds.");
+ return data + (r * cols);
+ }
+
+ /// \brief Matrix element access.
+ const PBQPNum* operator[](unsigned r) const {
+ assert(r < rows && "Row out of bounds.");
+ return data + (r * cols);
+ }
+
+ /// \brief Returns the given row as a vector.
+ Vector getRowAsVector(unsigned r) const {
+ Vector v(cols);
+ for (unsigned c = 0; c < cols; ++c)
+ v[c] = (*this)[r][c];
+ return v;
+ }
+
+ /// \brief Returns the given column as a vector.
+ Vector getColAsVector(unsigned c) const {
+ Vector v(rows);
+ for (unsigned r = 0; r < rows; ++r)
+ v[r] = (*this)[r][c];
+ return v;
+ }
+
+ /// \brief Reset the matrix to the given value.
+ Matrix& reset(PBQPNum val = 0) {
+ std::fill(data, data + (rows * cols), val);
+ return *this;
+ }
+
+ /// \brief Set a single row of this matrix to the given value.
+ Matrix& setRow(unsigned r, PBQPNum val) {
+ assert(r < rows && "Row out of bounds.");
+ std::fill(data + (r * cols), data + ((r + 1) * cols), val);
+ return *this;
+ }
+
+ /// \brief Set a single column of this matrix to the given value.
+ Matrix& setCol(unsigned c, PBQPNum val) {
+ assert(c < cols && "Column out of bounds.");
+ for (unsigned r = 0; r < rows; ++r)
+ (*this)[r][c] = val;
+ return *this;
+ }
+
+ /// \brief Matrix transpose.
+ Matrix transpose() const {
+ Matrix m(cols, rows);
+ for (unsigned r = 0; r < rows; ++r)
+ for (unsigned c = 0; c < cols; ++c)
+ m[c][r] = (*this)[r][c];
+ return m;
+ }
+
+ /// \brief Returns the diagonal of the matrix as a vector.
+ ///
+ /// Matrix must be square.
+ Vector diagonalize() const {
+ assert(rows == cols && "Attempt to diagonalize non-square matrix.");
+
+ Vector v(rows);
+ for (unsigned r = 0; r < rows; ++r)
+ v[r] = (*this)[r][r];
+ return v;
+ }
+
+ /// \brief Add the given matrix to this one.
+ Matrix& operator+=(const Matrix &m) {
+ assert(rows == m.rows && cols == m.cols &&
+ "Matrix dimensions mismatch.");
+ std::transform(data, data + (rows * cols), m.data, data,
+ std::plus<PBQPNum>());
+ return *this;
+ }
+
+ /// \brief Returns the minimum of the given row
+ PBQPNum getRowMin(unsigned r) const {
+ assert(r < rows && "Row out of bounds");
+ return *std::min_element(data + (r * cols), data + ((r + 1) * cols));
+ }
+
+ /// \brief Returns the minimum of the given column
+ PBQPNum getColMin(unsigned c) const {
+ PBQPNum minElem = (*this)[0][c];
+ for (unsigned r = 1; r < rows; ++r)
+ if ((*this)[r][c] < minElem) minElem = (*this)[r][c];
+ return minElem;
+ }
+
+ /// \brief Subtracts the given scalar from the elements of the given row.
+ Matrix& subFromRow(unsigned r, PBQPNum val) {
+ assert(r < rows && "Row out of bounds");
+ std::transform(data + (r * cols), data + ((r + 1) * cols),
+ data + (r * cols),
+ std::bind2nd(std::minus<PBQPNum>(), val));
+ return *this;
+ }
+
+ /// \brief Subtracts the given scalar from the elements of the given column.
+ Matrix& subFromCol(unsigned c, PBQPNum val) {
+ for (unsigned r = 0; r < rows; ++r)
+ (*this)[r][c] -= val;
+ return *this;
+ }
+
+ /// \brief Returns true if this is a zero matrix.
+ bool isZero() const {
+ return find_if(data, data + (rows * cols),
+ std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) ==
+ data + (rows * cols);
+ }
+
+ private:
+ unsigned rows, cols;
+ PBQPNum *data;
+};
+
+/// \brief Output a textual representation of the given matrix on the given
+/// output stream.
+template <typename OStream>
+OStream& operator<<(OStream &os, const Matrix &m) {
+
+ assert((m.getRows() != 0) && "Zero-row matrix badness.");
+
+ for (unsigned i = 0; i < m.getRows(); ++i) {
+ os << m.getRowAsVector(i);
+ }
+
+ return os;
+}
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_MATH_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h b/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h
new file mode 100644
index 000000000000..57d9b95fc3b1
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PBQP/Solution.h
@@ -0,0 +1,94 @@
+//===-- Solution.h ------- PBQP Solution ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// PBQP Solution class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_SOLUTION_H
+#define LLVM_CODEGEN_PBQP_SOLUTION_H
+
+#include "Math.h"
+#include "Graph.h"
+
+#include <map>
+
+namespace PBQP {
+
+ /// \brief Represents a solution to a PBQP problem.
+ ///
+ /// To get the selection for each node in the problem use the getSelection method.
+ class Solution {
+ private:
+
+ typedef std::map<Graph::ConstNodeItr, unsigned,
+ NodeItrComparator> SelectionsMap;
+ SelectionsMap selections;
+
+ unsigned r0Reductions, r1Reductions, r2Reductions, rNReductions;
+
+ public:
+
+ /// \brief Initialise an empty solution.
+ Solution()
+ : r0Reductions(0), r1Reductions(0), r2Reductions(0), rNReductions(0) {}
+
+ /// \brief Number of nodes for which selections have been made.
+ /// @return Number of nodes for which selections have been made.
+ unsigned numNodes() const { return selections.size(); }
+
+ /// \brief Records a reduction via the R0 rule. Should be called from the
+ /// solver only.
+ void recordR0() { ++r0Reductions; }
+
+ /// \brief Returns the number of R0 reductions applied to solve the problem.
+ unsigned numR0Reductions() const { return r0Reductions; }
+
+ /// \brief Records a reduction via the R1 rule. Should be called from the
+ /// solver only.
+ void recordR1() { ++r1Reductions; }
+
+ /// \brief Returns the number of R1 reductions applied to solve the problem.
+ unsigned numR1Reductions() const { return r1Reductions; }
+
+ /// \brief Records a reduction via the R2 rule. Should be called from the
+ /// solver only.
+ void recordR2() { ++r2Reductions; }
+
+ /// \brief Returns the number of R2 reductions applied to solve the problem.
+ unsigned numR2Reductions() const { return r2Reductions; }
+
+ /// \brief Records a reduction via the RN rule. Should be called from the
+ /// solver only.
+ void recordRN() { ++ rNReductions; }
+
+ /// \brief Returns the number of RN reductions applied to solve the problem.
+ unsigned numRNReductions() const { return rNReductions; }
+
+ /// \brief Set the selection for a given node.
+ /// @param nItr Node iterator.
+ /// @param selection Selection for nItr.
+ void setSelection(Graph::NodeItr nItr, unsigned selection) {
+ selections[nItr] = selection;
+ }
+
+ /// \brief Get a node's selection.
+ /// @param nItr Node iterator.
+ /// @return The selection for nItr;
+ unsigned getSelection(Graph::ConstNodeItr nItr) const {
+ SelectionsMap::const_iterator sItr = selections.find(nItr);
+ assert(sItr != selections.end() && "No selection for node.");
+ return sItr->second;
+ }
+
+ };
+
+}
+
+#endif // LLVM_CODEGEN_PBQP_SOLUTION_H
diff --git a/contrib/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm/include/llvm/CodeGen/Passes.h
new file mode 100644
index 000000000000..e76fe9925721
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/Passes.h
@@ -0,0 +1,452 @@
+//===-- Passes.h - Target independent code generation passes ----*- 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 interfaces to access the target independent code generation
+// passes provided by the LLVM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PASSES_H
+#define LLVM_CODEGEN_PASSES_H
+
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetMachine.h"
+#include <string>
+
+namespace llvm {
+
+ class FunctionPass;
+ class MachineFunctionPass;
+ class PassInfo;
+ class TargetLowering;
+ class TargetRegisterClass;
+ class raw_ostream;
+}
+
+namespace llvm {
+
+extern char &NoPassID; // Allow targets to choose not to run a pass.
+
+class PassConfigImpl;
+
+/// Target-Independent Code Generator Pass Configuration Options.
+///
+/// This is an ImmutablePass solely for the purpose of exposing CodeGen options
+/// to the internals of other CodeGen passes.
+class TargetPassConfig : public ImmutablePass {
+public:
+ /// Pseudo Pass IDs. These are defined within TargetPassConfig because they
+ /// are unregistered pass IDs. They are only useful for use with
+ /// TargetPassConfig APIs to identify multiple occurrences of the same pass.
+ ///
+
+ /// EarlyTailDuplicate - A clone of the TailDuplicate pass that runs early
+ /// during codegen, on SSA form.
+ static char EarlyTailDuplicateID;
+
+ /// PostRAMachineLICM - A clone of the LICM pass that runs during late machine
+ /// optimization after regalloc.
+ static char PostRAMachineLICMID;
+
+protected:
+ TargetMachine *TM;
+ PassManagerBase *PM;
+ PassConfigImpl *Impl; // Internal data structures
+ bool Initialized; // Flagged after all passes are configured.
+
+ // Target Pass Options
+ // Targets provide a default setting, user flags override.
+ //
+ bool DisableVerify;
+
+ /// Default setting for -enable-tail-merge on this target.
+ bool EnableTailMerge;
+
+public:
+ TargetPassConfig(TargetMachine *tm, PassManagerBase &pm);
+ // Dummy constructor.
+ TargetPassConfig();
+
+ virtual ~TargetPassConfig();
+
+ static char ID;
+
+ /// Get the right type of TargetMachine for this target.
+ template<typename TMC> TMC &getTM() const {
+ return *static_cast<TMC*>(TM);
+ }
+
+ const TargetLowering *getTargetLowering() const {
+ return TM->getTargetLowering();
+ }
+
+ //
+ void setInitialized() { Initialized = true; }
+
+ CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
+
+ void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
+
+ bool getEnableTailMerge() const { return EnableTailMerge; }
+ void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
+
+ /// Allow the target to override a specific pass without overriding the pass
+ /// pipeline. When passes are added to the standard pipeline at the
+ /// point where StadardID is expected, add TargetID in its place.
+ void substitutePass(char &StandardID, char &TargetID);
+
+ /// Allow the target to enable a specific standard pass by default.
+ void enablePass(char &ID) { substitutePass(ID, ID); }
+
+ /// Allow the target to disable a specific standard pass by default.
+ void disablePass(char &ID) { substitutePass(ID, NoPassID); }
+
+ /// Return the pass ssubtituted for StandardID by the target.
+ /// If no substitution exists, return StandardID.
+ AnalysisID getPassSubstitution(AnalysisID StandardID) const;
+
+ /// Return true if the optimized regalloc pipeline is enabled.
+ bool getOptimizeRegAlloc() const;
+
+ /// Add common target configurable passes that perform LLVM IR to IR
+ /// transforms following machine independent optimization.
+ virtual void addIRPasses();
+
+ /// Add common passes that perform LLVM IR to IR transforms in preparation for
+ /// instruction selection.
+ virtual void addISelPrepare();
+
+ /// addInstSelector - This method should install an instruction selector pass,
+ /// which converts from LLVM code to machine instructions.
+ virtual bool addInstSelector() {
+ return true;
+ }
+
+ /// Add the complete, standard set of LLVM CodeGen passes.
+ /// Fully developed targets will not generally override this.
+ virtual void addMachinePasses();
+
+protected:
+ // Helper to verify the analysis is really immutable.
+ void setOpt(bool &Opt, bool Val);
+
+ /// Methods with trivial inline returns are convenient points in the common
+ /// codegen pass pipeline where targets may insert passes. Methods with
+ /// out-of-line standard implementations are major CodeGen stages called by
+ /// addMachinePasses. Some targets may override major stages when inserting
+ /// passes is insufficient, but maintaining overriden stages is more work.
+ ///
+
+ /// addPreISelPasses - This method should add any "last minute" LLVM->LLVM
+ /// passes (which are run just before instruction selector).
+ virtual bool addPreISel() {
+ return true;
+ }
+
+ /// addMachineSSAOptimization - Add standard passes that optimize machine
+ /// instructions in SSA form.
+ virtual void addMachineSSAOptimization();
+
+ /// addPreRegAlloc - This method may be implemented by targets that want to
+ /// run passes immediately before register allocation. This should return
+ /// true if -print-machineinstrs should print after these passes.
+ virtual bool addPreRegAlloc() {
+ return false;
+ }
+
+ /// createTargetRegisterAllocator - Create the register allocator pass for
+ /// this target at the current optimization level.
+ virtual FunctionPass *createTargetRegisterAllocator(bool Optimized);
+
+ /// addFastRegAlloc - Add the minimum set of target-independent passes that
+ /// are required for fast register allocation.
+ virtual void addFastRegAlloc(FunctionPass *RegAllocPass);
+
+ /// addOptimizedRegAlloc - Add passes related to register allocation.
+ /// LLVMTargetMachine provides standard regalloc passes for most targets.
+ virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
+
+ /// addFinalizeRegAlloc - This method may be implemented by targets that want
+ /// to run passes within the regalloc pipeline, immediately after the register
+ /// allocation pass itself. These passes run as soon as virtual regisiters
+ /// have been rewritten to physical registers but before and other postRA
+ /// optimization happens. Targets that have marked instructions for bundling
+ /// must have finalized those bundles by the time these passes have run,
+ /// because subsequent passes are not guaranteed to be bundle-aware.
+ virtual bool addFinalizeRegAlloc() {
+ return false;
+ }
+
+ /// addPostRegAlloc - This method may be implemented by targets that want to
+ /// run passes after register allocation pass pipeline but before
+ /// prolog-epilog insertion. This should return true if -print-machineinstrs
+ /// should print after these passes.
+ virtual bool addPostRegAlloc() {
+ return false;
+ }
+
+ /// Add passes that optimize machine instructions after register allocation.
+ virtual void addMachineLateOptimization();
+
+ /// addPreSched2 - This method may be implemented by targets that want to
+ /// run passes after prolog-epilog insertion and before the second instruction
+ /// scheduling pass. This should return true if -print-machineinstrs should
+ /// print after these passes.
+ virtual bool addPreSched2() {
+ return false;
+ }
+
+ /// Add standard basic block placement passes.
+ virtual void addBlockPlacement();
+
+ /// addPreEmitPass - This pass may be implemented by targets that want to run
+ /// passes immediately before machine code is emitted. This should return
+ /// true if -print-machineinstrs should print out the code after the passes.
+ virtual bool addPreEmitPass() {
+ return false;
+ }
+
+ /// Utilities for targets to add passes to the pass manager.
+ ///
+
+ /// Add a CodeGen pass at this point in the pipeline after checking overrides.
+ /// Return the pass that was added, or NoPassID.
+ AnalysisID addPass(char &ID);
+
+ /// addMachinePasses helper to create the target-selected or overriden
+ /// regalloc pass.
+ FunctionPass *createRegAllocPass(bool Optimized);
+
+ /// printAndVerify - Add a pass to dump then verify the machine function, if
+ /// those steps are enabled.
+ ///
+ void printAndVerify(const char *Banner) const;
+};
+} // namespace llvm
+
+/// List of target independent CodeGen pass IDs.
+namespace llvm {
+ /// 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
+ /// not instruction select unreachable blocks, or run this pass as its
+ /// last LLVM modifying pass to clean up blocks that are not reachable from
+ /// the entry block.
+ FunctionPass *createUnreachableBlockEliminationPass();
+
+ /// MachineFunctionPrinter pass - This pass prints out the machine function to
+ /// the given stream as a debugging tool.
+ MachineFunctionPass *
+ createMachineFunctionPrinterPass(raw_ostream &OS,
+ const std::string &Banner ="");
+
+ /// 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;
+
+ /// EdgeBundles analysis - Bundle machine CFG edges.
+ extern char &EdgeBundlesID;
+
+ /// LiveVariables pass - This pass computes the set of blocks in which each
+ /// variable is life and sets machine operand kill flags.
+ extern char &LiveVariablesID;
+
+ /// PHIElimination - This pass eliminates machine instruction PHI nodes
+ /// by inserting copy instructions. This destroys SSA information, but is the
+ /// desired input for some register allocators. This pass is "required" by
+ /// these register allocator like this: AU.addRequiredID(PHIEliminationID);
+ extern char &PHIEliminationID;
+
+ /// StrongPHIElimination - This pass eliminates machine instruction PHI
+ /// nodes by inserting copy instructions. This destroys SSA information, but
+ /// is the desired input for some register allocators. This pass is
+ /// "required" by these register allocator like this:
+ /// AU.addRequiredID(PHIEliminationID);
+ /// This pass is still in development
+ extern char &StrongPHIEliminationID;
+
+ /// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
+ extern char &LiveStacksID;
+
+ /// TwoAddressInstruction - This pass reduces two-address instructions to
+ /// use two operands. This destroys SSA information but it is desired by
+ /// register allocators.
+ extern char &TwoAddressInstructionPassID;
+
+ /// ProcessImpicitDefs pass - This pass removes IMPLICIT_DEFs.
+ extern char &ProcessImplicitDefsID;
+
+ /// RegisterCoalescer - This pass merges live ranges to eliminate copies.
+ extern char &RegisterCoalescerID;
+
+ /// MachineScheduler - This pass schedules machine instructions.
+ extern char &MachineSchedulerID;
+
+ /// SpillPlacement analysis. Suggest optimal placement of spill code between
+ /// basic blocks.
+ extern char &SpillPlacementID;
+
+ /// UnreachableMachineBlockElimination - This pass removes unreachable
+ /// machine basic blocks.
+ extern char &UnreachableMachineBlockElimID;
+
+ /// DeadMachineInstructionElim - This pass removes dead machine instructions.
+ extern char &DeadMachineInstructionElimID;
+
+ /// FastRegisterAllocation Pass - This pass register allocates as fast as
+ /// possible. It is best suited for debug code where live ranges are short.
+ ///
+ FunctionPass *createFastRegisterAllocator();
+
+ /// BasicRegisterAllocation Pass - This pass implements a degenerate global
+ /// register allocator using the basic regalloc framework.
+ ///
+ FunctionPass *createBasicRegisterAllocator();
+
+ /// Greedy register allocation pass - This pass implements a global register
+ /// allocator for optimized builds.
+ ///
+ FunctionPass *createGreedyRegisterAllocator();
+
+ /// PBQPRegisterAllocation Pass - This pass implements the Partitioned Boolean
+ /// Quadratic Prograaming (PBQP) based register allocator.
+ ///
+ FunctionPass *createDefaultPBQPRegisterAllocator();
+
+ /// PrologEpilogCodeInserter - This pass inserts prolog and epilog code,
+ /// and eliminates abstract frame references.
+ extern char &PrologEpilogCodeInserterID;
+
+ /// ExpandPostRAPseudos - This pass expands pseudo instructions after
+ /// register allocation.
+ extern char &ExpandPostRAPseudosID;
+
+ /// createPostRAScheduler - This pass performs post register allocation
+ /// scheduling.
+ extern char &PostRASchedulerID;
+
+ /// BranchFolding - This pass performs machine code CFG based
+ /// optimizations to delete branches to branches, eliminate branches to
+ /// successor blocks (creating fall throughs), and eliminating branches over
+ /// branches.
+ extern char &BranchFolderPassID;
+
+ /// TailDuplicate - Duplicate blocks with unconditional branches
+ /// into tails of their predecessors.
+ extern char &TailDuplicateID;
+
+ /// IfConverter - This pass performs machine code if conversion.
+ extern char &IfConverterID;
+
+ /// MachineBlockPlacement - This pass places basic blocks based on branch
+ /// probabilities.
+ extern char &MachineBlockPlacementID;
+
+ /// MachineBlockPlacementStats - This pass collects statistics about the
+ /// basic block placement using branch probabilities and block frequency
+ /// information.
+ extern char &MachineBlockPlacementStatsID;
+
+ /// Code Placement - This pass optimize code placement and aligns loop
+ /// headers to target specific alignment boundary.
+ extern char &CodePlacementOptID;
+
+ /// GCLowering Pass - Performs target-independent LLVM IR transformations for
+ /// highly portable strategies.
+ ///
+ FunctionPass *createGCLoweringPass();
+
+ /// GCMachineCodeAnalysis - Target-independent pass to mark safe points
+ /// in machine code. Must be added very late during code generation, just
+ /// prior to output, and importantly after all CFG transformations (such as
+ /// branch folding).
+ extern char &GCMachineCodeAnalysisID;
+
+ /// Deleter Pass - Releases GC metadata.
+ ///
+ FunctionPass *createGCInfoDeleter();
+
+ /// Creates a pass to print GC metadata.
+ ///
+ FunctionPass *createGCInfoPrinter(raw_ostream &OS);
+
+ /// MachineCSE - This pass performs global CSE on machine instructions.
+ extern char &MachineCSEID;
+
+ /// MachineLICM - This pass performs LICM on machine instructions.
+ extern char &MachineLICMID;
+
+ /// MachineSinking - This pass performs sinking on machine instructions.
+ extern char &MachineSinkingID;
+
+ /// MachineCopyPropagation - This pass performs copy propagation on
+ /// machine instructions.
+ extern char &MachineCopyPropagationID;
+
+ /// PeepholeOptimizer - This pass performs peephole optimizations -
+ /// like extension and comparison eliminations.
+ extern char &PeepholeOptimizerID;
+
+ /// OptimizePHIs - This pass optimizes machine instruction PHIs
+ /// to take advantage of opportunities created during DAG legalization.
+ extern char &OptimizePHIsID;
+
+ /// StackSlotColoring - This pass performs stack slot coloring.
+ extern char &StackSlotColoringID;
+
+ /// createStackProtectorPass - This pass adds stack protectors to functions.
+ ///
+ FunctionPass *createStackProtectorPass(const TargetLowering *tli);
+
+ /// createMachineVerifierPass - This pass verifies cenerated machine code
+ /// instructions for correctness.
+ ///
+ FunctionPass *createMachineVerifierPass(const char *Banner = 0);
+
+ /// createDwarfEHPass - This pass mulches exception handling code into a form
+ /// adapted to code generation. Required if using dwarf exception handling.
+ FunctionPass *createDwarfEHPass(const TargetMachine *tm);
+
+ /// createSjLjEHPreparePass - This pass adapts exception handling code to use
+ /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
+ ///
+ FunctionPass *createSjLjEHPreparePass(const TargetLowering *tli);
+
+ /// LocalStackSlotAllocation - This pass assigns local frame indices to stack
+ /// slots relative to one another and allocates base registers to access them
+ /// when it is estimated by the target to be out of range of normal frame
+ /// pointer or stack pointer index addressing.
+ extern char &LocalStackSlotAllocationID;
+
+ /// ExpandISelPseudos - This pass expands pseudo-instructions.
+ extern char &ExpandISelPseudosID;
+
+ /// createExecutionDependencyFixPass - This pass fixes execution time
+ /// problems with dependent instructions, such as switching execution
+ /// domains to match.
+ ///
+ /// The pass will examine instructions using and defining registers in RC.
+ ///
+ FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC);
+
+ /// UnpackMachineBundles - This pass unpack machine instruction bundles.
+ extern char &UnpackMachineBundlesID;
+
+ /// FinalizeMachineBundles - This pass finalize machine instruction
+ /// bundles (created earlier, e.g. during pre-RA scheduling).
+ extern char &FinalizeMachineBundlesID;
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ProcessImplicitDefs.h b/contrib/llvm/include/llvm/CodeGen/ProcessImplicitDefs.h
new file mode 100644
index 000000000000..6ab57f03aee7
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ProcessImplicitDefs.h
@@ -0,0 +1,51 @@
+//===-------------- llvm/CodeGen/ProcessImplicitDefs.h ----------*- 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_PROCESSIMPLICITDEFS_H
+#define LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace llvm {
+
+ class MachineInstr;
+ class TargetInstrInfo;
+ class TargetRegisterInfo;
+ class MachineRegisterInfo;
+ class LiveVariables;
+
+ /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def
+ /// for each use. Add isUndef marker to implicit_def defs and their uses.
+ class ProcessImplicitDefs : public MachineFunctionPass {
+ const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+ MachineRegisterInfo *MRI;
+ LiveVariables *LV;
+
+ bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg,
+ unsigned OpIdx,
+ SmallSet<unsigned, 8> &ImpDefRegs);
+
+ public:
+ static char ID;
+
+ ProcessImplicitDefs() : MachineFunctionPass(ID) {
+ initializeProcessImplicitDefsPass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &au) const;
+
+ virtual bool runOnMachineFunction(MachineFunction &fn);
+ };
+
+}
+
+#endif // LLVM_CODEGEN_PROCESSIMPLICITDEFS_H
diff --git a/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h
new file mode 100644
index 000000000000..7dab4f948628
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/PseudoSourceValue.h
@@ -0,0 +1,112 @@
+//===-- llvm/CodeGen/PseudoSourceValue.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 the declaration of the PseudoSourceValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
+#define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
+
+#include "llvm/Value.h"
+
+namespace llvm {
+ class MachineFrameInfo;
+ class raw_ostream;
+
+ /// PseudoSourceValue - Special value supplied for machine level alias
+ /// analysis. It indicates that a memory access references the functions
+ /// stack frame (e.g., a spill slot), below the stack frame (e.g., argument
+ /// space), or constant pool.
+ class PseudoSourceValue : public Value {
+ private:
+ /// printCustom - Implement printing for PseudoSourceValue. This is called
+ /// from Value::print or Value's operator<<.
+ ///
+ virtual void printCustom(raw_ostream &O) const;
+
+ public:
+ explicit PseudoSourceValue(enum ValueTy Subclass = PseudoSourceValueVal);
+
+ /// isConstant - Test whether the memory pointed to by this
+ /// PseudoSourceValue has a constant value.
+ ///
+ virtual bool isConstant(const MachineFrameInfo *) const;
+
+ /// isAliased - Test whether the memory pointed to by this
+ /// PseudoSourceValue may also be pointed to by an LLVM IR Value.
+ virtual bool isAliased(const MachineFrameInfo *) const;
+
+ /// mayAlias - Return true if the memory pointed to by this
+ /// PseudoSourceValue can ever alias a LLVM IR Value.
+ virtual bool mayAlias(const MachineFrameInfo *) const;
+
+ /// 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;
+ }
+
+ /// A pseudo source value referencing a fixed stack frame entry,
+ /// e.g., a spill slot.
+ static const PseudoSourceValue *getFixedStack(int FI);
+
+ /// A pseudo source value referencing the area below the stack frame of
+ /// a function, e.g., the argument space.
+ static const PseudoSourceValue *getStack();
+
+ /// A pseudo source value referencing the global offset table
+ /// (or something the like).
+ static const PseudoSourceValue *getGOT();
+
+ /// A pseudo source value referencing the constant pool. Since constant
+ /// pools are constant, this doesn't need to identify a specific constant
+ /// pool entry.
+ static const PseudoSourceValue *getConstantPool();
+
+ /// A pseudo source value referencing a jump table. Since jump tables are
+ /// constant, this doesn't need to identify a specific jump table.
+ static const PseudoSourceValue *getJumpTable();
+ };
+
+ /// FixedStackPseudoSourceValue - A specialized PseudoSourceValue
+ /// for holding FixedStack values, which must include a frame
+ /// index.
+ class FixedStackPseudoSourceValue : public PseudoSourceValue {
+ const int FI;
+ public:
+ explicit FixedStackPseudoSourceValue(int fi) :
+ PseudoSourceValue(FixedStackPseudoSourceValueVal), FI(fi) {}
+
+ /// 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;
+ }
+
+ virtual bool isConstant(const MachineFrameInfo *MFI) const;
+
+ virtual bool isAliased(const MachineFrameInfo *MFI) const;
+
+ virtual bool mayAlias(const MachineFrameInfo *) const;
+
+ virtual void printCustom(raw_ostream &OS) const;
+
+ int getFrameIndex() const { return FI; }
+ };
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h
new file mode 100644
index 000000000000..bce3ec739b61
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/RegAllocPBQP.h
@@ -0,0 +1,168 @@
+//===-- RegAllocPBQP.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 defines the PBQPBuilder interface, for classes which build PBQP
+// instances to represent register allocation problems, and the RegAllocPBQP
+// interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGALLOCPBQP_H
+#define LLVM_CODEGEN_REGALLOCPBQP_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/PBQP/Graph.h"
+#include "llvm/CodeGen/PBQP/Solution.h"
+
+#include <map>
+#include <set>
+
+namespace llvm {
+
+ class LiveIntervals;
+ class MachineFunction;
+ class MachineLoopInfo;
+
+ /// This class wraps up a PBQP instance representing a register allocation
+ /// problem, plus the structures necessary to map back from the PBQP solution
+ /// to a register allocation solution. (i.e. The PBQP-node <--> vreg map,
+ /// and the PBQP option <--> storage location map).
+
+ class PBQPRAProblem {
+ public:
+
+ typedef SmallVector<unsigned, 16> AllowedSet;
+
+ PBQP::Graph& getGraph() { return graph; }
+
+ const PBQP::Graph& getGraph() const { return graph; }
+
+ /// Record the mapping between the given virtual register and PBQP node,
+ /// and the set of allowed pregs for the vreg.
+ ///
+ /// If you are extending
+ /// PBQPBuilder you are unlikely to need this: Nodes and options for all
+ /// vregs will already have been set up for you by the base class.
+ template <typename AllowedRegsItr>
+ void recordVReg(unsigned vreg, PBQP::Graph::NodeItr node,
+ AllowedRegsItr arBegin, AllowedRegsItr arEnd) {
+ assert(node2VReg.find(node) == node2VReg.end() && "Re-mapping node.");
+ assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg.");
+ assert(allowedSets[vreg].empty() && "vreg already has pregs.");
+
+ node2VReg[node] = vreg;
+ vreg2Node[vreg] = node;
+ std::copy(arBegin, arEnd, std::back_inserter(allowedSets[vreg]));
+ }
+
+ /// Get the virtual register corresponding to the given PBQP node.
+ unsigned getVRegForNode(PBQP::Graph::ConstNodeItr node) const;
+
+ /// Get the PBQP node corresponding to the given virtual register.
+ PBQP::Graph::NodeItr getNodeForVReg(unsigned vreg) const;
+
+ /// Returns true if the given PBQP option represents a physical register,
+ /// false otherwise.
+ bool isPRegOption(unsigned vreg, unsigned option) const {
+ // At present we only have spills or pregs, so anything that's not a
+ // spill is a preg. (This might be extended one day to support remat).
+ return !isSpillOption(vreg, option);
+ }
+
+ /// Returns true if the given PBQP option represents spilling, false
+ /// otherwise.
+ bool isSpillOption(unsigned vreg, unsigned option) const {
+ // We hardcode option zero as the spill option.
+ return option == 0;
+ }
+
+ /// Returns the allowed set for the given virtual register.
+ const AllowedSet& getAllowedSet(unsigned vreg) const;
+
+ /// Get PReg for option.
+ unsigned getPRegForOption(unsigned vreg, unsigned option) const;
+
+ private:
+
+ typedef std::map<PBQP::Graph::ConstNodeItr, unsigned,
+ PBQP::NodeItrComparator> Node2VReg;
+ typedef DenseMap<unsigned, PBQP::Graph::NodeItr> VReg2Node;
+ typedef DenseMap<unsigned, AllowedSet> AllowedSetMap;
+
+ PBQP::Graph graph;
+ Node2VReg node2VReg;
+ VReg2Node vreg2Node;
+
+ AllowedSetMap allowedSets;
+
+ };
+
+ /// Builds PBQP instances to represent register allocation problems. Includes
+ /// spill, interference and coalescing costs by default. You can extend this
+ /// class to support additional constraints for your architecture.
+ class PBQPBuilder {
+ private:
+ PBQPBuilder(const PBQPBuilder&) {}
+ void operator=(const PBQPBuilder&) {}
+ public:
+
+ typedef std::set<unsigned> RegSet;
+
+ /// Default constructor.
+ PBQPBuilder() {}
+
+ /// Clean up a PBQPBuilder.
+ virtual ~PBQPBuilder() {}
+
+ /// Build a PBQP instance to represent the register allocation problem for
+ /// the given MachineFunction.
+ virtual std::auto_ptr<PBQPRAProblem> build(
+ MachineFunction *mf,
+ const LiveIntervals *lis,
+ const MachineLoopInfo *loopInfo,
+ const RegSet &vregs);
+ private:
+
+ void addSpillCosts(PBQP::Vector &costVec, PBQP::PBQPNum spillCost);
+
+ void addInterferenceCosts(PBQP::Matrix &costMat,
+ const PBQPRAProblem::AllowedSet &vr1Allowed,
+ const PBQPRAProblem::AllowedSet &vr2Allowed,
+ const TargetRegisterInfo *tri);
+ };
+
+ /// Extended builder which adds coalescing constraints to a problem.
+ class PBQPBuilderWithCoalescing : public PBQPBuilder {
+ public:
+
+ /// Build a PBQP instance to represent the register allocation problem for
+ /// the given MachineFunction.
+ virtual std::auto_ptr<PBQPRAProblem> build(
+ MachineFunction *mf,
+ const LiveIntervals *lis,
+ const MachineLoopInfo *loopInfo,
+ const RegSet &vregs);
+
+ private:
+
+ void addPhysRegCoalesce(PBQP::Vector &costVec, unsigned pregOption,
+ PBQP::PBQPNum benefit);
+
+ void addVirtRegCoalesce(PBQP::Matrix &costMat,
+ const PBQPRAProblem::AllowedSet &vr1Allowed,
+ const PBQPRAProblem::AllowedSet &vr2Allowed,
+ PBQP::PBQPNum benefit);
+ };
+
+ FunctionPass* createPBQPRegisterAllocator(std::auto_ptr<PBQPBuilder> builder,
+ char *customPassID=0);
+}
+
+#endif /* LLVM_CODEGEN_REGALLOCPBQP_H */
diff --git a/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h
new file mode 100644
index 000000000000..100e357654fb
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/RegAllocRegistry.h
@@ -0,0 +1,66 @@
+//===-- llvm/CodeGen/RegAllocRegistry.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 the implementation for register allocator function
+// pass registry (RegisterRegAlloc).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGENREGALLOCREGISTRY_H
+#define LLVM_CODEGENREGALLOCREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterRegAlloc class - Track the registration of register allocators.
+///
+//===----------------------------------------------------------------------===//
+class RegisterRegAlloc : public MachinePassRegistryNode {
+
+public:
+
+ typedef FunctionPass *(*FunctionPassCtor)();
+
+ static MachinePassRegistry Registry;
+
+ RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+ {
+ Registry.Add(this);
+ }
+ ~RegisterRegAlloc() { Registry.Remove(this); }
+
+
+ // Accessors.
+ //
+ RegisterRegAlloc *getNext() const {
+ return (RegisterRegAlloc *)MachinePassRegistryNode::getNext();
+ }
+ static RegisterRegAlloc *getList() {
+ return (RegisterRegAlloc *)Registry.getList();
+ }
+ static FunctionPassCtor getDefault() {
+ return (FunctionPassCtor)Registry.getDefault();
+ }
+ static void setDefault(FunctionPassCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+
+};
+
+} // end namespace llvm
+
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h
new file mode 100644
index 000000000000..3986a8dd7da1
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/RegisterScavenging.h
@@ -0,0 +1,170 @@
+//===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the machine register scavenger class. It can provide
+// information such as unused register at any point in a machine basic block.
+// It also provides a mechanism to make registers availbale by evicting them
+// to spill slots.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
+#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/ADT/BitVector.h"
+
+namespace llvm {
+
+class MachineRegisterInfo;
+class TargetRegisterInfo;
+class TargetInstrInfo;
+class TargetRegisterClass;
+
+class RegScavenger {
+ const TargetRegisterInfo *TRI;
+ const TargetInstrInfo *TII;
+ MachineRegisterInfo* MRI;
+ MachineBasicBlock *MBB;
+ MachineBasicBlock::iterator MBBI;
+ unsigned NumPhysRegs;
+
+ /// Tracking - True if RegScavenger is currently tracking the liveness of
+ /// registers.
+ bool Tracking;
+
+ /// ScavengingFrameIndex - Special spill slot used for scavenging a register
+ /// post register allocation.
+ int ScavengingFrameIndex;
+
+ /// ScavengedReg - If none zero, the specific register is currently being
+ /// scavenged. That is, it is spilled to the special scavenging stack slot.
+ unsigned ScavengedReg;
+
+ /// ScavengedRC - Register class of the scavenged register.
+ ///
+ const TargetRegisterClass *ScavengedRC;
+
+ /// ScavengeRestore - Instruction that restores the scavenged register from
+ /// stack.
+ const MachineInstr *ScavengeRestore;
+
+ /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
+ ///
+ 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.
+ BitVector RegsAvailable;
+
+ // These BitVectors are only used internally to forward(). They are members
+ // to avoid frequent reallocations.
+ BitVector KillRegs, DefRegs;
+
+public:
+ RegScavenger()
+ : MBB(NULL), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {}
+
+ /// enterBasicBlock - Start tracking liveness from the begin of the specific
+ /// basic block.
+ void enterBasicBlock(MachineBasicBlock *mbb);
+
+ /// initRegState - allow resetting register state info for multiple
+ /// passes over/within the same function.
+ void initRegState();
+
+ /// forward - Move the internal MBB iterator and update register states.
+ void forward();
+
+ /// forward - Move the internal MBB iterator and update register states until
+ /// it has processed the specific iterator.
+ void forward(MachineBasicBlock::iterator I) {
+ if (!Tracking && MBB->begin() != I) forward();
+ while (MBBI != I) forward();
+ }
+
+ /// skipTo - Move the internal MBB iterator but do not update register states.
+ ///
+ void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
+
+ /// getRegsUsed - return all registers currently in use in used.
+ void getRegsUsed(BitVector &used, bool includeReserved);
+
+ /// getRegsAvailable - Return all available registers in the register class
+ /// in Mask.
+ BitVector getRegsAvailable(const TargetRegisterClass *RC);
+
+ /// FindUnusedReg - Find a unused register of the specified register class.
+ /// Return 0 if none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const;
+
+ /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
+ /// ScavengingFrameIndex.
+ void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
+ int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
+
+ /// scavengeRegister - Make a register of the specific register class
+ /// available and do the appropriate bookkeeping. SPAdj is the stack
+ /// adjustment due to call frame, it's passed along to eliminateFrameIndex().
+ /// Returns the scavenged register.
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass,
+ MachineBasicBlock::iterator I, int SPAdj);
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
+ return scavengeRegister(RegClass, MBBI, SPAdj);
+ }
+
+ /// setUsed - Tell the scavenger a register is used.
+ ///
+ 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); }
+
+ /// isUsed / isUnused - Test if a register is currently being used.
+ ///
+ bool isUsed(unsigned Reg) const {
+ return !RegsAvailable.test(Reg) || ReservedRegs.test(Reg);
+ }
+
+ /// isAliasUsed - Is Reg or an alias currently in use?
+ bool isAliasUsed(unsigned Reg) const;
+
+ /// setUsed / setUnused - Mark the state of one or a number of registers.
+ ///
+ void setUsed(BitVector &Regs) {
+ RegsAvailable.reset(Regs);
+ }
+ void setUnused(BitVector &Regs) {
+ RegsAvailable |= Regs;
+ }
+
+ /// Add Reg and all its sub-registers to BV.
+ void addRegWithSubRegs(BitVector &BV, unsigned Reg);
+
+ /// findSurvivorReg - Return the candidate register that is unused for the
+ /// longest after StartMI. UseMI is set to the instruction where the search
+ /// stopped.
+ ///
+ /// No more than InstrLimit instructions are inspected.
+ unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI,
+ BitVector &Candidates,
+ unsigned InstrLimit,
+ MachineBasicBlock::iterator &UseMI);
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h b/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h
new file mode 100644
index 000000000000..56b5855c01c9
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -0,0 +1,142 @@
+//===----- ResourcePriorityQueue.h - A DFA-oriented priority queue -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ResourcePriorityQueue class, which is a
+// SchedulingPriorityQueue that schedules using DFA state to
+// reduce the length of the critical path through the basic block
+// on VLIW platforms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RESOURCE_PRIORITY_QUEUE_H
+#define RESOURCE_PRIORITY_QUEUE_H
+
+#include "llvm/CodeGen/DFAPacketizer.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+namespace llvm {
+ class ResourcePriorityQueue;
+
+ /// Sorting functions for the Available queue.
+ struct resource_sort : public std::binary_function<SUnit*, SUnit*, bool> {
+ ResourcePriorityQueue *PQ;
+ explicit resource_sort(ResourcePriorityQueue *pq) : PQ(pq) {}
+
+ bool operator()(const SUnit* left, const SUnit* right) const;
+ };
+
+ class ResourcePriorityQueue : public SchedulingPriorityQueue {
+ /// SUnits - The SUnits for the current graph.
+ std::vector<SUnit> *SUnits;
+
+ /// NumNodesSolelyBlocking - This vector contains, for every node in the
+ /// Queue, the number of nodes that the node is the sole unscheduled
+ /// predecessor for. This is used as a tie-breaker heuristic for better
+ /// mobility.
+ std::vector<unsigned> NumNodesSolelyBlocking;
+
+ /// Queue - The queue.
+ std::vector<SUnit*> Queue;
+
+ /// RegPressure - Tracking current reg pressure per register class.
+ ///
+ std::vector<unsigned> RegPressure;
+
+ /// RegLimit - Tracking the number of allocatable registers per register
+ /// class.
+ std::vector<unsigned> RegLimit;
+
+ resource_sort Picker;
+ const TargetRegisterInfo *TRI;
+ const TargetLowering *TLI;
+ const TargetInstrInfo *TII;
+ const InstrItineraryData* InstrItins;
+ /// ResourcesModel - Represents VLIW state.
+ /// Not limited to VLIW targets per say, but assumes
+ /// definition of DFA by a target.
+ DFAPacketizer *ResourcesModel;
+
+ /// Resource model - packet/bundle model. Purely
+ /// internal at the time.
+ std::vector<SUnit*> Packet;
+
+ /// Heuristics for estimating register pressure.
+ unsigned ParallelLiveRanges;
+ signed HorizontalVerticalBalance;
+
+ public:
+ ResourcePriorityQueue(SelectionDAGISel *IS);
+
+ ~ResourcePriorityQueue() {
+ delete ResourcesModel;
+ }
+
+ bool isBottomUp() const { return false; }
+
+ void initNodes(std::vector<SUnit> &sunits);
+
+ void addNode(const SUnit *SU) {
+ NumNodesSolelyBlocking.resize(SUnits->size(), 0);
+ }
+
+ void updateNode(const SUnit *SU) {}
+
+ void releaseState() {
+ SUnits = 0;
+ }
+
+ unsigned getLatency(unsigned NodeNum) const {
+ assert(NodeNum < (*SUnits).size());
+ return (*SUnits)[NodeNum].getHeight();
+ }
+
+ unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
+ assert(NodeNum < NumNodesSolelyBlocking.size());
+ return NumNodesSolelyBlocking[NodeNum];
+ }
+
+ /// Single cost function reflecting benefit of scheduling SU
+ /// in the current cycle.
+ signed SUSchedulingCost (SUnit *SU);
+
+ /// InitNumRegDefsLeft - Determine the # of regs defined by this node.
+ ///
+ void initNumRegDefsLeft(SUnit *SU);
+ void updateNumRegDefsLeft(SUnit *SU);
+ signed regPressureDelta(SUnit *SU, bool RawPressure = false);
+ signed rawRegPressureDelta (SUnit *SU, unsigned RCId);
+
+ bool empty() const { return Queue.empty(); }
+
+ virtual void push(SUnit *U);
+
+ virtual SUnit *pop();
+
+ virtual void remove(SUnit *SU);
+
+ virtual void dump(ScheduleDAG* DAG) const;
+
+ /// scheduledNode - Main resource tracking point.
+ void scheduledNode(SUnit *Node);
+ bool isResourceAvailable(SUnit *SU);
+ void reserveResources(SUnit *SU);
+
+private:
+ void adjustPriorityOfUnscheduledPreds(SUnit *SU);
+ SUnit *getSingleUnscheduledPred(SUnit *SU);
+ unsigned numberRCValPredInSU (SUnit *SU, unsigned RCId);
+ unsigned numberRCValSuccInSU (SUnit *SU, unsigned RCId);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h
new file mode 100644
index 000000000000..4bfd4ab530d1
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -0,0 +1,330 @@
+//===-- CodeGen/RuntimeLibcall.h - Runtime Library Calls --------*- 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 enum representing the list of runtime library calls
+// the backend may emit during code generation, and also some helper functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_RUNTIMELIBCALLS_H
+#define LLVM_CODEGEN_RUNTIMELIBCALLS_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+namespace RTLIB {
+ /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
+ /// the backend can emit. The various long double types cannot be merged,
+ /// because 80-bit library functions use "xf" and 128-bit use "tf".
+ ///
+ /// When adding PPCF128 functions here, note that their names generally need
+ /// to be overridden for Darwin with the xxx$LDBL128 form. See
+ /// PPCISelLowering.cpp.
+ ///
+ enum Libcall {
+ // Integer
+ SHL_I16,
+ SHL_I32,
+ SHL_I64,
+ SHL_I128,
+ SRL_I16,
+ SRL_I32,
+ SRL_I64,
+ SRL_I128,
+ SRA_I16,
+ SRA_I32,
+ SRA_I64,
+ SRA_I128,
+ MUL_I8,
+ MUL_I16,
+ MUL_I32,
+ MUL_I64,
+ MUL_I128,
+ MULO_I32,
+ MULO_I64,
+ MULO_I128,
+ SDIV_I8,
+ SDIV_I16,
+ SDIV_I32,
+ SDIV_I64,
+ SDIV_I128,
+ UDIV_I8,
+ UDIV_I16,
+ UDIV_I32,
+ UDIV_I64,
+ UDIV_I128,
+ SREM_I8,
+ SREM_I16,
+ SREM_I32,
+ SREM_I64,
+ SREM_I128,
+ UREM_I8,
+ UREM_I16,
+ UREM_I32,
+ UREM_I64,
+ UREM_I128,
+ SDIVREM_I8,
+ SDIVREM_I16,
+ SDIVREM_I32,
+ SDIVREM_I64,
+ SDIVREM_I128,
+ UDIVREM_I8,
+ UDIVREM_I16,
+ UDIVREM_I32,
+ UDIVREM_I64,
+ UDIVREM_I128,
+ NEG_I32,
+ NEG_I64,
+
+ // FLOATING POINT
+ ADD_F32,
+ ADD_F64,
+ ADD_F80,
+ ADD_PPCF128,
+ SUB_F32,
+ SUB_F64,
+ SUB_F80,
+ SUB_PPCF128,
+ MUL_F32,
+ MUL_F64,
+ MUL_F80,
+ MUL_PPCF128,
+ DIV_F32,
+ DIV_F64,
+ DIV_F80,
+ DIV_PPCF128,
+ REM_F32,
+ REM_F64,
+ REM_F80,
+ REM_PPCF128,
+ FMA_F32,
+ FMA_F64,
+ FMA_F80,
+ FMA_PPCF128,
+ POWI_F32,
+ POWI_F64,
+ POWI_F80,
+ POWI_PPCF128,
+ SQRT_F32,
+ SQRT_F64,
+ SQRT_F80,
+ SQRT_PPCF128,
+ LOG_F32,
+ LOG_F64,
+ LOG_F80,
+ LOG_PPCF128,
+ LOG2_F32,
+ LOG2_F64,
+ LOG2_F80,
+ LOG2_PPCF128,
+ LOG10_F32,
+ LOG10_F64,
+ LOG10_F80,
+ LOG10_PPCF128,
+ EXP_F32,
+ EXP_F64,
+ EXP_F80,
+ EXP_PPCF128,
+ EXP2_F32,
+ EXP2_F64,
+ EXP2_F80,
+ EXP2_PPCF128,
+ SIN_F32,
+ SIN_F64,
+ SIN_F80,
+ SIN_PPCF128,
+ COS_F32,
+ COS_F64,
+ COS_F80,
+ COS_PPCF128,
+ POW_F32,
+ POW_F64,
+ POW_F80,
+ POW_PPCF128,
+ CEIL_F32,
+ CEIL_F64,
+ CEIL_F80,
+ CEIL_PPCF128,
+ TRUNC_F32,
+ TRUNC_F64,
+ TRUNC_F80,
+ TRUNC_PPCF128,
+ RINT_F32,
+ RINT_F64,
+ RINT_F80,
+ RINT_PPCF128,
+ NEARBYINT_F32,
+ NEARBYINT_F64,
+ NEARBYINT_F80,
+ NEARBYINT_PPCF128,
+ FLOOR_F32,
+ FLOOR_F64,
+ FLOOR_F80,
+ FLOOR_PPCF128,
+ COPYSIGN_F32,
+ COPYSIGN_F64,
+ COPYSIGN_F80,
+ COPYSIGN_PPCF128,
+
+ // CONVERSION
+ FPEXT_F32_F64,
+ FPEXT_F16_F32,
+ FPROUND_F32_F16,
+ FPROUND_F64_F32,
+ FPROUND_F80_F32,
+ FPROUND_PPCF128_F32,
+ FPROUND_F80_F64,
+ FPROUND_PPCF128_F64,
+ FPTOSINT_F32_I8,
+ FPTOSINT_F32_I16,
+ FPTOSINT_F32_I32,
+ FPTOSINT_F32_I64,
+ FPTOSINT_F32_I128,
+ FPTOSINT_F64_I8,
+ FPTOSINT_F64_I16,
+ FPTOSINT_F64_I32,
+ FPTOSINT_F64_I64,
+ FPTOSINT_F64_I128,
+ FPTOSINT_F80_I32,
+ FPTOSINT_F80_I64,
+ FPTOSINT_F80_I128,
+ FPTOSINT_PPCF128_I32,
+ FPTOSINT_PPCF128_I64,
+ FPTOSINT_PPCF128_I128,
+ FPTOUINT_F32_I8,
+ FPTOUINT_F32_I16,
+ FPTOUINT_F32_I32,
+ FPTOUINT_F32_I64,
+ FPTOUINT_F32_I128,
+ FPTOUINT_F64_I8,
+ FPTOUINT_F64_I16,
+ FPTOUINT_F64_I32,
+ FPTOUINT_F64_I64,
+ FPTOUINT_F64_I128,
+ FPTOUINT_F80_I32,
+ FPTOUINT_F80_I64,
+ FPTOUINT_F80_I128,
+ FPTOUINT_PPCF128_I32,
+ FPTOUINT_PPCF128_I64,
+ FPTOUINT_PPCF128_I128,
+ SINTTOFP_I32_F32,
+ SINTTOFP_I32_F64,
+ SINTTOFP_I32_F80,
+ SINTTOFP_I32_PPCF128,
+ SINTTOFP_I64_F32,
+ SINTTOFP_I64_F64,
+ SINTTOFP_I64_F80,
+ SINTTOFP_I64_PPCF128,
+ SINTTOFP_I128_F32,
+ SINTTOFP_I128_F64,
+ SINTTOFP_I128_F80,
+ SINTTOFP_I128_PPCF128,
+ UINTTOFP_I32_F32,
+ UINTTOFP_I32_F64,
+ UINTTOFP_I32_F80,
+ UINTTOFP_I32_PPCF128,
+ UINTTOFP_I64_F32,
+ UINTTOFP_I64_F64,
+ UINTTOFP_I64_F80,
+ UINTTOFP_I64_PPCF128,
+ UINTTOFP_I128_F32,
+ UINTTOFP_I128_F64,
+ UINTTOFP_I128_F80,
+ UINTTOFP_I128_PPCF128,
+
+ // COMPARISON
+ OEQ_F32,
+ OEQ_F64,
+ UNE_F32,
+ UNE_F64,
+ OGE_F32,
+ OGE_F64,
+ OLT_F32,
+ OLT_F64,
+ OLE_F32,
+ OLE_F64,
+ OGT_F32,
+ OGT_F64,
+ UO_F32,
+ UO_F64,
+ O_F32,
+ O_F64,
+
+ // MEMORY
+ MEMCPY,
+ MEMSET,
+ MEMMOVE,
+
+ // EXCEPTION HANDLING
+ UNWIND_RESUME,
+
+ // Family ATOMICs
+ SYNC_VAL_COMPARE_AND_SWAP_1,
+ SYNC_VAL_COMPARE_AND_SWAP_2,
+ SYNC_VAL_COMPARE_AND_SWAP_4,
+ SYNC_VAL_COMPARE_AND_SWAP_8,
+ SYNC_LOCK_TEST_AND_SET_1,
+ SYNC_LOCK_TEST_AND_SET_2,
+ SYNC_LOCK_TEST_AND_SET_4,
+ SYNC_LOCK_TEST_AND_SET_8,
+ SYNC_FETCH_AND_ADD_1,
+ SYNC_FETCH_AND_ADD_2,
+ SYNC_FETCH_AND_ADD_4,
+ SYNC_FETCH_AND_ADD_8,
+ SYNC_FETCH_AND_SUB_1,
+ SYNC_FETCH_AND_SUB_2,
+ SYNC_FETCH_AND_SUB_4,
+ SYNC_FETCH_AND_SUB_8,
+ SYNC_FETCH_AND_AND_1,
+ SYNC_FETCH_AND_AND_2,
+ SYNC_FETCH_AND_AND_4,
+ SYNC_FETCH_AND_AND_8,
+ SYNC_FETCH_AND_OR_1,
+ SYNC_FETCH_AND_OR_2,
+ SYNC_FETCH_AND_OR_4,
+ SYNC_FETCH_AND_OR_8,
+ SYNC_FETCH_AND_XOR_1,
+ SYNC_FETCH_AND_XOR_2,
+ SYNC_FETCH_AND_XOR_4,
+ SYNC_FETCH_AND_XOR_8,
+ SYNC_FETCH_AND_NAND_1,
+ SYNC_FETCH_AND_NAND_2,
+ SYNC_FETCH_AND_NAND_4,
+ SYNC_FETCH_AND_NAND_8,
+
+ UNKNOWN_LIBCALL
+ };
+
+ /// getFPEXT - Return the FPEXT_*_* value for the given types, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getFPEXT(EVT OpVT, EVT RetVT);
+
+ /// getFPROUND - Return the FPROUND_*_* value for the given types, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getFPROUND(EVT OpVT, EVT RetVT);
+
+ /// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getFPTOSINT(EVT OpVT, EVT RetVT);
+
+ /// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getFPTOUINT(EVT OpVT, EVT RetVT);
+
+ /// getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getSINTTOFP(EVT OpVT, EVT RetVT);
+
+ /// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getUINTTOFP(EVT OpVT, EVT RetVT);
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
new file mode 100644
index 000000000000..f4de6933b317
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAG.h
@@ -0,0 +1,711 @@
+//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ScheduleDAG class, which is used as the common
+// base class for instruction schedulers. This encapsulates the scheduling DAG,
+// which is shared between SelectionDAG and MachineInstr scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#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/GraphTraits.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace llvm {
+ class AliasAnalysis;
+ class SUnit;
+ class MachineConstantPool;
+ class MachineFunction;
+ class MachineRegisterInfo;
+ class MachineInstr;
+ class TargetRegisterInfo;
+ class ScheduleDAG;
+ class SDNode;
+ class TargetInstrInfo;
+ class MCInstrDesc;
+ class TargetMachine;
+ class TargetRegisterClass;
+ template<class Graph> class GraphWriter;
+
+ /// SDep - Scheduling dependency. This represents one direction of an
+ /// edge in the scheduling DAG.
+ class SDep {
+ public:
+ /// Kind - These are the different kinds of scheduling dependencies.
+ enum Kind {
+ Data, ///< Regular data dependence (aka true-dependence).
+ Anti, ///< A register anti-dependedence (aka WAR).
+ Output, ///< A register output-dependence (aka WAW).
+ Order ///< Any other ordering dependency.
+ };
+
+ private:
+ /// Dep - A pointer to the depending/depended-on SUnit, and an enum
+ /// indicating the kind of the dependency.
+ PointerIntPair<SUnit *, 2, Kind> Dep;
+
+ /// Contents - A union discriminated by the dependence kind.
+ union {
+ /// Reg - For Data, Anti, and Output dependencies, the associated
+ /// register. For Data dependencies that don't currently have a register
+ /// assigned, this is set to zero.
+ 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;
+ } Contents;
+
+ /// Latency - The time associated with this edge. Often this is just
+ /// the value of the Latency field of the predecessor, however advanced
+ /// models may provide additional information about specific edges.
+ unsigned Latency;
+
+ public:
+ /// SDep - Construct a null SDep. This is only for use by container
+ /// classes which require default constructors. SUnits may not
+ /// have null SDep edges.
+ 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) {
+ switch (kind) {
+ 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;
+ break;
+ case Order:
+ assert(Reg == 0 && "Reg given for non-register dependence!");
+ Contents.Order.isNormalMemory = isNormalMemory;
+ Contents.Order.isMustAlias = isMustAlias;
+ Contents.Order.isArtificial = isArtificial;
+ break;
+ }
+ }
+
+ bool operator==(const SDep &Other) const {
+ if (Dep != Other.Dep || Latency != Other.Latency) return false;
+ switch (Dep.getInt()) {
+ case Data:
+ case Anti:
+ 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;
+ }
+ llvm_unreachable("Invalid dependency kind!");
+ }
+
+ bool operator!=(const SDep &Other) const {
+ return !operator==(Other);
+ }
+
+ /// getLatency - Return the latency value for this edge, which roughly
+ /// means the minimum number of cycles that must elapse between the
+ /// predecessor and the successor, given that they have this edge
+ /// between them.
+ unsigned getLatency() const {
+ return Latency;
+ }
+
+ /// setLatency - Set the latency for this edge.
+ void setLatency(unsigned Lat) {
+ Latency = Lat;
+ }
+
+ //// getSUnit - Return the SUnit to which this edge points.
+ SUnit *getSUnit() const {
+ return Dep.getPointer();
+ }
+
+ //// setSUnit - Assign the SUnit to which this edge points.
+ void setSUnit(SUnit *SU) {
+ Dep.setPointer(SU);
+ }
+
+ /// getKind - Return an enum value representing the kind of the dependence.
+ Kind getKind() const {
+ return Dep.getInt();
+ }
+
+ /// isCtrl - Shorthand for getKind() != SDep::Data.
+ bool isCtrl() const {
+ return getKind() != Data;
+ }
+
+ /// isNormalMemory - Test if this is an Order dependence between two
+ /// 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;
+ }
+
+ /// 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;
+ }
+
+ /// 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;
+ }
+
+ /// isAssignedRegDep - Test if this is a Data dependence that is
+ /// associated with a register.
+ bool isAssignedRegDep() const {
+ return getKind() == Data && Contents.Reg != 0;
+ }
+
+ /// getReg - Return the register associated with this edge. This is
+ /// only valid on Data, Anti, and Output edges. On Data edges, this
+ /// value may be zero, meaning there is no associated register.
+ unsigned getReg() const {
+ assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
+ "getReg called on non-register dependence edge!");
+ return Contents.Reg;
+ }
+
+ /// setReg - Assign the associated register for this edge. This is
+ /// only valid on Data, Anti, and Output edges. On Anti and Output
+ /// edges, this value must not be zero. On Data edges, the value may
+ /// be zero, which would mean that no specific register is associated
+ /// with this edge.
+ void setReg(unsigned Reg) {
+ assert((getKind() == Data || getKind() == Anti || getKind() == Output) &&
+ "setReg called on non-register dependence edge!");
+ assert((getKind() != Anti || Reg != 0) &&
+ "SDep::Anti edge cannot use the zero register!");
+ assert((getKind() != Output || Reg != 0) &&
+ "SDep::Output edge cannot use the zero register!");
+ Contents.Reg = Reg;
+ }
+ };
+
+ template <>
+ struct isPodLike<SDep> { static const bool value = true; };
+
+ /// SUnit - Scheduling unit. This is a node in the scheduling DAG.
+ class SUnit {
+ private:
+ SDNode *Node; // Representative node.
+ MachineInstr *Instr; // Alternatively, a MachineInstr.
+ public:
+ SUnit *OrigNode; // If not this, the node from which
+ // this node was cloned.
+ // (SD scheduling only)
+
+ // Preds/Succs - The SUnits before/after us in the graph.
+ SmallVector<SDep, 4> Preds; // All sunit predecessors.
+ SmallVector<SDep, 4> Succs; // All sunit successors.
+
+ typedef SmallVector<SDep, 4>::iterator pred_iterator;
+ typedef SmallVector<SDep, 4>::iterator succ_iterator;
+ typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
+ typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
+
+ unsigned NodeNum; // Entry # of node in the node vector.
+ unsigned NodeQueueId; // Queue id of node.
+ unsigned NumPreds; // # of SDep::Data preds.
+ unsigned NumSuccs; // # of SDep::Data sucss.
+ unsigned NumPredsLeft; // # of preds not scheduled.
+ unsigned NumSuccsLeft; // # of 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.
+ bool isCall : 1; // Is a function call.
+ bool isCallOp : 1; // Is a function call operand.
+ bool isTwoAddress : 1; // Is a two-address instruction.
+ bool isCommutable : 1; // Is a commutable instruction.
+ bool hasPhysRegDefs : 1; // Has physreg defs that are being used.
+ bool hasPhysRegClobbers : 1; // Has any physreg defs, used or not.
+ bool isPending : 1; // True once pending.
+ bool isAvailable : 1; // True once available.
+ bool isScheduled : 1; // True once scheduled.
+ bool isScheduleHigh : 1; // True if preferable to schedule high.
+ bool isScheduleLow : 1; // True if preferable to schedule low.
+ bool isCloned : 1; // True if this node has been cloned.
+ Sched::Preference SchedulingPref; // Scheduling preference.
+
+ private:
+ bool isDepthCurrent : 1; // True if Depth is current.
+ bool isHeightCurrent : 1; // True if Height is current.
+ unsigned Depth; // Node depth.
+ unsigned Height; // Node height.
+ public:
+ const TargetRegisterClass *CopyDstRC; // Is a special copy node if not null.
+ const TargetRegisterClass *CopySrcRC;
+
+ /// 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),
+ 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),
+ isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(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),
+ 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),
+ isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
+ CopyDstRC(NULL), CopySrcRC(NULL) {}
+
+ /// SUnit - Construct a placeholder SUnit.
+ SUnit()
+ : Node(0), Instr(0), OrigNode(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),
+ isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
+ CopyDstRC(NULL), CopySrcRC(NULL) {}
+
+ /// setNode - Assign the representative SDNode for this SUnit.
+ /// This may be used during pre-regalloc scheduling.
+ void setNode(SDNode *N) {
+ assert(!Instr && "Setting SDNode of SUnit with MachineInstr!");
+ Node = N;
+ }
+
+ /// getNode - Return the representative SDNode for this SUnit.
+ /// This may be used during pre-regalloc scheduling.
+ SDNode *getNode() const {
+ assert(!Instr && "Reading SDNode of SUnit with MachineInstr!");
+ return Node;
+ }
+
+ /// isInstr - Return true if this SUnit refers to a machine instruction as
+ /// opposed to an SDNode.
+ bool isInstr() const { return Instr; }
+
+ /// setInstr - Assign the instruction for the SUnit.
+ /// This may be used during post-regalloc scheduling.
+ void setInstr(MachineInstr *MI) {
+ assert(!Node && "Setting MachineInstr of SUnit with SDNode!");
+ Instr = MI;
+ }
+
+ /// getInstr - Return the representative MachineInstr for this SUnit.
+ /// This may be used during post-regalloc scheduling.
+ MachineInstr *getInstr() const {
+ assert(!Node && "Reading MachineInstr of SUnit with SDNode!");
+ return Instr;
+ }
+
+ /// 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);
+
+ /// 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
+ /// the specified node.
+ void removePred(const SDep &D);
+
+ /// getDepth - Return the depth of this node, which is the length of the
+ /// maximum path up to any node which has no predecessors.
+ unsigned getDepth() const {
+ if (!isDepthCurrent)
+ const_cast<SUnit *>(this)->ComputeDepth();
+ return Depth;
+ }
+
+ /// getHeight - Return the height of this node, which is the length of the
+ /// maximum path down to any node which has no successors.
+ unsigned getHeight() const {
+ if (!isHeightCurrent)
+ const_cast<SUnit *>(this)->ComputeHeight();
+ return Height;
+ }
+
+ /// setDepthToAtLeast - If NewDepth is greater than this node's
+ /// depth value, set it to be the new depth value. This also
+ /// recursively marks successor nodes dirty.
+ void setDepthToAtLeast(unsigned NewDepth);
+
+ /// setDepthToAtLeast - If NewDepth is greater than this node's
+ /// depth value, set it to be the new height value. This also
+ /// recursively marks predecessor nodes dirty.
+ void setHeightToAtLeast(unsigned NewHeight);
+
+ /// setDepthDirty - Set a flag in this node to indicate that its
+ /// stored Depth value will require recomputation the next time
+ /// getDepth() is called.
+ void setDepthDirty();
+
+ /// setHeightDirty - Set a flag in this node to indicate that its
+ /// stored Height value will require recomputation the next time
+ /// getHeight() is called.
+ void setHeightDirty();
+
+ /// isPred - Test if node N is a predecessor of this node.
+ bool isPred(SUnit *N) {
+ for (unsigned i = 0, e = (unsigned)Preds.size(); i != e; ++i)
+ if (Preds[i].getSUnit() == N)
+ return true;
+ return false;
+ }
+
+ /// isSucc - Test if node N is a successor of this node.
+ bool isSucc(SUnit *N) {
+ for (unsigned i = 0, e = (unsigned)Succs.size(); i != e; ++i)
+ if (Succs[i].getSUnit() == N)
+ return true;
+ return false;
+ }
+
+ bool isTopReady() const {
+ return NumPredsLeft == 0;
+ }
+ bool isBottomReady() const {
+ return NumSuccsLeft == 0;
+ }
+
+ void dump(const ScheduleDAG *G) const;
+ void dumpAll(const ScheduleDAG *G) const;
+ void print(raw_ostream &O, const ScheduleDAG *G) const;
+
+ private:
+ void ComputeDepth();
+ void ComputeHeight();
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SchedulingPriorityQueue - This interface is used to plug different
+ /// priorities computation algorithms into the list scheduler. It implements
+ /// the interface of a standard priority queue, where nodes are inserted in
+ /// arbitrary order and returned in priority order. The computation of the
+ /// priority and the representation of the queue are totally up to the
+ /// implementation to decide.
+ ///
+ class SchedulingPriorityQueue {
+ virtual void anchor();
+ unsigned CurCycle;
+ bool HasReadyFilter;
+ public:
+ SchedulingPriorityQueue(bool rf = false):
+ CurCycle(0), HasReadyFilter(rf) {}
+ virtual ~SchedulingPriorityQueue() {}
+
+ virtual bool isBottomUp() const = 0;
+
+ virtual void initNodes(std::vector<SUnit> &SUnits) = 0;
+ virtual void addNode(const SUnit *SU) = 0;
+ virtual void updateNode(const SUnit *SU) = 0;
+ virtual void releaseState() = 0;
+
+ virtual bool empty() const = 0;
+
+ bool hasReadyFilter() const { return HasReadyFilter; }
+
+ virtual bool tracksRegPressure() const { return false; }
+
+ virtual bool isReady(SUnit *) const {
+ assert(!HasReadyFilter && "The ready filter must override isReady()");
+ return true;
+ }
+ virtual void push(SUnit *U) = 0;
+
+ void push_all(const std::vector<SUnit *> &Nodes) {
+ for (std::vector<SUnit *>::const_iterator I = Nodes.begin(),
+ E = Nodes.end(); I != E; ++I)
+ push(*I);
+ }
+
+ virtual SUnit *pop() = 0;
+
+ virtual void remove(SUnit *SU) = 0;
+
+ virtual void dump(ScheduleDAG *) const {}
+
+ /// scheduledNode - As each node is scheduled, this method is invoked. This
+ /// allows the priority function to adjust the priority of related
+ /// unscheduled nodes, for example.
+ ///
+ virtual void scheduledNode(SUnit *) {}
+
+ virtual void unscheduledNode(SUnit *) {}
+
+ void setCurCycle(unsigned Cycle) {
+ CurCycle = Cycle;
+ }
+
+ unsigned getCurCycle() const {
+ return CurCycle;
+ }
+ };
+
+ class ScheduleDAG {
+ public:
+ const TargetMachine &TM; // Target processor
+ const TargetInstrInfo *TII; // Target instruction information
+ const TargetRegisterInfo *TRI; // Target processor register info
+ MachineFunction &MF; // Machine function
+ MachineRegisterInfo &MRI; // Virtual/real register map
+ std::vector<SUnit> SUnits; // The scheduling units.
+ SUnit EntrySU; // Special node for the region entry.
+ SUnit ExitSU; // Special node for the region exit.
+
+#ifdef NDEBUG
+ static const bool StressSched = false;
+#else
+ bool StressSched;
+#endif
+
+ explicit ScheduleDAG(MachineFunction &mf);
+
+ virtual ~ScheduleDAG();
+
+ /// clearDAG - clear the DAG state (between regions).
+ void clearDAG();
+
+ /// getInstrDesc - Return the MCInstrDesc of this SUnit.
+ /// Return NULL for SDNodes without a machine opcode.
+ const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
+ if (SU->isInstr()) return &SU->getInstr()->getDesc();
+ return getNodeDesc(SU->getNode());
+ }
+
+ /// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
+ /// using 'dot'.
+ ///
+ void viewGraph(const Twine &Name, const Twine &Title);
+ void viewGraph();
+
+ virtual void dumpNode(const SUnit *SU) const = 0;
+
+ /// getGraphNodeLabel - Return a label for an SUnit node in a visualization
+ /// of the ScheduleDAG.
+ virtual std::string getGraphNodeLabel(const SUnit *SU) const = 0;
+
+ /// getDAGLabel - Return a label for the region of code covered by the DAG.
+ virtual std::string getDAGName() const = 0;
+
+ /// addCustomGraphFeatures - Add custom features for a visualization of
+ /// the ScheduleDAG.
+ virtual void addCustomGraphFeatures(GraphWriter<ScheduleDAG*> &) const {}
+
+#ifndef NDEBUG
+ /// VerifyScheduledDAG - Verify that all SUnits were scheduled and that
+ /// their state is consistent. Return the number of scheduled SUnits.
+ unsigned VerifyScheduledDAG(bool isBottomUp);
+#endif
+
+ protected:
+ /// ComputeLatency - Compute node latency.
+ ///
+ virtual void computeLatency(SUnit *SU) = 0;
+
+ /// ComputeOperandLatency - Override dependence edge latency using
+ /// operand use/def information
+ ///
+ virtual void computeOperandLatency(SUnit *, SUnit *,
+ SDep&) const { }
+
+ /// 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;
+ };
+
+ class SUnitIterator : public std::iterator<std::forward_iterator_tag,
+ SUnit, ptrdiff_t> {
+ SUnit *Node;
+ unsigned Operand;
+
+ SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
+ public:
+ bool operator==(const SUnitIterator& x) const {
+ return Operand == x.Operand;
+ }
+ bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
+
+ const SUnitIterator &operator=(const SUnitIterator &I) {
+ assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
+ Operand = I.Operand;
+ return *this;
+ }
+
+ pointer operator*() const {
+ return Node->Preds[Operand].getSUnit();
+ }
+ pointer operator->() const { return operator*(); }
+
+ SUnitIterator& operator++() { // Preincrement
+ ++Operand;
+ return *this;
+ }
+ SUnitIterator operator++(int) { // Postincrement
+ SUnitIterator tmp = *this; ++*this; return tmp;
+ }
+
+ static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
+ static SUnitIterator end (SUnit *N) {
+ return SUnitIterator(N, (unsigned)N->Preds.size());
+ }
+
+ unsigned getOperand() const { return Operand; }
+ const SUnit *getNode() const { return Node; }
+ /// isCtrlDep - Test if this is not an SDep::Data dependence.
+ bool isCtrlDep() const {
+ return getSDep().isCtrl();
+ }
+ bool isArtificialDep() const {
+ return getSDep().isArtificial();
+ }
+ const SDep &getSDep() const {
+ return Node->Preds[Operand];
+ }
+ };
+
+ template <> struct GraphTraits<SUnit*> {
+ typedef SUnit NodeType;
+ typedef SUnitIterator ChildIteratorType;
+ static inline NodeType *getEntryNode(SUnit *N) { return N; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return SUnitIterator::begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return SUnitIterator::end(N);
+ }
+ };
+
+ template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
+ typedef std::vector<SUnit>::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(ScheduleDAG *G) {
+ return G->SUnits.begin();
+ }
+ static nodes_iterator nodes_end(ScheduleDAG *G) {
+ return G->SUnits.end();
+ }
+ };
+
+ /// ScheduleDAGTopologicalSort is a class that computes a topological
+ /// ordering for SUnits and provides methods for dynamically updating
+ /// the ordering as new edges are added.
+ ///
+ /// This allows a very fast implementation of IsReachable, for example.
+ ///
+ class ScheduleDAGTopologicalSort {
+ /// SUnits - A reference to the ScheduleDAG's SUnits.
+ std::vector<SUnit> &SUnits;
+
+ /// Index2Node - Maps topological index to the node number.
+ std::vector<int> Index2Node;
+ /// Node2Index - Maps the node number to its topological index.
+ std::vector<int> Node2Index;
+ /// Visited - a set of nodes visited during a DFS traversal.
+ BitVector Visited;
+
+ /// DFS - make a DFS traversal and mark all nodes affected by the
+ /// edge insertion. These nodes will later get new topological indexes
+ /// by means of the Shift method.
+ void DFS(const SUnit *SU, int UpperBound, bool& HasLoop);
+
+ /// Shift - reassign topological indexes for the nodes in the DAG
+ /// to preserve the topological ordering.
+ void Shift(BitVector& Visited, int LowerBound, int UpperBound);
+
+ /// Allocate - assign the topological index to the node n.
+ void Allocate(int n, int index);
+
+ public:
+ explicit ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits);
+
+ /// InitDAGTopologicalSorting - create the initial topological
+ /// ordering from the DAG to be scheduled.
+ void InitDAGTopologicalSorting();
+
+ /// IsReachable - Checks if SU is reachable from TargetSU.
+ bool IsReachable(const SUnit *SU, const SUnit *TargetSU);
+
+ /// WillCreateCycle - Returns true if adding an edge from SU to TargetSU
+ /// will create a cycle.
+ bool WillCreateCycle(SUnit *SU, SUnit *TargetSU);
+
+ /// AddPred - Updates the topological ordering to accommodate an edge
+ /// to be added from SUnit X to SUnit Y.
+ void AddPred(SUnit *Y, SUnit *X);
+
+ /// RemovePred - Updates the topological ordering to accommodate an
+ /// an edge to be removed from the specified node N from the predecessors
+ /// of the current node M.
+ void RemovePred(SUnit *M, SUnit *N);
+
+ typedef std::vector<int>::iterator iterator;
+ typedef std::vector<int>::const_iterator const_iterator;
+ iterator begin() { return Index2Node.begin(); }
+ const_iterator begin() const { return Index2Node.begin(); }
+ iterator end() { return Index2Node.end(); }
+ const_iterator end() const { return Index2Node.end(); }
+
+ typedef std::vector<int>::reverse_iterator reverse_iterator;
+ typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
+ reverse_iterator rbegin() { return Index2Node.rbegin(); }
+ const_reverse_iterator rbegin() const { return Index2Node.rbegin(); }
+ reverse_iterator rend() { return Index2Node.rend(); }
+ const_reverse_iterator rend() const { return Index2Node.rend(); }
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
new file mode 100644
index 000000000000..4fee108cd2be
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -0,0 +1,351 @@
+//==- ScheduleDAGInstrs.h - MachineInstr Scheduling --------------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ScheduleDAGInstrs class, which implements
+// scheduling for a MachineInstr-based dependency graph.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SCHEDULEDAGINSTRS_H
+#define SCHEDULEDAGINSTRS_H
+
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/ScheduleDAG.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 {
+ class MachineLoopInfo;
+ class MachineDominatorTree;
+ class LiveIntervals;
+
+ /// 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 MachineLoopInfo &MLI;
+ const MachineDominatorTree &MDT;
+
+ public:
+ typedef std::map<unsigned, std::pair<const MachineOperand *, unsigned> >
+ LoopDeps;
+ LoopDeps Deps;
+
+ LoopDependencies(const MachineLoopInfo &mli,
+ const MachineDominatorTree &mdt) :
+ MLI(mli), 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;
+ SUnit *SU;
+
+ VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
+
+ unsigned getSparseSetKey() const {
+ return TargetRegisterInfo::virtReg2Index(VirtReg);
+ }
+ };
+
+ /// Combine a SparseSet with a 1x1 vector to track physical registers.
+ /// The SparseSet allows iterating over the (few) live registers for quickly
+ /// comparing against a regmask or clearing the set.
+ ///
+ /// Storage for the map is allocated once for the pass. The map can be
+ /// cleared between scheduling regions without freeing unused entries.
+ class Reg2SUnitsMap {
+ SparseSet<unsigned> PhysRegSet;
+ std::vector<std::vector<SUnit*> > SUnits;
+ public:
+ typedef SparseSet<unsigned>::const_iterator const_iterator;
+
+ // Allow iteration over register numbers (keys) in the map. If needed, we
+ // can provide an iterator over SUnits (values) as well.
+ const_iterator reg_begin() const { return PhysRegSet.begin(); }
+ const_iterator reg_end() const { return PhysRegSet.end(); }
+
+ /// Initialize the map with the number of registers.
+ /// If the map is already large enough, no allocation occurs.
+ /// For simplicity we expect the map to be empty().
+ void setRegLimit(unsigned Limit);
+
+ /// Returns true if the map is empty.
+ bool empty() const { return PhysRegSet.empty(); }
+
+ /// Clear the map without deallocating storage.
+ void clear();
+
+ bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); }
+
+ /// If this register is mapped, return its existing SUnits vector.
+ /// Otherwise map the register and return an empty SUnits vector.
+ std::vector<SUnit *> &operator[](unsigned Reg) {
+ bool New = PhysRegSet.insert(Reg).second;
+ assert((!New || SUnits[Reg].empty()) && "stale SUnits vector");
+ (void)New;
+ return SUnits[Reg];
+ }
+
+ /// Erase an existing element without freeing memory.
+ void erase(unsigned Reg) {
+ PhysRegSet.erase(Reg);
+ SUnits[Reg].clear();
+ }
+ };
+
+ /// Use SparseSet as a SparseMap by relying on the fact that it never
+ /// compares ValueT's, only unsigned keys. This allows the set to be cleared
+ /// between scheduling regions in constant time as long as ValueT does not
+ /// require a destructor.
+ typedef SparseSet<VReg2SUnit> VReg2SUnitMap;
+
+ /// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
+ /// MachineInstrs.
+ class ScheduleDAGInstrs : public ScheduleDAG {
+ protected:
+ const MachineLoopInfo &MLI;
+ const MachineDominatorTree &MDT;
+ const MachineFrameInfo *MFI;
+ const InstrItineraryData *InstrItins;
+
+ /// Live Intervals provides reaching defs in preRA scheduling.
+ LiveIntervals *LIS;
+
+ /// isPostRA flag indicates vregs cannot be present.
+ bool IsPostRA;
+
+ /// UnitLatencies (misnamed) flag avoids computing def-use latencies, using
+ /// the def-side latency only.
+ bool UnitLatencies;
+
+ /// The standard DAG builder does not normally include terminators as DAG
+ /// nodes because it does not create the necessary dependencies to prevent
+ /// reordering. A specialized scheduler can overide
+ /// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
+ /// it has taken responsibility for scheduling the terminator correctly.
+ bool CanHandleTerminators;
+
+ /// State specific to the current scheduling region.
+ /// ------------------------------------------------
+
+ /// The block in which to insert instructions
+ MachineBasicBlock *BB;
+
+ /// The beginning of the range to be scheduled.
+ MachineBasicBlock::iterator RegionBegin;
+
+ /// The end of the range to be scheduled.
+ MachineBasicBlock::iterator RegionEnd;
+
+ /// The index in BB of RegionEnd.
+ unsigned EndIndex;
+
+ /// After calling BuildSchedGraph, each machine instruction in the current
+ /// scheduling region is mapped to an SUnit.
+ DenseMap<MachineInstr*, SUnit*> MISUnitMap;
+
+ /// State internal to DAG building.
+ /// -------------------------------
+
+ /// Defs, Uses - Remember where defs and uses of each register are as we
+ /// iterate upward through the instructions. This is allocated here instead
+ /// of inside BuildSchedGraph to avoid the need for it to be initialized and
+ /// destructed for each block.
+ Reg2SUnitsMap Defs;
+ Reg2SUnitsMap Uses;
+
+ /// Track the last instructon in this region defining each virtual register.
+ VReg2SUnitMap VRegDefs;
+
+ /// PendingLoads - Remember where unknown loads are after the most recent
+ /// unknown store, as we iterate. As with Defs and Uses, this is here
+ /// to minimize construction/destruction.
+ std::vector<SUnit *> PendingLoads;
+
+ /// LoopRegs - Track which registers are used for loop-carried dependencies.
+ ///
+ LoopDependencies LoopRegs;
+
+ /// DbgValues - Remember instruction that preceeds DBG_VALUE.
+ /// These are generated by buildSchedGraph but persist so they can be
+ /// referenced when emitting the final schedule.
+ typedef std::vector<std::pair<MachineInstr *, MachineInstr *> >
+ DbgValueVector;
+ DbgValueVector DbgValues;
+ MachineInstr *FirstDbgValue;
+
+ public:
+ explicit ScheduleDAGInstrs(MachineFunction &mf,
+ const MachineLoopInfo &mli,
+ const MachineDominatorTree &mdt,
+ bool IsPostRAFlag,
+ LiveIntervals *LIS = 0);
+
+ virtual ~ScheduleDAGInstrs() {}
+
+ /// begin - Return an iterator to the top of the current scheduling region.
+ MachineBasicBlock::iterator begin() const { return RegionBegin; }
+
+ /// end - Return an iterator to the bottom of the current scheduling region.
+ MachineBasicBlock::iterator end() const { return RegionEnd; }
+
+ /// newSUnit - Creates a new SUnit and return a ptr to it.
+ SUnit *newSUnit(MachineInstr *MI);
+
+ /// getSUnit - Return an existing SUnit for this MI, or NULL.
+ SUnit *getSUnit(MachineInstr *MI) const;
+
+ /// startBlock - Prepare to perform scheduling in the given block.
+ virtual void startBlock(MachineBasicBlock *BB);
+
+ /// finishBlock - Clean up after scheduling in the given block.
+ virtual void finishBlock();
+
+ /// Initialize the scheduler state for the next scheduling region.
+ virtual void enterRegion(MachineBasicBlock *bb,
+ MachineBasicBlock::iterator begin,
+ MachineBasicBlock::iterator end,
+ unsigned endcount);
+
+ /// Notify that the scheduler has finished scheduling the current region.
+ virtual void exitRegion();
+
+ /// buildSchedGraph - Build SUnits from the MachineBasicBlock that we are
+ /// input.
+ void buildSchedGraph(AliasAnalysis *AA);
+
+ /// addSchedBarrierDeps - Add dependencies from instructions in the current
+ /// list of instructions being scheduled to scheduling barrier. We want to
+ /// make sure instructions which define registers that are either used by
+ /// the terminator or are live-out are properly scheduled. This is
+ /// especially important when the definition latency of the return value(s)
+ /// are too high to be hidden by the branch or when the liveout registers
+ /// used by instructions in the fallthrough block.
+ void addSchedBarrierDeps();
+
+ /// computeLatency - Compute node latency.
+ ///
+ virtual void computeLatency(SUnit *SU);
+
+ /// computeOperandLatency - Override dependence edge latency using
+ /// operand use/def information
+ ///
+ virtual void computeOperandLatency(SUnit *Def, SUnit *Use,
+ SDep& dep) const;
+
+ /// schedule - Order nodes according to selected style, filling
+ /// in the Sequence member.
+ ///
+ /// Typically, a scheduling algorithm will implement schedule() without
+ /// overriding enterRegion() or exitRegion().
+ virtual void schedule() = 0;
+
+ /// finalizeSchedule - Allow targets to perform final scheduling actions at
+ /// the level of the whole MachineFunction. By default does nothing.
+ virtual void finalizeSchedule() {}
+
+ virtual void dumpNode(const SUnit *SU) const;
+
+ /// Return a label for a DAG node that points to an instruction.
+ virtual std::string getGraphNodeLabel(const SUnit *SU) const;
+
+ /// Return a label for the region of code covered by the DAG.
+ virtual std::string getDAGName() const;
+
+ protected:
+ void initSUnits();
+ void addPhysRegDataDeps(SUnit *SU, const MachineOperand &MO);
+ void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
+ void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
+ void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
+
+ VReg2SUnitMap::iterator findVRegDef(unsigned VirtReg) {
+ return VRegDefs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
+ }
+ };
+
+ /// newSUnit - Creates a new SUnit and return a ptr to it.
+ inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
+#ifndef NDEBUG
+ const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0];
+#endif
+ SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
+ assert((Addr == 0 || Addr == &SUnits[0]) &&
+ "SUnits std::vector reallocated on the fly!");
+ SUnits.back().OrigNode = &SUnits.back();
+ return &SUnits.back();
+ }
+
+ /// getSUnit - Return an existing SUnit for this MI, or NULL.
+ inline SUnit *ScheduleDAGInstrs::getSUnit(MachineInstr *MI) const {
+ DenseMap<MachineInstr*, SUnit*>::const_iterator I = MISUnitMap.find(MI);
+ if (I == MISUnitMap.end())
+ return 0;
+ return I->second;
+ }
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h
new file mode 100644
index 000000000000..2f53baa1c7e6
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -0,0 +1,93 @@
+//=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ScheduleHazardRecognizer class, which implements
+// hazard-avoidance heuristics for scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
+
+namespace llvm {
+
+class SUnit;
+
+/// HazardRecognizer - This determines whether or not an instruction can be
+/// issued this cycle, and whether or not a noop needs to be inserted to handle
+/// the hazard.
+class ScheduleHazardRecognizer {
+protected:
+ /// MaxLookAhead - Indicate the number of cycles in the scoreboard
+ /// state. Important to restore the state after backtracking. Additionally,
+ /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
+ /// bypass virtual calls. Currently the PostRA scheduler ignores it.
+ unsigned MaxLookAhead;
+
+public:
+ ScheduleHazardRecognizer(): MaxLookAhead(0) {}
+ virtual ~ScheduleHazardRecognizer();
+
+ enum HazardType {
+ NoHazard, // This instruction can be emitted at this cycle.
+ Hazard, // This instruction can't be emitted at this cycle.
+ NoopHazard // This instruction can't be emitted, and needs noops.
+ };
+
+ unsigned getMaxLookAhead() const { return MaxLookAhead; }
+
+ bool isEnabled() const { return MaxLookAhead != 0; }
+
+ /// atIssueLimit - Return true if no more instructions may be issued in this
+ /// cycle.
+ virtual bool atIssueLimit() const { return false; }
+
+ /// getHazardType - Return the hazard type of emitting this node. There are
+ /// three possible results. Either:
+ /// * NoHazard: it is legal to issue this instruction on this cycle.
+ /// * Hazard: issuing this instruction would stall the machine. If some
+ /// other instruction is available, issue it first.
+ /// * NoopHazard: issuing this instruction would break the program. If
+ /// some other instruction can be issued, do so, otherwise issue a noop.
+ virtual HazardType getHazardType(SUnit *m, int Stalls) {
+ return NoHazard;
+ }
+
+ /// Reset - This callback is invoked when a new block of
+ /// instructions is about to be schedule. The hazard state should be
+ /// set to an initialized state.
+ virtual void Reset() {}
+
+ /// EmitInstruction - This callback is invoked when an instruction is
+ /// emitted, to advance the hazard state.
+ virtual void EmitInstruction(SUnit *) {}
+
+ /// AdvanceCycle - This callback is invoked whenever the next top-down
+ /// instruction to be scheduled cannot issue in the current cycle, either
+ /// because of latency or resource conflicts. This should increment the
+ /// internal state of the hazard recognizer so that previously "Hazard"
+ /// instructions will now not be hazards.
+ virtual void AdvanceCycle() {}
+
+ /// RecedeCycle - This callback is invoked whenever the next bottom-up
+ /// instruction to be scheduled cannot issue in the current cycle, either
+ /// because of latency or resource conflicts.
+ virtual void RecedeCycle() {}
+
+ /// EmitNoop - This callback is invoked when a noop was added to the
+ /// instruction stream.
+ virtual void EmitNoop() {
+ // Default implementation: count it as a cycle.
+ AdvanceCycle();
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h
new file mode 100644
index 000000000000..a582b0c40c8b
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/SchedulerRegistry.h
@@ -0,0 +1,107 @@
+//===-- llvm/CodeGen/SchedulerRegistry.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 the implementation for instruction scheduler function
+// pass registry (RegisterScheduler).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGENSCHEDULERREGISTRY_H
+#define LLVM_CODEGENSCHEDULERREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterScheduler class - Track the registration of instruction schedulers.
+///
+//===----------------------------------------------------------------------===//
+
+class SelectionDAGISel;
+class ScheduleDAGSDNodes;
+class SelectionDAG;
+class MachineBasicBlock;
+
+class RegisterScheduler : public MachinePassRegistryNode {
+public:
+ typedef ScheduleDAGSDNodes *(*FunctionPassCtor)(SelectionDAGISel*,
+ CodeGenOpt::Level);
+
+ static MachinePassRegistry Registry;
+
+ RegisterScheduler(const char *N, const char *D, FunctionPassCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+ { Registry.Add(this); }
+ ~RegisterScheduler() { Registry.Remove(this); }
+
+
+ // Accessors.
+ //
+ RegisterScheduler *getNext() const {
+ return (RegisterScheduler *)MachinePassRegistryNode::getNext();
+ }
+ static RegisterScheduler *getList() {
+ return (RegisterScheduler *)Registry.getList();
+ }
+ static FunctionPassCtor getDefault() {
+ return (FunctionPassCtor)Registry.getDefault();
+ }
+ static void setDefault(FunctionPassCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+};
+
+/// createBURRListDAGScheduler - This creates a bottom up register usage
+/// reduction list scheduler.
+ScheduleDAGSDNodes *createBURRListDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+
+/// createBURRListDAGScheduler - This creates a bottom up list scheduler that
+/// schedules nodes in source code order when possible.
+ScheduleDAGSDNodes *createSourceListDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+
+/// createHybridListDAGScheduler - This creates a bottom up register pressure
+/// aware list scheduler that make use of latency information to avoid stalls
+/// for long latency instructions in low register pressure mode. In high
+/// register pressure mode it schedules to reduce register pressure.
+ScheduleDAGSDNodes *createHybridListDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level);
+
+/// createILPListDAGScheduler - This creates a bottom up register pressure
+/// aware list scheduler that tries to increase instruction level parallelism
+/// in low register pressure mode. In high register pressure mode it schedules
+/// to reduce register pressure.
+ScheduleDAGSDNodes *createILPListDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level);
+
+/// createFastDAGScheduler - This creates a "fast" scheduler.
+///
+ScheduleDAGSDNodes *createFastDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+
+/// createVLIWDAGScheduler - Scheduler for VLIW targets. This creates top down
+/// DFA driven list scheduler with clustering heuristic to control
+/// register pressure.
+ScheduleDAGSDNodes *createVLIWDAGScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+/// createDefaultScheduler - This creates an instruction scheduler appropriate
+/// for the target.
+ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
+ CodeGenOpt::Level OptLevel);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
new file mode 100644
index 000000000000..060e89a3fdc7
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -0,0 +1,127 @@
+//=- llvm/CodeGen/ScoreboardHazardRecognizer.h - Schedule Support -*- 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 ScoreboardHazardRecognizer class, which
+// encapsulates hazard-avoidance heuristics for scheduling, based on the
+// scheduling itineraries specified for the target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+#define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
+
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/Support/DataTypes.h"
+
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+
+class InstrItineraryData;
+class ScheduleDAG;
+class SUnit;
+
+class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
+ // Scoreboard to track function unit usage. Scoreboard[0] is a
+ // mask of the FUs in use in the cycle currently being
+ // schedule. Scoreboard[1] is a mask for the next cycle. The
+ // Scoreboard is used as a circular buffer with the current cycle
+ // indicated by Head.
+ //
+ // Scoreboard always counts cycles in forward execution order. If used by a
+ // bottom-up scheduler, then the scoreboard cycles are the inverse of the
+ // scheduler's cycles.
+ class Scoreboard {
+ unsigned *Data;
+
+ // The maximum number of cycles monitored by the Scoreboard. This
+ // value is determined based on the target itineraries to ensure
+ // that all hazards can be tracked.
+ size_t Depth;
+ // Indices into the Scoreboard that represent the current cycle.
+ size_t Head;
+ public:
+ Scoreboard():Data(NULL), Depth(0), Head(0) { }
+ ~Scoreboard() {
+ delete[] Data;
+ }
+
+ size_t getDepth() const { return Depth; }
+ unsigned& operator[](size_t idx) const {
+ // Depth is expected to be a power-of-2.
+ assert(Depth && !(Depth & (Depth - 1)) &&
+ "Scoreboard was not initialized properly!");
+
+ return Data[(Head + idx) & (Depth-1)];
+ }
+
+ void reset(size_t d = 1) {
+ if (Data == NULL) {
+ Depth = d;
+ Data = new unsigned[Depth];
+ }
+
+ memset(Data, 0, Depth * sizeof(Data[0]));
+ Head = 0;
+ }
+
+ void advance() {
+ Head = (Head + 1) & (Depth-1);
+ }
+
+ void recede() {
+ Head = (Head - 1) & (Depth-1);
+ }
+
+ // Print the scoreboard.
+ void dump() const;
+ };
+
+#ifndef NDEBUG
+ // Support for tracing ScoreboardHazardRecognizer as a component within
+ // another module. Follows the current thread-unsafe model of tracing.
+ static const char *DebugType;
+#endif
+
+ // Itinerary data for the target.
+ const InstrItineraryData *ItinData;
+
+ const ScheduleDAG *DAG;
+
+ /// IssueWidth - Max issue per cycle. 0=Unknown.
+ unsigned IssueWidth;
+
+ /// IssueCount - Count instructions issued in this cycle.
+ unsigned IssueCount;
+
+ Scoreboard ReservedScoreboard;
+ Scoreboard RequiredScoreboard;
+
+public:
+ ScoreboardHazardRecognizer(const InstrItineraryData *ItinData,
+ const ScheduleDAG *DAG,
+ const char *ParentDebugType = "");
+
+ /// atIssueLimit - Return true if no more instructions may be issued in this
+ /// cycle.
+ virtual bool atIssueLimit() const;
+
+ // Stalls provides an cycle offset at which SU will be scheduled. It will be
+ // negative for bottom-up scheduling.
+ virtual HazardType getHazardType(SUnit *SU, int Stalls);
+ virtual void Reset();
+ virtual void EmitInstruction(SUnit *SU);
+ virtual void AdvanceCycle();
+ virtual void RecedeCycle();
+};
+
+}
+
+#endif //!LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h
new file mode 100644
index 000000000000..6a7a87e86636
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -0,0 +1,1074 @@
+//===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SelectionDAG class, and transitively defines the
+// SDNode class and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#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/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Support/RecyclingAllocator.h"
+#include "llvm/Target/TargetMachine.h"
+#include <cassert>
+#include <vector>
+#include <map>
+#include <string>
+
+namespace llvm {
+
+class AliasAnalysis;
+class MachineConstantPoolValue;
+class MachineFunction;
+class MDNode;
+class SDNodeOrdering;
+class SDDbgValue;
+class TargetLowering;
+class TargetSelectionDAGInfo;
+
+template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
+private:
+ mutable ilist_half_node<SDNode> Sentinel;
+public:
+ SDNode *createSentinel() const {
+ return static_cast<SDNode*>(&Sentinel);
+ }
+ static void destroySentinel(SDNode *) {}
+
+ SDNode *provideInitialHead() const { return createSentinel(); }
+ SDNode *ensureHead(SDNode*) const { return createSentinel(); }
+ static void noteHead(SDNode*, SDNode*) {}
+
+ static void deleteNode(SDNode *) {
+ llvm_unreachable("ilist_traits<SDNode> shouldn't see a deleteNode call!");
+ }
+private:
+ static void createNode(const SDNode &);
+};
+
+/// SDDbgInfo - Keeps track of dbg_value information through SDISel. We do
+/// not build SDNodes for these so as not to perturb the generated code;
+/// instead the info is kept off to the side in this structure. Each SDNode may
+/// have one or more associated dbg_value entries. This information is kept in
+/// DbgValMap.
+/// Byval parameters are handled separately because they don't use alloca's,
+/// which busts the normal mechanism. There is good reason for handling all
+/// parameters separately: they may not have code generated for them, they
+/// should always go at the beginning of the function regardless of other code
+/// motion, and debug info for them is potentially useful even if the parameter
+/// is unused. Right now only byval parameters are handled separately.
+class SDDbgInfo {
+ SmallVector<SDDbgValue*, 32> DbgValues;
+ SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
+ DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap;
+
+ void operator=(const SDDbgInfo&); // Do not implement.
+ SDDbgInfo(const SDDbgInfo&); // Do not implement.
+public:
+ SDDbgInfo() {}
+
+ void add(SDDbgValue *V, const SDNode *Node, bool isParameter) {
+ if (isParameter) {
+ ByvalParmDbgValues.push_back(V);
+ } else DbgValues.push_back(V);
+ if (Node)
+ DbgValMap[Node].push_back(V);
+ }
+
+ void clear() {
+ DbgValMap.clear();
+ DbgValues.clear();
+ ByvalParmDbgValues.clear();
+ }
+
+ bool empty() const {
+ return DbgValues.empty() && ByvalParmDbgValues.empty();
+ }
+
+ ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) {
+ DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> >::iterator I =
+ DbgValMap.find(Node);
+ if (I != DbgValMap.end())
+ return I->second;
+ return ArrayRef<SDDbgValue*>();
+ }
+
+ typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
+ DbgIterator DbgBegin() { return DbgValues.begin(); }
+ DbgIterator DbgEnd() { return DbgValues.end(); }
+ DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
+ DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); }
+};
+
+enum CombineLevel {
+ BeforeLegalizeTypes,
+ AfterLegalizeTypes,
+ AfterLegalizeVectorOps,
+ AfterLegalizeDAG
+};
+
+class SelectionDAG;
+void checkForCycles(const SDNode *N);
+void checkForCycles(const SelectionDAG *DAG);
+
+/// SelectionDAG class - This is used to represent a portion of an LLVM function
+/// in a low-level Data Dependence DAG representation suitable for instruction
+/// selection. This DAG is constructed as the first step of instruction
+/// selection in order to allow implementation of machine specific optimizations
+/// and code simplifications.
+///
+/// The representation used by the SelectionDAG is a target-independent
+/// representation, which has some similarities to the GCC RTL representation,
+/// but is significantly more simple, powerful, and is a graph form instead of a
+/// linear form.
+///
+class SelectionDAG {
+ const TargetMachine &TM;
+ const TargetLowering &TLI;
+ const TargetSelectionDAGInfo &TSI;
+ MachineFunction *MF;
+ LLVMContext *Context;
+ CodeGenOpt::Level OptLevel;
+
+ /// EntryNode - The starting token.
+ SDNode EntryNode;
+
+ /// Root - The root of the entire DAG.
+ SDValue Root;
+
+ /// AllNodes - A linked list of nodes in the current DAG.
+ ilist<SDNode> AllNodes;
+
+ /// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use
+ /// pool allocation with recycling.
+ typedef RecyclingAllocator<BumpPtrAllocator, SDNode, sizeof(LargestSDNode),
+ AlignOf<MostAlignedSDNode>::Alignment>
+ NodeAllocatorType;
+
+ /// NodeAllocator - Pool allocation for nodes.
+ NodeAllocatorType NodeAllocator;
+
+ /// CSEMap - This structure is used to memoize nodes, automatically performing
+ /// CSE with existing nodes when a duplicate is requested.
+ FoldingSet<SDNode> CSEMap;
+
+ /// OperandAllocator - Pool allocation for machine-opcode SDNode operands.
+ BumpPtrAllocator OperandAllocator;
+
+ /// Allocator - Pool allocation for misc. objects that are created once per
+ /// SelectionDAG.
+ BumpPtrAllocator Allocator;
+
+ /// SDNodeOrdering - The ordering of the SDNodes. It roughly corresponds to
+ /// the ordering of the original LLVM instructions.
+ SDNodeOrdering *Ordering;
+
+ /// DbgInfo - Tracks dbg_value information through SDISel.
+ SDDbgInfo *DbgInfo;
+
+ /// setGraphColorHelper - Implementation of setSubgraphColor.
+ /// Return whether we had to truncate the search.
+ ///
+ bool setSubgraphColorHelper(SDNode *N, const char *Color,
+ DenseSet<SDNode *> &visited,
+ int level, bool &printed);
+
+ void operator=(const SelectionDAG&); // Do not implement.
+ SelectionDAG(const SelectionDAG&); // Do not implement.
+
+public:
+ explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level);
+ ~SelectionDAG();
+
+ /// init - Prepare this SelectionDAG to process code in the given
+ /// MachineFunction.
+ ///
+ void init(MachineFunction &mf);
+
+ /// clear - Clear state and free memory necessary to make this
+ /// SelectionDAG ready to process a new block.
+ ///
+ void clear();
+
+ MachineFunction &getMachineFunction() const { return *MF; }
+ const TargetMachine &getTarget() const { return TM; }
+ const TargetLowering &getTargetLoweringInfo() const { return TLI; }
+ const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
+ LLVMContext *getContext() const {return Context; }
+
+ /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
+ ///
+ void viewGraph(const std::string &Title);
+ void viewGraph();
+
+#ifndef NDEBUG
+ std::map<const SDNode *, std::string> NodeGraphAttrs;
+#endif
+
+ /// clearGraphAttrs - Clear all previously defined node graph attributes.
+ /// Intended to be used from a debugging tool (eg. gdb).
+ void clearGraphAttrs();
+
+ /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
+ ///
+ void setGraphAttrs(const SDNode *N, const char *Attrs);
+
+ /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
+ /// Used from getNodeAttributes.
+ const std::string getGraphAttrs(const SDNode *N) const;
+
+ /// setGraphColor - Convenience for setting node color attribute.
+ ///
+ void setGraphColor(const SDNode *N, const char *Color);
+
+ /// setGraphColor - Convenience for setting subgraph color attribute.
+ ///
+ void setSubgraphColor(SDNode *N, const char *Color);
+
+ typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
+ allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
+ allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
+ typedef ilist<SDNode>::iterator allnodes_iterator;
+ allnodes_iterator allnodes_begin() { return AllNodes.begin(); }
+ allnodes_iterator allnodes_end() { return AllNodes.end(); }
+ ilist<SDNode>::size_type allnodes_size() const {
+ return AllNodes.size();
+ }
+
+ /// getRoot - Return the root tag of the SelectionDAG.
+ ///
+ const SDValue &getRoot() const { return Root; }
+
+ /// getEntryNode - Return the token chain corresponding to the entry of the
+ /// function.
+ SDValue getEntryNode() const {
+ return SDValue(const_cast<SDNode *>(&EntryNode), 0);
+ }
+
+ /// setRoot - Set the current root tag of the SelectionDAG.
+ ///
+ const SDValue &setRoot(SDValue N) {
+ assert((!N.getNode() || N.getValueType() == MVT::Other) &&
+ "DAG root value is not a chain!");
+ if (N.getNode())
+ checkForCycles(N.getNode());
+ Root = N;
+ if (N.getNode())
+ checkForCycles(this);
+ return Root;
+ }
+
+ /// Combine - This iterates over the nodes in the SelectionDAG, folding
+ /// certain types of nodes together, or eliminating superfluous nodes. The
+ /// Level argument controls whether Combine is allowed to produce nodes and
+ /// types that are illegal on the target.
+ void Combine(CombineLevel Level, AliasAnalysis &AA,
+ CodeGenOpt::Level OptLevel);
+
+ /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
+ /// only uses types natively supported by the target. Returns "true" if it
+ /// made any changes.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ bool LegalizeTypes();
+
+ /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is
+ /// compatible with the target instruction selector, as indicated by the
+ /// TargetLowering object.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ void Legalize();
+
+ /// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG
+ /// that only uses vector math operations supported by the target. This is
+ /// necessary as a separate step from Legalize because unrolling a vector
+ /// operation can introduce illegal types, which requires running
+ /// LegalizeTypes again.
+ ///
+ /// This returns true if it made any changes; in that case, LegalizeTypes
+ /// is called again before Legalize.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ bool LegalizeVectors();
+
+ /// RemoveDeadNodes - This method deletes all unreachable nodes in the
+ /// SelectionDAG.
+ void RemoveDeadNodes();
+
+ /// DeleteNode - Remove the specified node from the system. This node must
+ /// have no referrers.
+ void DeleteNode(SDNode *N);
+
+ /// getVTList - Return an SDVTList that represents the list of values
+ /// specified.
+ SDVTList getVTList(EVT VT);
+ SDVTList getVTList(EVT VT1, EVT VT2);
+ SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3);
+ SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4);
+ SDVTList getVTList(const EVT *VTs, unsigned NumVTs);
+
+ //===--------------------------------------------------------------------===//
+ // Node creation methods.
+ //
+ SDValue getConstant(uint64_t Val, EVT VT, bool isTarget = false);
+ SDValue getConstant(const APInt &Val, EVT VT, bool isTarget = false);
+ SDValue getConstant(const ConstantInt &Val, EVT VT, bool isTarget = false);
+ SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false);
+ SDValue getTargetConstant(uint64_t Val, EVT VT) {
+ return getConstant(Val, VT, true);
+ }
+ SDValue getTargetConstant(const APInt &Val, EVT VT) {
+ return getConstant(Val, VT, true);
+ }
+ SDValue getTargetConstant(const ConstantInt &Val, EVT VT) {
+ return getConstant(Val, VT, true);
+ }
+ // The forms below that take a double should only be used for simple
+ // constants that can be exactly represented in VT. No checks are made.
+ SDValue getConstantFP(double Val, EVT VT, bool isTarget = false);
+ SDValue getConstantFP(const APFloat& Val, EVT VT, bool isTarget = false);
+ SDValue getConstantFP(const ConstantFP &CF, EVT VT, bool isTarget = false);
+ SDValue getTargetConstantFP(double Val, EVT VT) {
+ return getConstantFP(Val, VT, true);
+ }
+ SDValue getTargetConstantFP(const APFloat& Val, EVT VT) {
+ return getConstantFP(Val, VT, true);
+ }
+ SDValue getTargetConstantFP(const ConstantFP &Val, EVT VT) {
+ return getConstantFP(Val, VT, true);
+ }
+ SDValue getGlobalAddress(const GlobalValue *GV, DebugLoc DL, EVT VT,
+ int64_t offset = 0, bool isTargetGA = false,
+ unsigned char TargetFlags = 0);
+ SDValue getTargetGlobalAddress(const GlobalValue *GV, DebugLoc DL, EVT VT,
+ int64_t offset = 0,
+ unsigned char TargetFlags = 0) {
+ return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags);
+ }
+ SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false);
+ SDValue getTargetFrameIndex(int FI, EVT VT) {
+ return getFrameIndex(FI, VT, true);
+ }
+ SDValue getJumpTable(int JTI, EVT VT, bool isTarget = false,
+ unsigned char TargetFlags = 0);
+ SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags = 0) {
+ return getJumpTable(JTI, VT, true, TargetFlags);
+ }
+ SDValue getConstantPool(const Constant *C, EVT VT,
+ unsigned Align = 0, int Offs = 0, bool isT=false,
+ unsigned char TargetFlags = 0);
+ SDValue getTargetConstantPool(const Constant *C, EVT VT,
+ unsigned Align = 0, int Offset = 0,
+ unsigned char TargetFlags = 0) {
+ return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
+ }
+ SDValue getConstantPool(MachineConstantPoolValue *C, EVT VT,
+ unsigned Align = 0, int Offs = 0, bool isT=false,
+ unsigned char TargetFlags = 0);
+ SDValue getTargetConstantPool(MachineConstantPoolValue *C,
+ EVT VT, unsigned Align = 0,
+ int Offset = 0, unsigned char TargetFlags=0) {
+ return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
+ }
+ // When generating a branch to a BB, we don't in general know enough
+ // to provide debug info for the BB at that time, so keep this one around.
+ SDValue getBasicBlock(MachineBasicBlock *MBB);
+ SDValue getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl);
+ SDValue getExternalSymbol(const char *Sym, EVT VT);
+ SDValue getExternalSymbol(const char *Sym, DebugLoc dl, EVT VT);
+ SDValue getTargetExternalSymbol(const char *Sym, EVT VT,
+ unsigned char TargetFlags = 0);
+ SDValue getValueType(EVT);
+ SDValue getRegister(unsigned Reg, EVT VT);
+ 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);
+
+ SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
+ return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
+ getRegister(Reg, N.getValueType()), N);
+ }
+
+ // This version of the getCopyToReg method takes an extra operand, which
+ // indicates that there is potentially an incoming glue value (if Glue is not
+ // null) and that there should be a glue result.
+ SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N,
+ SDValue Glue) {
+ SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue };
+ return getNode(ISD::CopyToReg, dl, VTs, Ops, Glue.getNode() ? 4 : 3);
+ }
+
+ // Similar to last getCopyToReg() except parameter Reg is a SDValue
+ SDValue getCopyToReg(SDValue Chain, DebugLoc dl, SDValue Reg, SDValue N,
+ SDValue Glue) {
+ SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, Reg, N, Glue };
+ return getNode(ISD::CopyToReg, dl, VTs, Ops, Glue.getNode() ? 4 : 3);
+ }
+
+ SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT) {
+ SDVTList VTs = getVTList(VT, MVT::Other);
+ SDValue Ops[] = { Chain, getRegister(Reg, VT) };
+ return getNode(ISD::CopyFromReg, dl, VTs, Ops, 2);
+ }
+
+ // This version of the getCopyFromReg method takes an extra operand, which
+ // indicates that there is potentially an incoming glue value (if Glue is not
+ // null) and that there should be a glue result.
+ SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, EVT VT,
+ SDValue Glue) {
+ SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue };
+ return getNode(ISD::CopyFromReg, dl, VTs, Ops, Glue.getNode() ? 3 : 2);
+ }
+
+ SDValue getCondCode(ISD::CondCode Cond);
+
+ /// Returns the ConvertRndSat Note: Avoid using this node because it may
+ /// disappear in the future and most targets don't support it.
+ SDValue getConvertRndSat(EVT VT, DebugLoc dl, SDValue Val, SDValue DTy,
+ SDValue STy,
+ SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
+
+ /// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node. The number of
+ /// elements in VT, which must be a vector type, must match the number of
+ /// mask elements NumElts. A integer mask element equal to -1 is treated as
+ /// undefined.
+ SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2,
+ const int *MaskElts);
+
+ /// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// integer type VT, by either any-extending or truncating it.
+ SDValue getAnyExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
+
+ /// getSExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// integer type VT, by either sign-extending or truncating it.
+ SDValue getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
+
+ /// getZExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// integer type VT, by either zero-extending or truncating it.
+ SDValue getZExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
+
+ /// getZeroExtendInReg - Return the expression required to zero extend the Op
+ /// value assuming it was the smaller SrcTy value.
+ SDValue getZeroExtendInReg(SDValue Op, DebugLoc DL, EVT SrcTy);
+
+ /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
+ SDValue getNOT(DebugLoc DL, SDValue Val, EVT VT);
+
+ /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
+ /// a glue result (to ensure it's not CSE'd). CALLSEQ_START does not have a
+ /// useful DebugLoc.
+ SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) {
+ SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, Op };
+ return getNode(ISD::CALLSEQ_START, DebugLoc(), VTs, Ops, 2);
+ }
+
+ /// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a
+ /// glue result (to ensure it's not CSE'd). CALLSEQ_END does not have
+ /// a useful DebugLoc.
+ SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2,
+ SDValue InGlue) {
+ SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue);
+ SmallVector<SDValue, 4> Ops;
+ Ops.push_back(Chain);
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ Ops.push_back(InGlue);
+ return getNode(ISD::CALLSEQ_END, DebugLoc(), NodeTys, &Ops[0],
+ (unsigned)Ops.size() - (InGlue.getNode() == 0 ? 1 : 0));
+ }
+
+ /// getUNDEF - Return an UNDEF node. UNDEF does not have a useful DebugLoc.
+ SDValue getUNDEF(EVT VT) {
+ return getNode(ISD::UNDEF, DebugLoc(), VT);
+ }
+
+ /// getGLOBAL_OFFSET_TABLE - Return a GLOBAL_OFFSET_TABLE node. This does
+ /// not have a useful DebugLoc.
+ SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
+ return getNode(ISD::GLOBAL_OFFSET_TABLE, DebugLoc(), VT);
+ }
+
+ /// getNode - Gets or creates the specified node.
+ ///
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, SDValue N);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT, SDValue N1, SDValue N2);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT,
+ SDValue N1, SDValue N2, SDValue N3);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4,
+ SDValue N5);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT,
+ const SDUse *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, EVT VT,
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL,
+ const std::vector<EVT> &ResultTys,
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, const EVT *VTs, unsigned NumVTs,
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, SDValue N);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, SDValue N3);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4);
+ SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
+ SDValue N1, SDValue N2, SDValue N3, SDValue N4,
+ SDValue N5);
+
+ /// getStackArgumentTokenFactor - Compute a TokenFactor to force all
+ /// the incoming stack arguments to be loaded from the stack. This is
+ /// used in tail call lowering to protect stack arguments from being
+ /// clobbered.
+ SDValue getStackArgumentTokenFactor(SDValue Chain);
+
+ SDValue getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst, SDValue Src,
+ SDValue Size, unsigned Align, bool isVol, bool AlwaysInline,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo);
+
+ SDValue getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst, SDValue Src,
+ SDValue Size, unsigned Align, bool isVol,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo);
+
+ SDValue getMemset(SDValue Chain, DebugLoc dl, SDValue Dst, SDValue Src,
+ SDValue Size, unsigned Align, bool isVol,
+ MachinePointerInfo DstPtrInfo);
+
+ /// getSetCC - Helper function to make it easier to build SetCC's if you just
+ /// have an ISD::CondCode instead of an SDValue.
+ ///
+ SDValue getSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS,
+ ISD::CondCode Cond) {
+ assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
+ "Cannot compare scalars to vectors");
+ assert(LHS.getValueType().isVector() == VT.isVector() &&
+ "Cannot compare scalars to vectors");
+ return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
+ }
+
+ /// getSelectCC - Helper function to make it easier to build SelectCC's if you
+ /// just have an ISD::CondCode instead of an SDValue.
+ ///
+ SDValue getSelectCC(DebugLoc DL, SDValue LHS, SDValue RHS,
+ SDValue True, SDValue False, ISD::CondCode Cond) {
+ return getNode(ISD::SELECT_CC, DL, True.getValueType(),
+ LHS, RHS, True, False, getCondCode(Cond));
+ }
+
+ /// getVAArg - VAArg produces a result and token chain, and takes a pointer
+ /// and a source value as input.
+ SDValue getVAArg(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
+ SDValue SV, unsigned Align);
+
+ /// getAtomic - Gets a node for an atomic op, produces result and chain and
+ /// takes 3 operands
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
+ SDValue Ptr, SDValue Cmp, SDValue Swp,
+ MachinePointerInfo PtrInfo, unsigned Alignment,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
+ SDValue Ptr, SDValue Cmp, SDValue Swp,
+ MachineMemOperand *MMO,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+
+ /// getAtomic - Gets a node for an atomic op, produces result (if relevant)
+ /// and chain and takes 2 operands.
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
+ SDValue Ptr, SDValue Val, const Value* PtrVal,
+ unsigned Alignment, AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
+ SDValue Ptr, SDValue Val, MachineMemOperand *MMO,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+
+ /// getAtomic - Gets a node for an atomic op, produces result and chain and
+ /// takes 1 operand.
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT,
+ SDValue Chain, SDValue Ptr, const Value* PtrVal,
+ unsigned Alignment,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT,
+ SDValue Chain, SDValue Ptr, MachineMemOperand *MMO,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+
+ /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
+ /// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
+ /// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not
+ /// less than FIRST_TARGET_MEMORY_OPCODE.
+ SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl,
+ const EVT *VTs, unsigned NumVTs,
+ const SDValue *Ops, unsigned NumOps,
+ EVT MemVT, MachinePointerInfo PtrInfo,
+ unsigned Align = 0, bool Vol = false,
+ bool ReadMem = true, bool WriteMem = true);
+
+ SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
+ const SDValue *Ops, unsigned NumOps,
+ EVT MemVT, MachinePointerInfo PtrInfo,
+ unsigned Align = 0, bool Vol = false,
+ bool ReadMem = true, bool WriteMem = true);
+
+ SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
+ const SDValue *Ops, unsigned NumOps,
+ EVT MemVT, MachineMemOperand *MMO);
+
+ /// getMergeValues - Create a MERGE_VALUES node from the given operands.
+ SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, DebugLoc dl);
+
+ /// getLoad - Loads are not normal binary operators: their result type is not
+ /// determined by their operands, and they produce a value AND a token chain.
+ ///
+ SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
+ MachinePointerInfo PtrInfo, bool isVolatile,
+ bool isNonTemporal, bool isInvariant, unsigned Alignment,
+ const MDNode *TBAAInfo = 0, const MDNode *Ranges = 0);
+ SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
+ SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo,
+ EVT MemVT, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment,
+ const MDNode *TBAAInfo = 0);
+ SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
+ SDValue Offset, ISD::MemIndexedMode AM);
+ SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+ EVT VT, DebugLoc dl,
+ SDValue Chain, SDValue Ptr, SDValue Offset,
+ MachinePointerInfo PtrInfo, EVT MemVT,
+ bool isVolatile, bool isNonTemporal, bool isInvariant,
+ unsigned Alignment, const MDNode *TBAAInfo = 0,
+ const MDNode *Ranges = 0);
+ SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
+ EVT VT, DebugLoc dl,
+ SDValue Chain, SDValue Ptr, SDValue Offset,
+ EVT MemVT, MachineMemOperand *MMO);
+
+ /// getStore - Helper function to build ISD::STORE nodes.
+ ///
+ SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
+ MachinePointerInfo PtrInfo, bool isVolatile,
+ bool isNonTemporal, unsigned Alignment,
+ const MDNode *TBAAInfo = 0);
+ SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
+ MachineMemOperand *MMO);
+ SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
+ MachinePointerInfo PtrInfo, EVT TVT,
+ bool isNonTemporal, bool isVolatile,
+ unsigned Alignment,
+ const MDNode *TBAAInfo = 0);
+ SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
+ EVT TVT, MachineMemOperand *MMO);
+ SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base,
+ SDValue Offset, ISD::MemIndexedMode AM);
+
+ /// getSrcValue - Construct a node to track a Value* through the backend.
+ SDValue getSrcValue(const Value *v);
+
+ /// getMDNode - Return an MDNodeSDNode which holds an MDNode.
+ SDValue getMDNode(const MDNode *MD);
+
+ /// getShiftAmountOperand - Return the specified value casted to
+ /// the target's desired shift amount type.
+ SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
+
+ /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
+ /// specified operands. If the resultant node already exists in the DAG,
+ /// this does not modify the specified node, instead it returns the node that
+ /// already exists. If the resultant node does not exist in the DAG, the
+ /// input node is returned. As a degenerate case, if you specify the same
+ /// input operands as the node already has, the input node is returned.
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op);
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2);
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
+ SDValue Op3);
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
+ SDValue Op3, SDValue Op4);
+ SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
+ SDValue Op3, SDValue Op4, SDValue Op5);
+ SDNode *UpdateNodeOperands(SDNode *N,
+ const SDValue *Ops, unsigned NumOps);
+
+ /// SelectNodeTo - These are used for target selectors to *mutate* the
+ /// specified node to have the specified return type, Target opcode, and
+ /// operands. Note that target opcodes are stored as
+ /// ~TargetOpcode in the node opcode field. The resultant node is returned.
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT, SDValue Op1);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT,
+ SDValue Op1, SDValue Op2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT,
+ SDValue Op1, SDValue Op2, SDValue Op3);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT,
+ const SDValue *Ops, unsigned NumOps);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1, EVT VT2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+ EVT VT2, const SDValue *Ops, unsigned NumOps);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+ EVT VT2, EVT VT3, const SDValue *Ops, unsigned NumOps);
+ SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT1,
+ EVT VT2, EVT VT3, EVT VT4, const SDValue *Ops,
+ unsigned NumOps);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+ EVT VT2, SDValue Op1);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+ EVT VT2, SDValue Op1, SDValue Op2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+ EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, EVT VT1,
+ EVT VT2, EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+
+ /// MorphNodeTo - This *mutates* the specified node to have the specified
+ /// return type, opcode, and operands.
+ SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+
+ /// getMachineNode - These are used for target selectors to create a new node
+ /// with specified return type(s), MachineInstr opcode, and operands.
+ ///
+ /// Note that getMachineNode returns the resultant node. If there is already
+ /// a node of the specified opcode and operands, it returns that node instead
+ /// of the current one.
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
+ SDValue Op1);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
+ SDValue Op1, SDValue Op2);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
+ SDValue Op1, SDValue Op2, SDValue Op3);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT,
+ const SDValue *Ops, unsigned NumOps);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ SDValue Op1);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1,
+ EVT VT2, SDValue Op1, SDValue Op2);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1,
+ EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ const SDValue *Ops, unsigned NumOps);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ EVT VT3, SDValue Op1, SDValue Op2);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ EVT VT3, const SDValue *Ops, unsigned NumOps);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, EVT VT1, EVT VT2,
+ EVT VT3, EVT VT4, const SDValue *Ops, unsigned NumOps);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl,
+ const std::vector<EVT> &ResultTys, const SDValue *Ops,
+ unsigned NumOps);
+ MachineSDNode *getMachineNode(unsigned Opcode, DebugLoc dl, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+
+ /// getTargetExtractSubreg - A convenience function for creating
+ /// TargetInstrInfo::EXTRACT_SUBREG nodes.
+ SDValue getTargetExtractSubreg(int SRIdx, DebugLoc DL, EVT VT,
+ SDValue Operand);
+
+ /// getTargetInsertSubreg - A convenience function for creating
+ /// TargetInstrInfo::INSERT_SUBREG nodes.
+ SDValue getTargetInsertSubreg(int SRIdx, DebugLoc DL, EVT VT,
+ SDValue Operand, SDValue Subreg);
+
+ /// getNodeIfExists - Get the specified node if it's already available, or
+ /// else return NULL.
+ SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps);
+
+ /// getDbgValue - Creates a SDDbgValue node.
+ ///
+ SDDbgValue *getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, uint64_t Off,
+ DebugLoc DL, unsigned O);
+ SDDbgValue *getDbgValue(MDNode *MDPtr, const Value *C, uint64_t Off,
+ DebugLoc DL, unsigned O);
+ SDDbgValue *getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
+ DebugLoc DL, unsigned O);
+
+ /// DAGUpdateListener - Clients of various APIs that cause global effects on
+ /// the DAG can optionally implement this interface. This allows the clients
+ /// to handle the various sorts of updates that happen.
+ class DAGUpdateListener {
+ public:
+ virtual ~DAGUpdateListener();
+
+ /// NodeDeleted - The node N that was deleted and, if E is not null, an
+ /// equivalent node E that replaced it.
+ virtual void NodeDeleted(SDNode *N, SDNode *E) = 0;
+
+ /// NodeUpdated - The node N that was updated.
+ virtual void NodeUpdated(SDNode *N) = 0;
+ };
+
+ /// RemoveDeadNode - Remove the specified node from the system. If any of its
+ /// operands then becomes dead, remove them as well. Inform UpdateListener
+ /// for each node deleted.
+ void RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener = 0);
+
+ /// RemoveDeadNodes - This method deletes the unreachable nodes in the
+ /// given list, and any nodes that become unreachable as a result.
+ void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
+ DAGUpdateListener *UpdateListener = 0);
+
+ /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
+ /// This can cause recursive merging of nodes in the DAG. Use the first
+ /// version if 'From' is known to have a single result, use the second
+ /// if you have two nodes with identical results (or if 'To' has a superset
+ /// of the results of 'From'), use the third otherwise.
+ ///
+ /// These methods all take an optional UpdateListener, which (if not null) is
+ /// informed about nodes that are deleted and modified due to recursive
+ /// changes in the dag.
+ ///
+ /// These functions only replace all existing uses. It's possible that as
+ /// these replacements are being performed, CSE may cause the From node
+ /// to be given new uses. These new uses of From are left in place, and
+ /// not automatically transferred to To.
+ ///
+ void ReplaceAllUsesWith(SDValue From, SDValue Op,
+ DAGUpdateListener *UpdateListener = 0);
+ void ReplaceAllUsesWith(SDNode *From, SDNode *To,
+ DAGUpdateListener *UpdateListener = 0);
+ void ReplaceAllUsesWith(SDNode *From, const SDValue *To,
+ DAGUpdateListener *UpdateListener = 0);
+
+ /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
+ /// uses of other values produced by From.Val alone.
+ void ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
+ DAGUpdateListener *UpdateListener = 0);
+
+ /// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but
+ /// for multiple values at once. This correctly handles the case where
+ /// there is an overlap between the From values and the To values.
+ void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
+ unsigned Num,
+ DAGUpdateListener *UpdateListener = 0);
+
+ /// AssignTopologicalOrder - Topological-sort the AllNodes list and a
+ /// assign a unique node id for each node in the DAG based on their
+ /// topological order. Returns the number of nodes.
+ unsigned AssignTopologicalOrder();
+
+ /// RepositionNode - Move node N in the AllNodes list to be immediately
+ /// before the given iterator Position. This may be used to update the
+ /// topological ordering when the list of nodes is modified.
+ void RepositionNode(allnodes_iterator Position, SDNode *N) {
+ AllNodes.insert(Position, AllNodes.remove(N));
+ }
+
+ /// isCommutativeBinOp - Returns true if the opcode is a commutative binary
+ /// operation.
+ static bool isCommutativeBinOp(unsigned Opcode) {
+ // FIXME: This should get its info from the td file, so that we can include
+ // target info.
+ switch (Opcode) {
+ case ISD::ADD:
+ case ISD::MUL:
+ case ISD::MULHU:
+ case ISD::MULHS:
+ case ISD::SMUL_LOHI:
+ case ISD::UMUL_LOHI:
+ case ISD::FADD:
+ case ISD::FMUL:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::SADDO:
+ case ISD::UADDO:
+ case ISD::ADDC:
+ case ISD::ADDE: return true;
+ default: return false;
+ }
+ }
+
+ /// AssignOrdering - Assign an order to the SDNode.
+ void AssignOrdering(const SDNode *SD, unsigned Order);
+
+ /// GetOrdering - Get the order for the SDNode.
+ unsigned GetOrdering(const SDNode *SD) const;
+
+ /// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
+ /// value is produced by SD.
+ void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
+
+ /// GetDbgValues - Get the debug values which reference the given SDNode.
+ ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) {
+ return DbgInfo->getSDDbgValues(SD);
+ }
+
+ /// TransferDbgValues - Transfer SDDbgValues.
+ void TransferDbgValues(SDValue From, SDValue To);
+
+ /// hasDebugValues - Return true if there are any SDDbgValue nodes associated
+ /// with this SelectionDAG.
+ bool hasDebugValues() const { return !DbgInfo->empty(); }
+
+ SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
+ SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
+ SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
+ return DbgInfo->ByvalParmDbgBegin();
+ }
+ SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
+ return DbgInfo->ByvalParmDbgEnd();
+ }
+
+ void dump() const;
+
+ /// CreateStackTemporary - Create a stack temporary, suitable for holding the
+ /// specified value type. If minAlign is specified, the slot size will have
+ /// at least that alignment.
+ SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1);
+
+ /// CreateStackTemporary - Create a stack temporary suitable for holding
+ /// either of the specified value types.
+ SDValue CreateStackTemporary(EVT VT1, EVT VT2);
+
+ /// FoldConstantArithmetic -
+ SDValue FoldConstantArithmetic(unsigned Opcode,
+ EVT VT,
+ ConstantSDNode *Cst1,
+ ConstantSDNode *Cst2);
+
+ /// FoldSetCC - Constant fold a setcc to true or false.
+ SDValue FoldSetCC(EVT VT, SDValue N1,
+ SDValue N2, ISD::CondCode Cond, DebugLoc dl);
+
+ /// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
+ /// use this predicate to simplify operations downstream.
+ bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
+
+ /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We
+ /// use this predicate to simplify operations downstream. Op and Mask are
+ /// known to be the same type.
+ bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth = 0)
+ const;
+
+ /// ComputeMaskedBits - Determine which of the bits specified in Mask are
+ /// known to be either zero or one and return them in the KnownZero/KnownOne
+ /// bitsets. This code only analyzes bits in Mask, in order to short-circuit
+ /// processing. Targets can implement the computeMaskedBitsForTargetNode
+ /// method in the TargetLowering class to allow target nodes to be understood.
+ void ComputeMaskedBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
+ unsigned Depth = 0) const;
+
+ /// ComputeNumSignBits - Return the number of times the sign bit of the
+ /// register is replicated into the other bits. We know that at least 1 bit
+ /// is always equal to the sign bit (itself), but other cases can give us
+ /// information. For example, immediately after an "SRA X, 2", we know that
+ /// the top 3 bits are all equal to each other, so we return 3. Targets can
+ /// implement the ComputeNumSignBitsForTarget method in the TargetLowering
+ /// class to allow target nodes to be understood.
+ unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
+
+ /// isBaseWithConstantOffset - Return true if the specified operand is an
+ /// ISD::ADD with a ConstantSDNode on the right-hand side, or if it is an
+ /// ISD::OR with a ConstantSDNode that is guaranteed to have the same
+ /// semantics as an ADD. This handles the equivalence:
+ /// X|Cst == X+Cst iff X&Cst = 0.
+ bool isBaseWithConstantOffset(SDValue Op) const;
+
+ /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
+ bool isKnownNeverNaN(SDValue Op) const;
+
+ /// isKnownNeverZero - Test whether the given SDValue is known to never be
+ /// positive or negative Zero.
+ bool isKnownNeverZero(SDValue Op) const;
+
+ /// isEqualTo - Test whether two SDValues are known to compare equal. This
+ /// is true if they are the same value, or if one is negative zero and the
+ /// other positive zero.
+ bool isEqualTo(SDValue A, SDValue B) const;
+
+ /// UnrollVectorOp - Utility function used by legalize and lowering to
+ /// "unroll" a vector operation by splitting out the scalars and operating
+ /// on each element individually. If the ResNE is 0, fully unroll the vector
+ /// op. If ResNE is less than the width of the vector op, unroll up to ResNE.
+ /// If the ResNE is greater than the width of the vector op, unroll the
+ /// vector op and fill the end of the resulting vector with UNDEFS.
+ SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
+
+ /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
+ /// location that is 'Dist' units away from the location that the 'Base' load
+ /// is loading from.
+ bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,
+ unsigned Bytes, int Dist) const;
+
+ /// InferPtrAlignment - Infer alignment of a load / store address. Return 0 if
+ /// it cannot be inferred.
+ unsigned InferPtrAlignment(SDValue Ptr) const;
+
+private:
+ bool RemoveNodeFromCSEMaps(SDNode *N);
+ void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);
+ SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
+ SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
+ void *&InsertPos);
+ SDNode *FindModifiedNodeSlot(SDNode *N, const SDValue *Ops, unsigned NumOps,
+ void *&InsertPos);
+ SDNode *UpdadeDebugLocOnMergedSDNode(SDNode *N, DebugLoc loc);
+
+ void DeleteNodeNotInCSEMaps(SDNode *N);
+ void DeallocateNode(SDNode *N);
+
+ unsigned getEVTAlignment(EVT MemoryVT) const;
+
+ void allnodes_clear();
+
+ /// VTList - List of non-single value types.
+ std::vector<SDVTList> VTList;
+
+ /// CondCodeNodes - Maps to auto-CSE operations.
+ std::vector<CondCodeSDNode*> CondCodeNodes;
+
+ std::vector<SDNode*> ValueTypeNodes;
+ std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes;
+ StringMap<SDNode*> ExternalSymbols;
+
+ std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols;
+};
+
+template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
+ typedef SelectionDAG::allnodes_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(SelectionDAG *G) {
+ return G->allnodes_begin();
+ }
+ static nodes_iterator nodes_end(SelectionDAG *G) {
+ return G->allnodes_end();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h
new file mode 100644
index 000000000000..ee3f2319c0b3
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGISel.h
@@ -0,0 +1,313 @@
+//===-- llvm/CodeGen/SelectionDAGISel.h - Common Base Class------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SelectionDAGISel class, which is used as the common
+// base class for SelectionDAG-based instruction selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+ class FastISel;
+ class SelectionDAGBuilder;
+ class SDValue;
+ class MachineRegisterInfo;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class TargetLowering;
+ class TargetLibraryInfo;
+ class TargetInstrInfo;
+ class FunctionLoweringInfo;
+ class ScheduleHazardRecognizer;
+ class GCFunctionInfo;
+ class ScheduleDAGSDNodes;
+ class LoadInst;
+
+/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
+/// pattern-matching instruction selectors.
+class SelectionDAGISel : public MachineFunctionPass {
+public:
+ const TargetMachine &TM;
+ const TargetLowering &TLI;
+ const TargetLibraryInfo *LibInfo;
+ FunctionLoweringInfo *FuncInfo;
+ MachineFunction *MF;
+ MachineRegisterInfo *RegInfo;
+ SelectionDAG *CurDAG;
+ SelectionDAGBuilder *SDB;
+ AliasAnalysis *AA;
+ GCFunctionInfo *GFI;
+ CodeGenOpt::Level OptLevel;
+ static char ID;
+
+ explicit SelectionDAGISel(const TargetMachine &tm,
+ CodeGenOpt::Level OL = CodeGenOpt::Default);
+ virtual ~SelectionDAGISel();
+
+ const TargetLowering &getTargetLowering() { return TLI; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ virtual void EmitFunctionEntryCode() {}
+
+ /// PreprocessISelDAG - This hook allows targets to hack on the graph before
+ /// instruction selection starts.
+ virtual void PreprocessISelDAG() {}
+
+ /// PostprocessISelDAG() - This hook allows the target to hack on the graph
+ /// right after selection.
+ virtual void PostprocessISelDAG() {}
+
+ /// Select - Main hook targets implement to select a node.
+ virtual SDNode *Select(SDNode *N) = 0;
+
+ /// SelectInlineAsmMemoryOperand - Select the specified address as a target
+ /// addressing mode, according to the specified constraint code. If this does
+ /// not match or is not implemented, return true. The resultant operands
+ /// (which will appear in the machine instruction) should be added to the
+ /// OutOps vector.
+ virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
+ char ConstraintCode,
+ std::vector<SDValue> &OutOps) {
+ return true;
+ }
+
+ /// IsProfitableToFold - Returns true if it's profitable to fold the specific
+ /// operand node N of U during instruction selection that starts at Root.
+ virtual bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const;
+
+ /// IsLegalToFold - Returns true if the specific operand node N of
+ /// U can be folded during instruction selection that starts at Root.
+ /// FIXME: This is a static member function because the MSP430/X86
+ /// targets, which uses it during isel. This could become a proper member.
+ static bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
+ CodeGenOpt::Level OptLevel,
+ bool IgnoreChains = false);
+
+ // Opcodes used by the DAG state machine:
+ enum BuiltinOpcodes {
+ OPC_Scope,
+ OPC_RecordNode,
+ OPC_RecordChild0, OPC_RecordChild1, OPC_RecordChild2, OPC_RecordChild3,
+ OPC_RecordChild4, OPC_RecordChild5, OPC_RecordChild6, OPC_RecordChild7,
+ OPC_RecordMemRef,
+ OPC_CaptureGlueInput,
+ OPC_MoveChild,
+ OPC_MoveParent,
+ OPC_CheckSame,
+ OPC_CheckPatternPredicate,
+ OPC_CheckPredicate,
+ OPC_CheckOpcode,
+ OPC_SwitchOpcode,
+ OPC_CheckType,
+ OPC_SwitchType,
+ OPC_CheckChild0Type, OPC_CheckChild1Type, OPC_CheckChild2Type,
+ OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
+ OPC_CheckChild6Type, OPC_CheckChild7Type,
+ OPC_CheckInteger,
+ OPC_CheckCondCode,
+ OPC_CheckValueType,
+ OPC_CheckComplexPat,
+ OPC_CheckAndImm, OPC_CheckOrImm,
+ OPC_CheckFoldableChainNode,
+
+ OPC_EmitInteger,
+ OPC_EmitRegister,
+ OPC_EmitRegister2,
+ OPC_EmitConvertToTarget,
+ OPC_EmitMergeInputChains,
+ OPC_EmitMergeInputChains1_0,
+ OPC_EmitMergeInputChains1_1,
+ OPC_EmitCopyToReg,
+ OPC_EmitNodeXForm,
+ OPC_EmitNode,
+ OPC_MorphNodeTo,
+ OPC_MarkGlueResults,
+ OPC_CompleteMatch
+ };
+
+ enum {
+ OPFL_None = 0, // Node has no chain or glue input and isn't variadic.
+ OPFL_Chain = 1, // Node has a chain input.
+ OPFL_GlueInput = 2, // Node has a glue input.
+ OPFL_GlueOutput = 4, // Node has a glue output.
+ OPFL_MemRefs = 8, // Node gets accumulated MemRefs.
+ OPFL_Variadic0 = 1<<4, // Node is variadic, root has 0 fixed inputs.
+ OPFL_Variadic1 = 2<<4, // Node is variadic, root has 1 fixed inputs.
+ OPFL_Variadic2 = 3<<4, // Node is variadic, root has 2 fixed inputs.
+ OPFL_Variadic3 = 4<<4, // Node is variadic, root has 3 fixed inputs.
+ OPFL_Variadic4 = 5<<4, // Node is variadic, root has 4 fixed inputs.
+ OPFL_Variadic5 = 6<<4, // Node is variadic, root has 5 fixed inputs.
+ OPFL_Variadic6 = 7<<4, // Node is variadic, root has 6 fixed inputs.
+
+ OPFL_VariadicInfo = OPFL_Variadic6
+ };
+
+ /// getNumFixedFromVariadicInfo - Transform an EmitNode flags word into the
+ /// number of fixed arity values that should be skipped when copying from the
+ /// root.
+ static inline int getNumFixedFromVariadicInfo(unsigned Flags) {
+ return ((Flags&OPFL_VariadicInfo) >> 4)-1;
+ }
+
+
+protected:
+ /// DAGSize - Size of DAG being instruction selected.
+ ///
+ unsigned DAGSize;
+
+ /// ISelPosition - Node iterator marking the current position of
+ /// instruction selection as it procedes through the topologically-sorted
+ /// node list.
+ SelectionDAG::allnodes_iterator ISelPosition;
+
+
+ /// ISelUpdater - helper class to handle updates of the
+ /// instruction selection graph.
+ class ISelUpdater : public SelectionDAG::DAGUpdateListener {
+ virtual void anchor();
+ SelectionDAG::allnodes_iterator &ISelPosition;
+ public:
+ explicit ISelUpdater(SelectionDAG::allnodes_iterator &isp)
+ : ISelPosition(isp) {}
+
+ /// NodeDeleted - Handle nodes deleted from the graph. If the
+ /// node being deleted is the current ISelPosition node, update
+ /// ISelPosition.
+ ///
+ virtual void NodeDeleted(SDNode *N, SDNode *E) {
+ if (ISelPosition == SelectionDAG::allnodes_iterator(N))
+ ++ISelPosition;
+ }
+
+ /// NodeUpdated - Ignore updates for now.
+ virtual void NodeUpdated(SDNode *N) {}
+ };
+
+ /// ReplaceUses - replace all uses of the old node F with the use
+ /// of the new node T.
+ void ReplaceUses(SDValue F, SDValue T) {
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->ReplaceAllUsesOfValueWith(F, T, &ISU);
+ }
+
+ /// ReplaceUses - replace all uses of the old nodes F with the use
+ /// of the new nodes T.
+ void ReplaceUses(const SDValue *F, const SDValue *T, unsigned Num) {
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISU);
+ }
+
+ /// ReplaceUses - replace all uses of the old node F with the use
+ /// of the new node T.
+ void ReplaceUses(SDNode *F, SDNode *T) {
+ ISelUpdater ISU(ISelPosition);
+ CurDAG->ReplaceAllUsesWith(F, T, &ISU);
+ }
+
+
+ /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
+ /// by tblgen. Others should not call it.
+ void SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops);
+
+
+public:
+ // Calls to these predicates are generated by tblgen.
+ bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
+ int64_t DesiredMaskS) const;
+ bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
+ int64_t DesiredMaskS) const;
+
+
+ /// CheckPatternPredicate - This function is generated by tblgen in the
+ /// target. It runs the specified pattern predicate and returns true if it
+ /// succeeds or false if it fails. The number is a private implementation
+ /// detail to the code tblgen produces.
+ virtual bool CheckPatternPredicate(unsigned PredNo) const {
+ llvm_unreachable("Tblgen should generate the implementation of this!");
+ }
+
+ /// CheckNodePredicate - This function is generated by tblgen in the target.
+ /// It runs node predicate number PredNo and returns true if it succeeds or
+ /// false if it fails. The number is a private implementation
+ /// detail to the code tblgen produces.
+ virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const {
+ llvm_unreachable("Tblgen should generate the implementation of this!");
+ }
+
+ virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N,
+ unsigned PatternNo,
+ SmallVectorImpl<std::pair<SDValue, SDNode*> > &Result) {
+ llvm_unreachable("Tblgen should generate the implementation of this!");
+ }
+
+ virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) {
+ llvm_unreachable("Tblgen should generate this!");
+ }
+
+ SDNode *SelectCodeCommon(SDNode *NodeToMatch,
+ const unsigned char *MatcherTable,
+ unsigned TableSize);
+
+private:
+
+ // Calls to these functions are generated by tblgen.
+ SDNode *Select_INLINEASM(SDNode *N);
+ SDNode *Select_UNDEF(SDNode *N);
+ void CannotYetSelect(SDNode *N);
+
+private:
+ void DoInstructionSelection();
+ SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
+
+ void PrepareEHLandingPad();
+ void SelectAllBasicBlocks(const Function &Fn);
+ bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst,
+ FastISel *FastIS);
+ void FinishBasicBlock();
+
+ void SelectBasicBlock(BasicBlock::const_iterator Begin,
+ BasicBlock::const_iterator End,
+ bool &HadTailCall);
+ void CodeGenAndEmitDAG();
+ void LowerArguments(const BasicBlock *BB);
+
+ void ComputeLiveOutVRegInfo();
+
+ /// Create the scheduler. If a specific scheduler was specified
+ /// via the SchedulerRegistry, use it, otherwise select the
+ /// one preferred by the target.
+ ///
+ ScheduleDAGSDNodes *CreateScheduler();
+
+ /// OpcodeOffset - This is a cache used to dispatch efficiently into isel
+ /// state machines that start with a OPC_SwitchOpcode node.
+ std::vector<unsigned> OpcodeOffset;
+
+ void UpdateChainsAndGlue(SDNode *NodeToMatch, SDValue InputChain,
+ const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+ SDValue InputGlue, const SmallVectorImpl<SDNode*> &F,
+ bool isMorphNodeTo);
+
+};
+
+}
+
+#endif /* LLVM_CODEGEN_SELECTIONDAG_ISEL_H */
diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
new file mode 100644
index 000000000000..f8248b845337
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -0,0 +1,1858 @@
+//===-- llvm/CodeGen/SelectionDAGNodes.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.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SDNode class and derived classes, which are used to
+// represent the nodes and operations present in a SelectionDAG. These nodes
+// and operations are machine code level operations, with some similarities to
+// the GCC RTL representation.
+//
+// Clients should include the SelectionDAG.h file instead of this file directly.
+//
+//===----------------------------------------------------------------------===//
+
+#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/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DebugLoc.h"
+#include <cassert>
+
+namespace llvm {
+
+class SelectionDAG;
+class GlobalValue;
+class MachineBasicBlock;
+class MachineConstantPoolValue;
+class SDNode;
+class Value;
+class MCSymbol;
+template <typename T> struct DenseMapInfo;
+template <typename T> struct simplify_type;
+template <typename T> struct ilist_traits;
+
+void checkForCycles(const SDNode *N);
+
+/// SDVTList - This represents a list of ValueType's that has been intern'd by
+/// a SelectionDAG. Instances of this simple value class are returned by
+/// SelectionDAG::getVTList(...).
+///
+struct SDVTList {
+ const EVT *VTs;
+ unsigned int NumVTs;
+};
+
+namespace ISD {
+ /// Node predicates
+
+ /// isBuildVectorAllOnes - Return true if the specified node is a
+ /// BUILD_VECTOR where all of the elements are ~0 or undef.
+ bool isBuildVectorAllOnes(const SDNode *N);
+
+ /// isBuildVectorAllZeros - Return true if the specified node is a
+ /// BUILD_VECTOR where all of the elements are 0 or undef.
+ bool isBuildVectorAllZeros(const SDNode *N);
+
+ /// isScalarToVector - Return true if the specified node is a
+ /// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
+ /// element is not an undef.
+ bool isScalarToVector(const SDNode *N);
+} // end llvm:ISD namespace
+
+//===----------------------------------------------------------------------===//
+/// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple
+/// values as the result of a computation. Many nodes return multiple values,
+/// from loads (which define a token and a return value) to ADDC (which returns
+/// a result and a carry value), to calls (which may return an arbitrary number
+/// of values).
+///
+/// As such, each use of a SelectionDAG computation must indicate the node that
+/// computes it as well as which return value to use from that node. This pair
+/// of information is represented with the SDValue value type.
+///
+class SDValue {
+ SDNode *Node; // The node defining the value we are using.
+ unsigned ResNo; // Which return value of the node we are using.
+public:
+ SDValue() : Node(0), ResNo(0) {}
+ SDValue(SDNode *node, unsigned resno) : Node(node), ResNo(resno) {}
+
+ /// get the index which selects a specific result in the SDNode
+ unsigned getResNo() const { return ResNo; }
+
+ /// get the SDNode which holds the desired result
+ SDNode *getNode() const { return Node; }
+
+ /// set the SDNode
+ void setNode(SDNode *N) { Node = N; }
+
+ inline SDNode *operator->() const { return Node; }
+
+ bool operator==(const SDValue &O) const {
+ return Node == O.Node && ResNo == O.ResNo;
+ }
+ bool operator!=(const SDValue &O) const {
+ return !operator==(O);
+ }
+ bool operator<(const SDValue &O) const {
+ return Node < O.Node || (Node == O.Node && ResNo < O.ResNo);
+ }
+
+ SDValue getValue(unsigned R) const {
+ return SDValue(Node, R);
+ }
+
+ // isOperandOf - Return true if this node is an operand of N.
+ bool isOperandOf(SDNode *N) const;
+
+ /// getValueType - Return the ValueType of the referenced return value.
+ ///
+ inline EVT getValueType() const;
+
+ /// getValueSizeInBits - Returns the size of the value in bits.
+ ///
+ unsigned getValueSizeInBits() const {
+ return getValueType().getSizeInBits();
+ }
+
+ // Forwarding methods - These forward to the corresponding methods in SDNode.
+ inline unsigned getOpcode() const;
+ inline unsigned getNumOperands() const;
+ inline const SDValue &getOperand(unsigned i) const;
+ inline uint64_t getConstantOperandVal(unsigned i) const;
+ inline bool isTargetMemoryOpcode() const;
+ inline bool isTargetOpcode() const;
+ inline bool isMachineOpcode() const;
+ inline unsigned getMachineOpcode() const;
+ inline const DebugLoc getDebugLoc() const;
+
+
+ /// reachesChainWithoutSideEffects - Return true if this operand (which must
+ /// be a chain) reaches the specified operand without crossing any
+ /// side-effecting instructions. In practice, this looks through token
+ /// factors and non-volatile loads. In order to remain efficient, this only
+ /// looks a couple of nodes in, it does not do an exhaustive search.
+ bool reachesChainWithoutSideEffects(SDValue Dest,
+ unsigned Depth = 2) const;
+
+ /// use_empty - Return true if there are no nodes using value ResNo
+ /// of Node.
+ ///
+ inline bool use_empty() const;
+
+ /// hasOneUse - Return true if there is exactly one node using value
+ /// ResNo of Node.
+ ///
+ inline bool hasOneUse() const;
+};
+
+
+template<> struct DenseMapInfo<SDValue> {
+ static inline SDValue getEmptyKey() {
+ return SDValue((SDNode*)-1, -1U);
+ }
+ static inline SDValue getTombstoneKey() {
+ return SDValue((SDNode*)-1, 0);
+ }
+ static unsigned getHashValue(const SDValue &Val) {
+ return ((unsigned)((uintptr_t)Val.getNode() >> 4) ^
+ (unsigned)((uintptr_t)Val.getNode() >> 9)) + Val.getResNo();
+ }
+ static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
+ return LHS == RHS;
+ }
+};
+template <> struct isPodLike<SDValue> { static const bool value = true; };
+
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDValues as if they were SDNode*'s.
+template<> struct simplify_type<SDValue> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDValue &Val) {
+ return static_cast<SimpleType>(Val.getNode());
+ }
+};
+template<> struct simplify_type<const SDValue> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDValue &Val) {
+ return static_cast<SimpleType>(Val.getNode());
+ }
+};
+
+/// SDUse - Represents a use of a SDNode. This class holds an SDValue,
+/// which records the SDNode being used and the result number, a
+/// pointer to the SDNode using the value, and Next and Prev pointers,
+/// which link together all the uses of an SDNode.
+///
+class SDUse {
+ /// Val - The value being used.
+ SDValue Val;
+ /// User - The user of this value.
+ SDNode *User;
+ /// Prev, Next - Pointers to the uses list of the SDNode referred by
+ /// this operand.
+ SDUse **Prev, *Next;
+
+ SDUse(const SDUse &U); // Do not implement
+ void operator=(const SDUse &U); // Do not implement
+
+public:
+ SDUse() : Val(), User(NULL), Prev(NULL), Next(NULL) {}
+
+ /// Normally SDUse will just implicitly convert to an SDValue that it holds.
+ operator const SDValue&() const { return Val; }
+
+ /// If implicit conversion to SDValue doesn't work, the get() method returns
+ /// the SDValue.
+ const SDValue &get() const { return Val; }
+
+ /// getUser - This returns the SDNode that contains this Use.
+ SDNode *getUser() { return User; }
+
+ /// getNext - Get the next SDUse in the use list.
+ SDUse *getNext() const { return Next; }
+
+ /// getNode - Convenience function for get().getNode().
+ SDNode *getNode() const { return Val.getNode(); }
+ /// getResNo - Convenience function for get().getResNo().
+ unsigned getResNo() const { return Val.getResNo(); }
+ /// getValueType - Convenience function for get().getValueType().
+ EVT getValueType() const { return Val.getValueType(); }
+
+ /// operator== - Convenience function for get().operator==
+ bool operator==(const SDValue &V) const {
+ return Val == V;
+ }
+
+ /// operator!= - Convenience function for get().operator!=
+ bool operator!=(const SDValue &V) const {
+ return Val != V;
+ }
+
+ /// operator< - Convenience function for get().operator<
+ bool operator<(const SDValue &V) const {
+ return Val < V;
+ }
+
+private:
+ friend class SelectionDAG;
+ friend class SDNode;
+
+ void setUser(SDNode *p) { User = p; }
+
+ /// set - Remove this use from its existing use list, assign it the
+ /// given value, and add it to the new value's node's use list.
+ inline void set(const SDValue &V);
+ /// setInitial - like set, but only supports initializing a newly-allocated
+ /// SDUse with a non-null value.
+ inline void setInitial(const SDValue &V);
+ /// setNode - like set, but only sets the Node portion of the value,
+ /// leaving the ResNo portion unmodified.
+ inline void setNode(SDNode *N);
+
+ void addToList(SDUse **List) {
+ Next = *List;
+ if (Next) Next->Prev = &Next;
+ Prev = List;
+ *List = this;
+ }
+
+ void removeFromList() {
+ *Prev = Next;
+ if (Next) Next->Prev = Prev;
+ }
+};
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDValues as if they were SDNode*'s.
+template<> struct simplify_type<SDUse> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDUse &Val) {
+ return static_cast<SimpleType>(Val.getNode());
+ }
+};
+template<> struct simplify_type<const SDUse> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDUse &Val) {
+ return static_cast<SimpleType>(Val.getNode());
+ }
+};
+
+
+/// SDNode - Represents one node in the SelectionDAG.
+///
+class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
+private:
+ /// NodeType - The operation that this node performs.
+ ///
+ int16_t NodeType;
+
+ /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true,
+ /// then they will be delete[]'d when the node is destroyed.
+ uint16_t OperandsNeedDelete : 1;
+
+ /// HasDebugValue - This tracks whether this node has one or more dbg_value
+ /// nodes corresponding to it.
+ uint16_t HasDebugValue : 1;
+
+protected:
+ /// SubclassData - This member is defined by this class, but is not used for
+ /// anything. Subclasses can use it to hold whatever state they find useful.
+ /// This field is initialized to zero by the ctor.
+ uint16_t SubclassData : 14;
+
+private:
+ /// NodeId - Unique id per SDNode in the DAG.
+ int NodeId;
+
+ /// OperandList - The values that are used by this operation.
+ ///
+ SDUse *OperandList;
+
+ /// ValueList - The types of the values this node defines. SDNode's may
+ /// define multiple values simultaneously.
+ const EVT *ValueList;
+
+ /// UseList - List of uses for this SDNode.
+ SDUse *UseList;
+
+ /// NumOperands/NumValues - The number of entries in the Operand/Value list.
+ unsigned short NumOperands, NumValues;
+
+ /// debugLoc - source line information.
+ DebugLoc debugLoc;
+
+ /// getValueTypeList - Return a pointer to the specified value type.
+ static const EVT *getValueTypeList(EVT VT);
+
+ friend class SelectionDAG;
+ friend struct ilist_traits<SDNode>;
+
+public:
+ //===--------------------------------------------------------------------===//
+ // Accessors
+ //
+
+ /// getOpcode - Return the SelectionDAG opcode value for this node. For
+ /// pre-isel nodes (those for which isMachineOpcode returns false), these
+ /// are the opcode values in the ISD and <target>ISD namespaces. For
+ /// post-isel opcodes, see getMachineOpcode.
+ unsigned getOpcode() const { return (unsigned short)NodeType; }
+
+ /// isTargetOpcode - Test if this node has a target-specific opcode (in the
+ /// \<target\>ISD namespace).
+ bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
+
+ /// isTargetMemoryOpcode - Test if this node has a target-specific
+ /// memory-referencing opcode (in the \<target\>ISD namespace and
+ /// greater than FIRST_TARGET_MEMORY_OPCODE).
+ bool isTargetMemoryOpcode() const {
+ return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
+ }
+
+ /// isMachineOpcode - Test if this node has a post-isel opcode, directly
+ /// corresponding to a MachineInstr opcode.
+ bool isMachineOpcode() const { return NodeType < 0; }
+
+ /// getMachineOpcode - This may only be called if isMachineOpcode returns
+ /// true. It returns the MachineInstr opcode value that the node's opcode
+ /// corresponds to.
+ unsigned getMachineOpcode() const {
+ assert(isMachineOpcode() && "Not a MachineInstr opcode!");
+ return ~NodeType;
+ }
+
+ /// getHasDebugValue - get this bit.
+ bool getHasDebugValue() const { return HasDebugValue; }
+
+ /// setHasDebugValue - set this bit.
+ void setHasDebugValue(bool b) { HasDebugValue = b; }
+
+ /// use_empty - Return true if there are no uses of this node.
+ ///
+ bool use_empty() const { return UseList == NULL; }
+
+ /// hasOneUse - Return true if there is exactly one use of this node.
+ ///
+ bool hasOneUse() const {
+ return !use_empty() && llvm::next(use_begin()) == use_end();
+ }
+
+ /// use_size - Return the number of uses of this node. This method takes
+ /// time proportional to the number of uses.
+ ///
+ size_t use_size() const { return std::distance(use_begin(), use_end()); }
+
+ /// getNodeId - Return the unique node id.
+ ///
+ int getNodeId() const { return NodeId; }
+
+ /// setNodeId - Set unique node id.
+ void setNodeId(int Id) { NodeId = Id; }
+
+ /// getDebugLoc - Return the source location info.
+ const DebugLoc getDebugLoc() const { return debugLoc; }
+
+ /// setDebugLoc - Set source location info. Try to avoid this, putting
+ /// it in the constructor is preferable.
+ void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }
+
+ /// use_iterator - This class provides iterator support for SDUse
+ /// operands that use a specific SDNode.
+ class use_iterator
+ : public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> {
+ SDUse *Op;
+ explicit use_iterator(SDUse *op) : Op(op) {
+ }
+ friend class SDNode;
+ public:
+ typedef std::iterator<std::forward_iterator_tag,
+ SDUse, ptrdiff_t>::reference reference;
+ typedef std::iterator<std::forward_iterator_tag,
+ SDUse, ptrdiff_t>::pointer pointer;
+
+ use_iterator(const use_iterator &I) : Op(I.Op) {}
+ use_iterator() : Op(0) {}
+
+ bool operator==(const use_iterator &x) const {
+ return Op == x.Op;
+ }
+ bool operator!=(const use_iterator &x) const {
+ return !operator==(x);
+ }
+
+ /// atEnd - return true if this iterator is at the end of uses list.
+ bool atEnd() const { return Op == 0; }
+
+ // Iterator traversal: forward iteration only.
+ use_iterator &operator++() { // Preincrement
+ assert(Op && "Cannot increment end iterator!");
+ Op = Op->getNext();
+ return *this;
+ }
+
+ use_iterator operator++(int) { // Postincrement
+ use_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ /// Retrieve a pointer to the current user node.
+ SDNode *operator*() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return Op->getUser();
+ }
+
+ SDNode *operator->() const { return operator*(); }
+
+ SDUse &getUse() const { return *Op; }
+
+ /// getOperandNo - Retrieve the operand # of this use in its user.
+ ///
+ unsigned getOperandNo() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return (unsigned)(Op - Op->getUser()->OperandList);
+ }
+ };
+
+ /// use_begin/use_end - Provide iteration support to walk over all uses
+ /// of an SDNode.
+
+ use_iterator use_begin() const {
+ return use_iterator(UseList);
+ }
+
+ static use_iterator use_end() { return use_iterator(0); }
+
+
+ /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
+ /// indicated value. This method ignores uses of other values defined by this
+ /// operation.
+ bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
+
+ /// hasAnyUseOfValue - Return true if there are any use of the indicated
+ /// value. This method ignores uses of other values defined by this operation.
+ bool hasAnyUseOfValue(unsigned Value) const;
+
+ /// isOnlyUserOf - Return true if this node is the only use of N.
+ ///
+ bool isOnlyUserOf(SDNode *N) const;
+
+ /// isOperandOf - Return true if this node is an operand of N.
+ ///
+ bool isOperandOf(SDNode *N) const;
+
+ /// isPredecessorOf - Return true if this node is a predecessor of N.
+ /// NOTE: Implemented on top of hasPredecessor and every bit as
+ /// expensive. Use carefully.
+ bool isPredecessorOf(const SDNode *N) const { return N->hasPredecessor(this); }
+
+ /// hasPredecessor - Return true if N is a predecessor of this node.
+ /// N is either an operand of this node, or can be reached by recursively
+ /// traversing up the operands.
+ /// NOTE: This is an expensive method. Use it carefully.
+ bool hasPredecessor(const SDNode *N) const;
+
+ /// hasPredecesorHelper - Return true if N is a predecessor of this node.
+ /// N is either an operand of this node, or can be reached by recursively
+ /// traversing up the operands.
+ /// In this helper the Visited and worklist sets are held externally to
+ /// cache predecessors over multiple invocations. If you want to test for
+ /// multiple predecessors this method is preferable to multiple calls to
+ /// hasPredecessor. Be sure to clear Visited and Worklist if the DAG
+ /// changes.
+ /// NOTE: This is still very expensive. Use carefully.
+ bool hasPredecessorHelper(const SDNode *N,
+ SmallPtrSet<const SDNode *, 32> &Visited,
+ SmallVector<const SDNode *, 16> &Worklist) const;
+
+ /// getNumOperands - Return the number of values used by this operation.
+ ///
+ unsigned getNumOperands() const { return NumOperands; }
+
+ /// getConstantOperandVal - Helper method returns the integer value of a
+ /// ConstantSDNode operand.
+ uint64_t getConstantOperandVal(unsigned Num) const;
+
+ const SDValue &getOperand(unsigned Num) const {
+ assert(Num < NumOperands && "Invalid child # of SDNode!");
+ return OperandList[Num];
+ }
+
+ typedef SDUse* op_iterator;
+ op_iterator op_begin() const { return OperandList; }
+ op_iterator op_end() const { return OperandList+NumOperands; }
+
+ SDVTList getVTList() const {
+ SDVTList X = { ValueList, NumValues };
+ return X;
+ }
+
+ /// getGluedNode - If this node has a glue operand, return the node
+ /// to which the glue operand points. Otherwise return NULL.
+ SDNode *getGluedNode() const {
+ if (getNumOperands() != 0 &&
+ getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
+ return getOperand(getNumOperands()-1).getNode();
+ return 0;
+ }
+
+ // If this is a pseudo op, like copyfromreg, look to see if there is a
+ // real target node glued to it. If so, return the target node.
+ const SDNode *getGluedMachineNode() const {
+ const SDNode *FoundNode = this;
+
+ // Climb up glue edges until a machine-opcode node is found, or the
+ // end of the chain is reached.
+ while (!FoundNode->isMachineOpcode()) {
+ const SDNode *N = FoundNode->getGluedNode();
+ if (!N) break;
+ FoundNode = N;
+ }
+
+ return FoundNode;
+ }
+
+ /// getGluedUser - If this node has a glue value with a user, return
+ /// the user (there is at most one). Otherwise return NULL.
+ SDNode *getGluedUser() const {
+ for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
+ if (UI.getUse().get().getValueType() == MVT::Glue)
+ return *UI;
+ return 0;
+ }
+
+ /// getNumValues - Return the number of values defined/returned by this
+ /// operator.
+ ///
+ unsigned getNumValues() const { return NumValues; }
+
+ /// getValueType - Return the type of a specified result.
+ ///
+ EVT getValueType(unsigned ResNo) const {
+ assert(ResNo < NumValues && "Illegal result number!");
+ return ValueList[ResNo];
+ }
+
+ /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)).
+ ///
+ unsigned getValueSizeInBits(unsigned ResNo) const {
+ return getValueType(ResNo).getSizeInBits();
+ }
+
+ typedef const EVT* value_iterator;
+ value_iterator value_begin() const { return ValueList; }
+ value_iterator value_end() const { return ValueList+NumValues; }
+
+ /// getOperationName - Return the opcode of this operation for printing.
+ ///
+ std::string getOperationName(const SelectionDAG *G = 0) const;
+ static const char* getIndexedModeName(ISD::MemIndexedMode AM);
+ void print_types(raw_ostream &OS, const SelectionDAG *G) const;
+ void print_details(raw_ostream &OS, const SelectionDAG *G) const;
+ void print(raw_ostream &OS, const SelectionDAG *G = 0) const;
+ void printr(raw_ostream &OS, const SelectionDAG *G = 0) const;
+
+ /// printrFull - Print a SelectionDAG node and all children down to
+ /// the leaves. The given SelectionDAG allows target-specific nodes
+ /// to be printed in human-readable form. Unlike printr, this will
+ /// print the whole DAG, including children that appear multiple
+ /// times.
+ ///
+ void printrFull(raw_ostream &O, const SelectionDAG *G = 0) const;
+
+ /// printrWithDepth - Print a SelectionDAG node and children up to
+ /// depth "depth." The given SelectionDAG allows target-specific
+ /// nodes to be printed in human-readable form. Unlike printr, this
+ /// will print children that appear multiple times wherever they are
+ /// used.
+ ///
+ void printrWithDepth(raw_ostream &O, const SelectionDAG *G = 0,
+ unsigned depth = 100) const;
+
+
+ /// dump - Dump this node, for debugging.
+ void dump() const;
+
+ /// dumpr - Dump (recursively) this node and its use-def subgraph.
+ void dumpr() const;
+
+ /// dump - Dump this node, for debugging.
+ /// The given SelectionDAG allows target-specific nodes to be printed
+ /// in human-readable form.
+ void dump(const SelectionDAG *G) const;
+
+ /// dumpr - Dump (recursively) this node and its use-def subgraph.
+ /// The given SelectionDAG allows target-specific nodes to be printed
+ /// in human-readable form.
+ void dumpr(const SelectionDAG *G) const;
+
+ /// dumprFull - printrFull to dbgs(). The given SelectionDAG allows
+ /// target-specific nodes to be printed in human-readable form.
+ /// Unlike dumpr, this will print the whole DAG, including children
+ /// that appear multiple times.
+ ///
+ void dumprFull(const SelectionDAG *G = 0) const;
+
+ /// dumprWithDepth - printrWithDepth to dbgs(). The given
+ /// SelectionDAG allows target-specific nodes to be printed in
+ /// human-readable form. Unlike dumpr, this will print children
+ /// that appear multiple times wherever they are used.
+ ///
+ void dumprWithDepth(const SelectionDAG *G = 0, unsigned depth = 100) const;
+
+
+ static bool classof(const SDNode *) { return true; }
+
+ /// Profile - Gather unique data for the node.
+ ///
+ void Profile(FoldingSetNodeID &ID) const;
+
+ /// addUse - This method should only be used by the SDUse class.
+ ///
+ void addUse(SDUse &U) { U.addToList(&UseList); }
+
+protected:
+ static SDVTList getSDVTList(EVT VT) {
+ SDVTList Ret = { getValueTypeList(VT), 1 };
+ return Ret;
+ }
+
+ SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops,
+ unsigned NumOps)
+ : NodeType(Opc), OperandsNeedDelete(true), HasDebugValue(false),
+ SubclassData(0), NodeId(-1),
+ OperandList(NumOps ? new SDUse[NumOps] : 0),
+ ValueList(VTs.VTs), UseList(NULL),
+ NumOperands(NumOps), NumValues(VTs.NumVTs),
+ debugLoc(dl) {
+ for (unsigned i = 0; i != NumOps; ++i) {
+ OperandList[i].setUser(this);
+ OperandList[i].setInitial(Ops[i]);
+ }
+ checkForCycles(this);
+ }
+
+ /// This constructor adds no operands itself; operands can be
+ /// set later with InitOperands.
+ SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs)
+ : NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false),
+ SubclassData(0), NodeId(-1), OperandList(0), ValueList(VTs.VTs),
+ UseList(NULL), NumOperands(0), NumValues(VTs.NumVTs),
+ debugLoc(dl) {}
+
+ /// InitOperands - Initialize the operands list of this with 1 operand.
+ void InitOperands(SDUse *Ops, const SDValue &Op0) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ NumOperands = 1;
+ OperandList = Ops;
+ checkForCycles(this);
+ }
+
+ /// InitOperands - Initialize the operands list of this with 2 operands.
+ void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ Ops[1].setUser(this);
+ Ops[1].setInitial(Op1);
+ NumOperands = 2;
+ OperandList = Ops;
+ checkForCycles(this);
+ }
+
+ /// InitOperands - Initialize the operands list of this with 3 operands.
+ void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+ const SDValue &Op2) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ Ops[1].setUser(this);
+ Ops[1].setInitial(Op1);
+ Ops[2].setUser(this);
+ Ops[2].setInitial(Op2);
+ NumOperands = 3;
+ OperandList = Ops;
+ checkForCycles(this);
+ }
+
+ /// InitOperands - Initialize the operands list of this with 4 operands.
+ void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+ const SDValue &Op2, const SDValue &Op3) {
+ Ops[0].setUser(this);
+ Ops[0].setInitial(Op0);
+ Ops[1].setUser(this);
+ Ops[1].setInitial(Op1);
+ Ops[2].setUser(this);
+ Ops[2].setInitial(Op2);
+ Ops[3].setUser(this);
+ Ops[3].setInitial(Op3);
+ NumOperands = 4;
+ OperandList = Ops;
+ checkForCycles(this);
+ }
+
+ /// InitOperands - Initialize the operands list of this with N operands.
+ void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) {
+ for (unsigned i = 0; i != N; ++i) {
+ Ops[i].setUser(this);
+ Ops[i].setInitial(Vals[i]);
+ }
+ NumOperands = N;
+ OperandList = Ops;
+ checkForCycles(this);
+ }
+
+ /// DropOperands - Release the operands and set this node to have
+ /// zero operands.
+ void DropOperands();
+};
+
+
+// Define inline functions from the SDValue class.
+
+inline unsigned SDValue::getOpcode() const {
+ return Node->getOpcode();
+}
+inline EVT SDValue::getValueType() const {
+ return Node->getValueType(ResNo);
+}
+inline unsigned SDValue::getNumOperands() const {
+ return Node->getNumOperands();
+}
+inline const SDValue &SDValue::getOperand(unsigned i) const {
+ return Node->getOperand(i);
+}
+inline uint64_t SDValue::getConstantOperandVal(unsigned i) const {
+ return Node->getConstantOperandVal(i);
+}
+inline bool SDValue::isTargetOpcode() const {
+ return Node->isTargetOpcode();
+}
+inline bool SDValue::isTargetMemoryOpcode() const {
+ return Node->isTargetMemoryOpcode();
+}
+inline bool SDValue::isMachineOpcode() const {
+ return Node->isMachineOpcode();
+}
+inline unsigned SDValue::getMachineOpcode() const {
+ return Node->getMachineOpcode();
+}
+inline bool SDValue::use_empty() const {
+ return !Node->hasAnyUseOfValue(ResNo);
+}
+inline bool SDValue::hasOneUse() const {
+ return Node->hasNUsesOfValue(1, ResNo);
+}
+inline const DebugLoc SDValue::getDebugLoc() const {
+ return Node->getDebugLoc();
+}
+
+// Define inline functions from the SDUse class.
+
+inline void SDUse::set(const SDValue &V) {
+ if (Val.getNode()) removeFromList();
+ Val = V;
+ if (V.getNode()) V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setInitial(const SDValue &V) {
+ Val = V;
+ V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setNode(SDNode *N) {
+ if (Val.getNode()) removeFromList();
+ Val.setNode(N);
+ if (N) N->addUse(*this);
+}
+
+/// UnarySDNode - This class is used for single-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class UnarySDNode : public SDNode {
+ SDUse Op;
+public:
+ UnarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X)
+ : SDNode(Opc, dl, VTs) {
+ InitOperands(&Op, X);
+ }
+};
+
+/// BinarySDNode - This class is used for two-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class BinarySDNode : public SDNode {
+ SDUse Ops[2];
+public:
+ BinarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y)
+ : SDNode(Opc, dl, VTs) {
+ InitOperands(Ops, X, Y);
+ }
+};
+
+/// TernarySDNode - This class is used for three-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class TernarySDNode : public SDNode {
+ SDUse Ops[3];
+public:
+ TernarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y,
+ SDValue Z)
+ : SDNode(Opc, dl, VTs) {
+ InitOperands(Ops, X, Y, Z);
+ }
+};
+
+
+/// HandleSDNode - This class is used to form a handle around another node that
+/// is persistent and is updated across invocations of replaceAllUsesWith on its
+/// operand. This node should be directly created by end-users and not added to
+/// the AllNodes list.
+class HandleSDNode : public SDNode {
+ SDUse Op;
+public:
+ // FIXME: Remove the "noinline" attribute once <rdar://problem/5852746> is
+ // fixed.
+#if __GNUC__==4 && __GNUC_MINOR__==2 && defined(__APPLE__) && !defined(__llvm__)
+ explicit __attribute__((__noinline__)) HandleSDNode(SDValue X)
+#else
+ explicit HandleSDNode(SDValue X)
+#endif
+ : SDNode(ISD::HANDLENODE, DebugLoc(), getSDVTList(MVT::Other)) {
+ InitOperands(&Op, X);
+ }
+ ~HandleSDNode();
+ const SDValue &getValue() const { return Op; }
+};
+
+/// Abstact virtual class for operations for memory operations
+class MemSDNode : public SDNode {
+private:
+ // MemoryVT - VT of in-memory value.
+ EVT MemoryVT;
+
+protected:
+ /// MMO - Memory reference information.
+ MachineMemOperand *MMO;
+
+public:
+ MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, EVT MemoryVT,
+ MachineMemOperand *MMO);
+
+ MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, const SDValue *Ops,
+ unsigned NumOps, EVT MemoryVT, MachineMemOperand *MMO);
+
+ bool readMem() const { return MMO->isLoad(); }
+ bool writeMem() const { return MMO->isStore(); }
+
+ /// Returns alignment and volatility of the memory access
+ unsigned getOriginalAlignment() const {
+ return MMO->getBaseAlignment();
+ }
+ unsigned getAlignment() const {
+ return MMO->getAlignment();
+ }
+
+ /// getRawSubclassData - Return the SubclassData value, which contains an
+ /// encoding of the volatile flag, as well as bits used by subclasses. This
+ /// function should only be used to compute a FoldingSetNodeID value.
+ unsigned getRawSubclassData() const {
+ return SubclassData;
+ }
+
+ // We access subclass data here so that we can check consistency
+ // with MachineMemOperand information.
+ bool isVolatile() const { return (SubclassData >> 5) & 1; }
+ bool isNonTemporal() const { return (SubclassData >> 6) & 1; }
+ bool isInvariant() const { return (SubclassData >> 7) & 1; }
+
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering((SubclassData >> 8) & 15);
+ }
+ SynchronizationScope getSynchScope() const {
+ return SynchronizationScope((SubclassData >> 12) & 1);
+ }
+
+ /// Returns the SrcValue and offset that describes the location of the access
+ const Value *getSrcValue() const { return MMO->getValue(); }
+ int64_t getSrcValueOffset() const { return MMO->getOffset(); }
+
+ /// Returns the TBAAInfo that describes the dereference.
+ const MDNode *getTBAAInfo() const { return MMO->getTBAAInfo(); }
+
+ /// Returns the Ranges that describes the dereference.
+ const MDNode *getRanges() const { return MMO->getRanges(); }
+
+ /// getMemoryVT - Return the type of the in-memory value.
+ EVT getMemoryVT() const { return MemoryVT; }
+
+ /// getMemOperand - Return a MachineMemOperand object describing the memory
+ /// reference performed by operation.
+ MachineMemOperand *getMemOperand() const { return MMO; }
+
+ const MachinePointerInfo &getPointerInfo() const {
+ return MMO->getPointerInfo();
+ }
+
+ /// 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
+ /// this MachineMemOperand.
+ void refineAlignment(const MachineMemOperand *NewMMO) {
+ MMO->refineAlignment(NewMMO);
+ }
+
+ const SDValue &getChain() const { return getOperand(0); }
+ const SDValue &getBasePtr() const {
+ return getOperand(getOpcode() == ISD::STORE ? 2 : 1);
+ }
+
+ // 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.
+ return N->getOpcode() == ISD::LOAD ||
+ N->getOpcode() == ISD::STORE ||
+ N->getOpcode() == ISD::PREFETCH ||
+ N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
+ N->getOpcode() == ISD::ATOMIC_SWAP ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
+ N->getOpcode() == ISD::ATOMIC_LOAD ||
+ N->getOpcode() == ISD::ATOMIC_STORE ||
+ N->isTargetMemoryOpcode();
+ }
+};
+
+/// AtomicSDNode - A SDNode reprenting atomic operations.
+///
+class AtomicSDNode : public MemSDNode {
+ SDUse Ops[4];
+
+ void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) {
+ // This must match encodeMemSDNodeFlags() in SelectionDAG.cpp.
+ assert((Ordering & 15) == Ordering &&
+ "Ordering may not require more than 4 bits!");
+ assert((SynchScope & 1) == SynchScope &&
+ "SynchScope may not require more than 1 bit!");
+ SubclassData |= Ordering << 8;
+ SubclassData |= SynchScope << 12;
+ assert(getOrdering() == Ordering && "Ordering encoding error!");
+ assert(getSynchScope() == SynchScope && "Synch-scope encoding error!");
+
+ assert((readMem() || getOrdering() <= Monotonic) &&
+ "Acquire/Release MachineMemOperand must be a load!");
+ assert((writeMem() || getOrdering() <= Monotonic) &&
+ "Acquire/Release MachineMemOperand must be a store!");
+ }
+
+public:
+ // Opc: opcode for atomic
+ // VTL: value type list
+ // Chain: memory chain for operaand
+ // Ptr: address to update as a SDValue
+ // Cmp: compare value
+ // Swp: swap value
+ // SrcVal: address to update as a Value (used for MemOperand)
+ // Align: alignment of memory
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT,
+ SDValue Chain, SDValue Ptr,
+ SDValue Cmp, SDValue Swp, MachineMemOperand *MMO,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope)
+ : MemSDNode(Opc, dl, VTL, MemVT, MMO) {
+ InitAtomic(Ordering, SynchScope);
+ InitOperands(Ops, Chain, Ptr, Cmp, Swp);
+ }
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT,
+ SDValue Chain, SDValue Ptr,
+ SDValue Val, MachineMemOperand *MMO,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope)
+ : MemSDNode(Opc, dl, VTL, MemVT, MMO) {
+ InitAtomic(Ordering, SynchScope);
+ InitOperands(Ops, Chain, Ptr, Val);
+ }
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT,
+ SDValue Chain, SDValue Ptr,
+ MachineMemOperand *MMO,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope)
+ : MemSDNode(Opc, dl, VTL, MemVT, MMO) {
+ InitAtomic(Ordering, SynchScope);
+ InitOperands(Ops, Chain, Ptr);
+ }
+
+ const SDValue &getBasePtr() const { return getOperand(1); }
+ const SDValue &getVal() const { return getOperand(2); }
+
+ bool isCompareAndSwap() const {
+ unsigned Op = getOpcode();
+ return Op == ISD::ATOMIC_CMP_SWAP;
+ }
+
+ // 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 ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
+ N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
+ N->getOpcode() == ISD::ATOMIC_LOAD ||
+ N->getOpcode() == ISD::ATOMIC_STORE;
+ }
+};
+
+/// MemIntrinsicSDNode - This SDNode is used for target intrinsics that touch
+/// memory and need an associated MachineMemOperand. Its opcode may be
+/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
+/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
+class MemIntrinsicSDNode : public MemSDNode {
+public:
+ MemIntrinsicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
+ const SDValue *Ops, unsigned NumOps,
+ EVT MemoryVT, MachineMemOperand *MMO)
+ : MemSDNode(Opc, dl, VTs, Ops, NumOps, MemoryVT, MMO) {
+ }
+
+ // 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
+ return N->getOpcode() == ISD::INTRINSIC_W_CHAIN ||
+ N->getOpcode() == ISD::INTRINSIC_VOID ||
+ N->getOpcode() == ISD::PREFETCH ||
+ N->isTargetMemoryOpcode();
+ }
+};
+
+/// ShuffleVectorSDNode - This SDNode is used to implement the code generator
+/// support for the llvm IR shufflevector instruction. It combines elements
+/// from two input vectors into a new input vector, with the selection and
+/// ordering of elements determined by an array of integers, referred to as
+/// the shuffle mask. For input vectors of width N, mask indices of 0..N-1
+/// refer to elements from the LHS input, and indices from N to 2N-1 the RHS.
+/// An index of -1 is treated as undef, such that the code generator may put
+/// any value in the corresponding element of the result.
+class ShuffleVectorSDNode : public SDNode {
+ SDUse Ops[2];
+
+ // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and
+ // is freed when the SelectionDAG object is destroyed.
+ const int *Mask;
+protected:
+ friend class SelectionDAG;
+ ShuffleVectorSDNode(EVT VT, DebugLoc dl, SDValue N1, SDValue N2,
+ const int *M)
+ : SDNode(ISD::VECTOR_SHUFFLE, dl, getSDVTList(VT)), Mask(M) {
+ InitOperands(Ops, N1, N2);
+ }
+public:
+
+ ArrayRef<int> getMask() const {
+ EVT VT = getValueType(0);
+ return makeArrayRef(Mask, VT.getVectorNumElements());
+ }
+ int getMaskElt(unsigned Idx) const {
+ assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
+ return Mask[Idx];
+ }
+
+ bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
+ int getSplatIndex() const {
+ assert(isSplat() && "Cannot get splat index for non-splat!");
+ EVT VT = getValueType(0);
+ for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+ if (Mask[i] != -1)
+ return Mask[i];
+ }
+ return -1;
+ }
+ static bool isSplatMask(const int *Mask, EVT VT);
+
+ static bool classof(const ShuffleVectorSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::VECTOR_SHUFFLE;
+ }
+};
+
+class ConstantSDNode : public SDNode {
+ const ConstantInt *Value;
+ friend class SelectionDAG;
+ ConstantSDNode(bool isTarget, const ConstantInt *val, EVT VT)
+ : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant,
+ DebugLoc(), getSDVTList(VT)), Value(val) {
+ }
+public:
+
+ const ConstantInt *getConstantIntValue() const { return Value; }
+ const APInt &getAPIntValue() const { return Value->getValue(); }
+ uint64_t getZExtValue() const { return Value->getZExtValue(); }
+ int64_t getSExtValue() const { return Value->getSExtValue(); }
+
+ bool isOne() const { return Value->isOne(); }
+ 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;
+ }
+};
+
+class ConstantFPSDNode : public SDNode {
+ const ConstantFP *Value;
+ friend class SelectionDAG;
+ ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT)
+ : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
+ DebugLoc(), getSDVTList(VT)), Value(val) {
+ }
+public:
+
+ const APFloat& getValueAPF() const { return Value->getValueAPF(); }
+ const ConstantFP *getConstantFPValue() const { return Value; }
+
+ /// isZero - Return true if the value is positive or negative zero.
+ bool isZero() const { return Value->isZero(); }
+
+ /// isNaN - Return true if the value is a NaN.
+ bool isNaN() const { return Value->isNaN(); }
+
+ /// isExactlyValue - We don't rely on operator== working on double values, as
+ /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
+ /// As such, this method can be used to do an exact bit-for-bit comparison of
+ /// two floating point values.
+
+ /// We leave the version with the double argument here because it's just so
+ /// convenient to write "2.0" and the like. Without this function we'd
+ /// 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);
+ return isExactlyValue(Tmp);
+ }
+ bool isExactlyValue(const APFloat& V) const;
+
+ 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;
+ }
+};
+
+class GlobalAddressSDNode : public SDNode {
+ const GlobalValue *TheGlobal;
+ int64_t Offset;
+ unsigned char TargetFlags;
+ friend class SelectionDAG;
+ GlobalAddressSDNode(unsigned Opc, DebugLoc DL, const GlobalValue *GA, EVT VT,
+ int64_t o, unsigned char TargetFlags);
+public:
+
+ const GlobalValue *getGlobal() const { return TheGlobal; }
+ int64_t getOffset() const { return Offset; }
+ unsigned char getTargetFlags() const { return TargetFlags; }
+ // 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 ||
+ N->getOpcode() == ISD::GlobalTLSAddress ||
+ N->getOpcode() == ISD::TargetGlobalTLSAddress;
+ }
+};
+
+class FrameIndexSDNode : public SDNode {
+ int FI;
+ friend class SelectionDAG;
+ FrameIndexSDNode(int fi, EVT VT, bool isTarg)
+ : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
+ DebugLoc(), getSDVTList(VT)), FI(fi) {
+ }
+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;
+ }
+};
+
+class JumpTableSDNode : public SDNode {
+ int JTI;
+ unsigned char TargetFlags;
+ friend class SelectionDAG;
+ JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned char TF)
+ : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
+ DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
+ }
+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;
+ }
+};
+
+class ConstantPoolSDNode : public SDNode {
+ union {
+ const Constant *ConstVal;
+ MachineConstantPoolValue *MachineCPVal;
+ } Val;
+ int Offset; // It's a MachineConstantPoolValue if top bit is set.
+ unsigned Alignment; // Minimum alignment requirement of CP (not log2 value).
+ unsigned char TargetFlags;
+ friend class SelectionDAG;
+ ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o,
+ unsigned Align, unsigned char TF)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ DebugLoc(),
+ getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = c;
+ }
+ ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
+ EVT VT, int o, unsigned Align, unsigned char TF)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ DebugLoc(),
+ getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = v;
+ Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
+ }
+public:
+
+
+ bool isMachineConstantPoolEntry() const {
+ return (int)Offset < 0;
+ }
+
+ const Constant *getConstVal() const {
+ assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
+ return Val.ConstVal;
+ }
+
+ MachineConstantPoolValue *getMachineCPVal() const {
+ assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
+ return Val.MachineCPVal;
+ }
+
+ int getOffset() const {
+ return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
+ }
+
+ // Return the alignment of this constant pool object, which is either 0 (for
+ // default alignment) or the desired value.
+ unsigned getAlignment() const { return Alignment; }
+ unsigned char getTargetFlags() const { return TargetFlags; }
+
+ 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;
+ }
+};
+
+class BasicBlockSDNode : public SDNode {
+ MachineBasicBlock *MBB;
+ friend class SelectionDAG;
+ /// Debug info is meaningful and potentially useful here, but we create
+ /// blocks out of order when they're jumped to, which makes it a bit
+ /// harder. Let's see if we need it first.
+ explicit BasicBlockSDNode(MachineBasicBlock *mbb)
+ : SDNode(ISD::BasicBlock, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb) {
+ }
+public:
+
+ MachineBasicBlock *getBasicBlock() const { return MBB; }
+
+ static bool classof(const BasicBlockSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::BasicBlock;
+ }
+};
+
+/// BuildVectorSDNode - A "pseudo-class" with methods for operating on
+/// BUILD_VECTORs.
+class BuildVectorSDNode : public SDNode {
+ // These are constructed as SDNodes and then cast to BuildVectorSDNodes.
+ explicit BuildVectorSDNode(); // Do not implement
+public:
+ /// isConstantSplat - Check if this is a constant splat, and if so, find the
+ /// smallest element size that splats the vector. If MinSplatBits is
+ /// nonzero, the element size must be at least that large. Note that the
+ /// splat element may be the entire vector (i.e., a one element vector).
+ /// Returns the splat element value in SplatValue. Any undefined bits in
+ /// that value are zero, and the corresponding bits in the SplatUndef mask
+ /// are set. The SplatBitSize value is set to the splat element size in
+ /// bits. HasAnyUndefs is set to true if any bits in the vector are
+ /// undefined. isBigEndian describes the endianness of the target.
+ bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
+ 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;
+ }
+};
+
+/// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR Value. This is
+/// used when the SelectionDAG needs to make a simple reference to something
+/// in the LLVM IR representation.
+///
+class SrcValueSDNode : public SDNode {
+ const Value *V;
+ friend class SelectionDAG;
+ /// Create a SrcValue for a general value.
+ explicit SrcValueSDNode(const Value *v)
+ : SDNode(ISD::SRCVALUE, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
+
+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;
+ }
+};
+
+class MDNodeSDNode : public SDNode {
+ const MDNode *MD;
+ friend class SelectionDAG;
+ explicit MDNodeSDNode(const MDNode *md)
+ : SDNode(ISD::MDNODE_SDNODE, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {}
+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;
+ }
+};
+
+
+class RegisterSDNode : public SDNode {
+ unsigned Reg;
+ friend class SelectionDAG;
+ RegisterSDNode(unsigned reg, EVT VT)
+ : SDNode(ISD::Register, DebugLoc(), getSDVTList(VT)), Reg(reg) {
+ }
+public:
+
+ unsigned getReg() const { return Reg; }
+
+ static bool classof(const RegisterSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::Register;
+ }
+};
+
+class RegisterMaskSDNode : public SDNode {
+ // The memory for RegMask is not owned by the node.
+ const uint32_t *RegMask;
+ friend class SelectionDAG;
+ RegisterMaskSDNode(const uint32_t *mask)
+ : SDNode(ISD::RegisterMask, DebugLoc(), getSDVTList(MVT::Untyped)),
+ RegMask(mask) {}
+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;
+ }
+};
+
+class BlockAddressSDNode : public SDNode {
+ const BlockAddress *BA;
+ unsigned char TargetFlags;
+ friend class SelectionDAG;
+ BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
+ unsigned char Flags)
+ : SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
+ BA(ba), TargetFlags(Flags) {
+ }
+public:
+ const BlockAddress *getBlockAddress() const { return BA; }
+ 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;
+ }
+};
+
+class EHLabelSDNode : public SDNode {
+ SDUse Chain;
+ MCSymbol *Label;
+ friend class SelectionDAG;
+ EHLabelSDNode(DebugLoc dl, SDValue ch, MCSymbol *L)
+ : SDNode(ISD::EH_LABEL, dl, getSDVTList(MVT::Other)), Label(L) {
+ InitOperands(&Chain, ch);
+ }
+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;
+ }
+};
+
+class ExternalSymbolSDNode : public SDNode {
+ const char *Symbol;
+ unsigned char TargetFlags;
+
+ friend class SelectionDAG;
+ ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, EVT VT)
+ : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
+ DebugLoc(), getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
+ }
+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;
+ }
+};
+
+class CondCodeSDNode : public SDNode {
+ ISD::CondCode Condition;
+ friend class SelectionDAG;
+ explicit CondCodeSDNode(ISD::CondCode Cond)
+ : SDNode(ISD::CONDCODE, DebugLoc(), getSDVTList(MVT::Other)),
+ Condition(Cond) {
+ }
+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;
+ }
+};
+
+/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the
+/// future and most targets don't support it.
+class CvtRndSatSDNode : public SDNode {
+ ISD::CvtCode CvtCode;
+ friend class SelectionDAG;
+ explicit CvtRndSatSDNode(EVT VT, DebugLoc dl, const SDValue *Ops,
+ unsigned NumOps, ISD::CvtCode Code)
+ : SDNode(ISD::CONVERT_RNDSAT, dl, getSDVTList(VT), Ops, NumOps),
+ CvtCode(Code) {
+ assert(NumOps == 5 && "wrong number of operations");
+ }
+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;
+ }
+};
+
+/// VTSDNode - This class is used to represent EVT's, which are used
+/// to parameterize some operations.
+class VTSDNode : public SDNode {
+ EVT ValueType;
+ friend class SelectionDAG;
+ explicit VTSDNode(EVT VT)
+ : SDNode(ISD::VALUETYPE, DebugLoc(), getSDVTList(MVT::Other)),
+ ValueType(VT) {
+ }
+public:
+
+ EVT getVT() const { return ValueType; }
+
+ static bool classof(const VTSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::VALUETYPE;
+ }
+};
+
+/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode
+///
+class LSBaseSDNode : public MemSDNode {
+ //! Operand array for load and store
+ /*!
+ \note Moving this array to the base class captures more
+ common functionality shared between LoadSDNode and
+ StoreSDNode
+ */
+ SDUse Ops[4];
+public:
+ LSBaseSDNode(ISD::NodeType NodeTy, DebugLoc dl, SDValue *Operands,
+ unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM,
+ EVT MemVT, MachineMemOperand *MMO)
+ : MemSDNode(NodeTy, dl, VTs, MemVT, MMO) {
+ SubclassData |= AM << 2;
+ assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+ InitOperands(Ops, Operands, numOperands);
+ assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
+ "Only indexed loads and stores have a non-undef offset operand");
+ }
+
+ const SDValue &getOffset() const {
+ return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
+ }
+
+ /// getAddressingMode - Return the addressing mode for this load or store:
+ /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
+ ISD::MemIndexedMode getAddressingMode() const {
+ return ISD::MemIndexedMode((SubclassData >> 2) & 7);
+ }
+
+ /// isIndexed - Return true if this is a pre/post inc/dec load/store.
+ bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
+
+ /// 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;
+ }
+};
+
+/// LoadSDNode - This class is used to represent ISD::LOAD nodes.
+///
+class LoadSDNode : public LSBaseSDNode {
+ friend class SelectionDAG;
+ LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs,
+ ISD::MemIndexedMode AM, ISD::LoadExtType ETy, EVT MemVT,
+ MachineMemOperand *MMO)
+ : LSBaseSDNode(ISD::LOAD, dl, ChainPtrOff, 3,
+ VTs, AM, MemVT, MMO) {
+ SubclassData |= (unsigned short)ETy;
+ assert(getExtensionType() == ETy && "LoadExtType encoding error!");
+ assert(readMem() && "Load MachineMemOperand is not a load!");
+ assert(!writeMem() && "Load MachineMemOperand is a store!");
+ }
+public:
+
+ /// getExtensionType - Return whether this is a plain node,
+ /// or one of the varieties of value-extending loads.
+ ISD::LoadExtType getExtensionType() const {
+ return ISD::LoadExtType(SubclassData & 3);
+ }
+
+ 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;
+ }
+};
+
+/// StoreSDNode - This class is used to represent ISD::STORE nodes.
+///
+class StoreSDNode : public LSBaseSDNode {
+ friend class SelectionDAG;
+ StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs,
+ ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
+ MachineMemOperand *MMO)
+ : LSBaseSDNode(ISD::STORE, dl, ChainValuePtrOff, 4,
+ VTs, AM, MemVT, MMO) {
+ SubclassData |= (unsigned short)isTrunc;
+ assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
+ assert(!readMem() && "Store MachineMemOperand is a load!");
+ assert(writeMem() && "Store MachineMemOperand is not a store!");
+ }
+public:
+
+ /// isTruncatingStore - Return true if the op does a truncation before store.
+ /// For integers this is the same as doing a TRUNCATE and storing the result.
+ /// For floats, it is the same as doing an FP_ROUND and storing the result.
+ bool isTruncatingStore() const { return SubclassData & 1; }
+
+ const SDValue &getValue() const { return getOperand(1); }
+ 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;
+ }
+};
+
+/// MachineSDNode - An SDNode that represents everything that will be needed
+/// to construct a MachineInstr. These nodes are created during the
+/// instruction selection proper phase.
+///
+class MachineSDNode : public SDNode {
+public:
+ typedef MachineMemOperand **mmo_iterator;
+
+private:
+ friend class SelectionDAG;
+ MachineSDNode(unsigned Opc, const DebugLoc DL, SDVTList VTs)
+ : SDNode(Opc, DL, VTs), MemRefs(0), MemRefsEnd(0) {}
+
+ /// LocalOperands - Operands for this instruction, if they fit here. If
+ /// they don't, this field is unused.
+ SDUse LocalOperands[4];
+
+ /// MemRefs - Memory reference descriptions for this instruction.
+ mmo_iterator MemRefs;
+ mmo_iterator MemRefsEnd;
+
+public:
+ mmo_iterator memoperands_begin() const { return MemRefs; }
+ mmo_iterator memoperands_end() const { return MemRefsEnd; }
+ bool memoperands_empty() const { return MemRefsEnd == MemRefs; }
+
+ /// setMemRefs - Assign this MachineSDNodes's memory reference descriptor
+ /// list. This does not transfer ownership.
+ void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) {
+ for (mmo_iterator MMI = NewMemRefs, MME = NewMemRefsEnd; MMI != MME; ++MMI)
+ assert(*MMI && "Null mem ref detected!");
+ MemRefs = NewMemRefs;
+ MemRefsEnd = NewMemRefsEnd;
+ }
+
+ static bool classof(const MachineSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->isMachineOpcode();
+ }
+};
+
+class SDNodeIterator : public std::iterator<std::forward_iterator_tag,
+ SDNode, ptrdiff_t> {
+ SDNode *Node;
+ unsigned Operand;
+
+ SDNodeIterator(SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
+public:
+ bool operator==(const SDNodeIterator& x) const {
+ return Operand == x.Operand;
+ }
+ bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
+
+ const SDNodeIterator &operator=(const SDNodeIterator &I) {
+ assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
+ Operand = I.Operand;
+ return *this;
+ }
+
+ pointer operator*() const {
+ return Node->getOperand(Operand).getNode();
+ }
+ pointer operator->() const { return operator*(); }
+
+ SDNodeIterator& operator++() { // Preincrement
+ ++Operand;
+ return *this;
+ }
+ SDNodeIterator operator++(int) { // Postincrement
+ SDNodeIterator tmp = *this; ++*this; return tmp;
+ }
+ size_t operator-(SDNodeIterator Other) const {
+ assert(Node == Other.Node &&
+ "Cannot compare iterators of two different nodes!");
+ return Operand - Other.Operand;
+ }
+
+ static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); }
+ static SDNodeIterator end (SDNode *N) {
+ return SDNodeIterator(N, N->getNumOperands());
+ }
+
+ unsigned getOperand() const { return Operand; }
+ const SDNode *getNode() const { return Node; }
+};
+
+template <> struct GraphTraits<SDNode*> {
+ typedef SDNode NodeType;
+ typedef SDNodeIterator ChildIteratorType;
+ static inline NodeType *getEntryNode(SDNode *N) { return N; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return SDNodeIterator::begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return SDNodeIterator::end(N);
+ }
+};
+
+/// LargestSDNode - The largest SDNode class.
+///
+typedef LoadSDNode LargestSDNode;
+
+/// MostAlignedSDNode - The SDNode class with the greatest alignment
+/// requirement.
+///
+typedef GlobalAddressSDNode MostAlignedSDNode;
+
+namespace ISD {
+ /// isNormalLoad - Returns true if the specified node is a non-extending
+ /// and unindexed load.
+ inline bool isNormalLoad(const SDNode *N) {
+ const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N);
+ return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
+ Ld->getAddressingMode() == ISD::UNINDEXED;
+ }
+
+ /// isNON_EXTLoad - Returns true if the specified node is a non-extending
+ /// load.
+ inline bool isNON_EXTLoad(const SDNode *N) {
+ return isa<LoadSDNode>(N) &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
+ }
+
+ /// isEXTLoad - Returns true if the specified node is a EXTLOAD.
+ ///
+ inline bool isEXTLoad(const SDNode *N) {
+ return isa<LoadSDNode>(N) &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+ }
+
+ /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
+ ///
+ inline bool isSEXTLoad(const SDNode *N) {
+ return isa<LoadSDNode>(N) &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+ }
+
+ /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
+ ///
+ inline bool isZEXTLoad(const SDNode *N) {
+ return isa<LoadSDNode>(N) &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+ }
+
+ /// isUNINDEXEDLoad - Returns true if the specified node is an unindexed load.
+ ///
+ inline bool isUNINDEXEDLoad(const SDNode *N) {
+ return isa<LoadSDNode>(N) &&
+ cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+ }
+
+ /// isNormalStore - Returns true if the specified node is a non-truncating
+ /// and unindexed store.
+ inline bool isNormalStore(const SDNode *N) {
+ const StoreSDNode *St = dyn_cast<StoreSDNode>(N);
+ return St && !St->isTruncatingStore() &&
+ St->getAddressingMode() == ISD::UNINDEXED;
+ }
+
+ /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating
+ /// store.
+ inline bool isNON_TRUNCStore(const SDNode *N) {
+ return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore();
+ }
+
+ /// isTRUNCStore - Returns true if the specified node is a truncating
+ /// store.
+ inline bool isTRUNCStore(const SDNode *N) {
+ return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore();
+ }
+
+ /// isUNINDEXEDStore - Returns true if the specified node is an
+ /// unindexed store.
+ inline bool isUNINDEXEDStore(const SDNode *N) {
+ return isa<StoreSDNode>(N) &&
+ cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+ }
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h
new file mode 100644
index 000000000000..0457e43e6b7b
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/SlotIndexes.h
@@ -0,0 +1,694 @@
+//===- llvm/CodeGen/SlotIndexes.h - Slot indexes representation -*- 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 SlotIndex and related classes. The purpose of SlotIndex
+// is to describe a position at which a register can become live, or cease to
+// be live.
+//
+// SlotIndex is mostly a proxy for entries of the SlotIndexList, a class which
+// is held is LiveIntervals and provides the real numbering. This allows
+// LiveIntervals to perform largely transparent renumbering.
+//===----------------------------------------------------------------------===//
+
+#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/PointerIntPair.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+
+namespace llvm {
+
+ /// This class represents an entry in the slot index list held in the
+ /// SlotIndexes pass. It should not be used directly. See the
+ /// SlotIndex & SlotIndexes classes for the public interface to this
+ /// information.
+ class IndexListEntry : public ilist_node<IndexListEntry> {
+ MachineInstr *mi;
+ unsigned index;
+
+ public:
+
+ IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
+
+ MachineInstr* getInstr() const { return mi; }
+ void setInstr(MachineInstr *mi) {
+ this->mi = mi;
+ }
+
+ unsigned getIndex() const { return index; }
+ void setIndex(unsigned index) {
+ this->index = index;
+ }
+
+ };
+
+ template <>
+ struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexListEntry> {
+ private:
+ mutable ilist_half_node<IndexListEntry> Sentinel;
+ public:
+ IndexListEntry *createSentinel() const {
+ return static_cast<IndexListEntry*>(&Sentinel);
+ }
+ void destroySentinel(IndexListEntry *) const {}
+
+ IndexListEntry *provideInitialHead() const { return createSentinel(); }
+ IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); }
+ static void noteHead(IndexListEntry*, IndexListEntry*) {}
+ void deleteNode(IndexListEntry *N) {}
+
+ private:
+ void createNode(const IndexListEntry &);
+ };
+
+ /// SlotIndex - An opaque wrapper around machine indexes.
+ class SlotIndex {
+ friend class SlotIndexes;
+ friend struct DenseMapInfo<SlotIndex>;
+
+ enum Slot {
+ /// Basic block boundary. Used for live ranges entering and leaving a
+ /// block without being live in the layout neighbor. Also used as the
+ /// def slot of PHI-defs.
+ Slot_Block,
+
+ /// Early-clobber register use/def slot. A live range defined at
+ /// Slot_EarlyCLobber interferes with normal live ranges killed at
+ /// Slot_Register. Also used as the kill slot for live ranges tied to an
+ /// early-clobber def.
+ Slot_EarlyClobber,
+
+ /// Normal register use/def slot. Normal instructions kill and define
+ /// register live ranges at this slot.
+ Slot_Register,
+
+ /// Dead def kill point. Kill slot for a live range that is defined by
+ /// the same instruction (Slot_Register or Slot_EarlyClobber), but isn't
+ /// used anywhere.
+ Slot_Dead,
+
+ Slot_Count
+ };
+
+ PointerIntPair<IndexListEntry*, 2, unsigned> lie;
+
+ SlotIndex(IndexListEntry *entry, unsigned slot)
+ : lie(entry, slot) {}
+
+ IndexListEntry* listEntry() const {
+ assert(isValid() && "Attempt to compare reserved index.");
+ return lie.getPointer();
+ }
+
+ int getIndex() const {
+ return listEntry()->getIndex() | getSlot();
+ }
+
+ /// Returns the slot for this SlotIndex.
+ Slot getSlot() const {
+ return static_cast<Slot>(lie.getInt());
+ }
+
+ static inline unsigned getHashValue(const SlotIndex &v) {
+ void *ptrVal = v.lie.getOpaqueValue();
+ return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9);
+ }
+
+ public:
+ enum {
+ /// The default distance between instructions as returned by distance().
+ /// This may vary as instructions are inserted and removed.
+ InstrDist = 4 * Slot_Count
+ };
+
+ static inline SlotIndex getEmptyKey() {
+ return SlotIndex(0, 1);
+ }
+
+ static inline SlotIndex getTombstoneKey() {
+ return SlotIndex(0, 2);
+ }
+
+ /// Construct an invalid index.
+ SlotIndex() : lie(0, 0) {}
+
+ // Construct a new slot index from the given one, and set the slot.
+ SlotIndex(const SlotIndex &li, Slot s) : lie(li.listEntry(), unsigned(s)) {
+ assert(lie.getPointer() != 0 &&
+ "Attempt to construct index with 0 pointer.");
+ }
+
+ /// Returns true if this is a valid index. Invalid indicies do
+ /// not point into an index table, and cannot be compared.
+ bool isValid() const {
+ return lie.getPointer();
+ }
+
+ /// Return true for a valid index.
+ operator bool() const { return isValid(); }
+
+ /// Print this index to the given raw_ostream.
+ void print(raw_ostream &os) const;
+
+ /// Dump this index to stderr.
+ void dump() const;
+
+ /// Compare two SlotIndex objects for equality.
+ bool operator==(SlotIndex other) const {
+ return lie == other.lie;
+ }
+ /// Compare two SlotIndex objects for inequality.
+ bool operator!=(SlotIndex other) const {
+ return lie != other.lie;
+ }
+
+ /// Compare two SlotIndex objects. Return true if the first index
+ /// is strictly lower than the second.
+ bool operator<(SlotIndex other) const {
+ return getIndex() < other.getIndex();
+ }
+ /// Compare two SlotIndex objects. Return true if the first index
+ /// is lower than, or equal to, the second.
+ bool operator<=(SlotIndex other) const {
+ return getIndex() <= other.getIndex();
+ }
+
+ /// Compare two SlotIndex objects. Return true if the first index
+ /// is greater than the second.
+ bool operator>(SlotIndex other) const {
+ return getIndex() > other.getIndex();
+ }
+
+ /// Compare two SlotIndex objects. Return true if the first index
+ /// is greater than, or equal to, the second.
+ bool operator>=(SlotIndex other) const {
+ return getIndex() >= other.getIndex();
+ }
+
+ /// isSameInstr - Return true if A and B refer to the same instruction.
+ static bool isSameInstr(SlotIndex A, SlotIndex B) {
+ return A.lie.getPointer() == B.lie.getPointer();
+ }
+
+ /// isEarlierInstr - Return true if A refers to an instruction earlier than
+ /// B. This is equivalent to A < B && !isSameInstr(A, B).
+ static bool isEarlierInstr(SlotIndex A, SlotIndex B) {
+ return A.listEntry()->getIndex() < B.listEntry()->getIndex();
+ }
+
+ /// Return the distance from this index to the given one.
+ int distance(SlotIndex other) const {
+ return other.getIndex() - getIndex();
+ }
+
+ /// isBlock - Returns true if this is a block boundary slot.
+ bool isBlock() const { return getSlot() == Slot_Block; }
+
+ /// isEarlyClobber - Returns true if this is an early-clobber slot.
+ bool isEarlyClobber() const { return getSlot() == Slot_EarlyClobber; }
+
+ /// isRegister - Returns true if this is a normal register use/def slot.
+ /// Note that early-clobber slots may also be used for uses and defs.
+ bool isRegister() const { return getSlot() == Slot_Register; }
+
+ /// isDead - Returns true if this is a dead def kill slot.
+ bool isDead() const { return getSlot() == Slot_Dead; }
+
+ /// Returns the base index for associated with this index. The base index
+ /// is the one associated with the Slot_Block slot for the instruction
+ /// pointed to by this index.
+ SlotIndex getBaseIndex() const {
+ return SlotIndex(listEntry(), Slot_Block);
+ }
+
+ /// Returns the boundary index for associated with this index. The boundary
+ /// index is the one associated with the Slot_Block slot for the instruction
+ /// pointed to by this index.
+ SlotIndex getBoundaryIndex() const {
+ return SlotIndex(listEntry(), Slot_Dead);
+ }
+
+ /// Returns the register use/def slot in the current instruction for a
+ /// normal or early-clobber def.
+ SlotIndex getRegSlot(bool EC = false) const {
+ return SlotIndex(listEntry(), EC ? Slot_EarlyClobber : Slot_Register);
+ }
+
+ /// Returns the dead def kill slot for the current instruction.
+ SlotIndex getDeadSlot() const {
+ return SlotIndex(listEntry(), Slot_Dead);
+ }
+
+ /// Returns the next slot in the index list. This could be either the
+ /// next slot for the instruction pointed to by this index or, if this
+ /// index is a STORE, the first slot for the next instruction.
+ /// WARNING: This method is considerably more expensive than the methods
+ /// that return specific slots (getUseIndex(), etc). If you can - please
+ /// use one of those methods.
+ SlotIndex getNextSlot() const {
+ Slot s = getSlot();
+ if (s == Slot_Dead) {
+ return SlotIndex(listEntry()->getNextNode(), Slot_Block);
+ }
+ return SlotIndex(listEntry(), s + 1);
+ }
+
+ /// Returns the next index. This is the index corresponding to the this
+ /// index's slot, but for the next instruction.
+ SlotIndex getNextIndex() const {
+ return SlotIndex(listEntry()->getNextNode(), getSlot());
+ }
+
+ /// Returns the previous slot in the index list. This could be either the
+ /// previous slot for the instruction pointed to by this index or, if this
+ /// index is a Slot_Block, the last slot for the previous instruction.
+ /// WARNING: This method is considerably more expensive than the methods
+ /// that return specific slots (getUseIndex(), etc). If you can - please
+ /// use one of those methods.
+ SlotIndex getPrevSlot() const {
+ Slot s = getSlot();
+ if (s == Slot_Block) {
+ return SlotIndex(listEntry()->getPrevNode(), Slot_Dead);
+ }
+ return SlotIndex(listEntry(), s - 1);
+ }
+
+ /// Returns the previous index. This is the index corresponding to this
+ /// index's slot, but for the previous instruction.
+ SlotIndex getPrevIndex() const {
+ return SlotIndex(listEntry()->getPrevNode(), getSlot());
+ }
+
+ };
+
+ /// DenseMapInfo specialization for SlotIndex.
+ template <>
+ struct DenseMapInfo<SlotIndex> {
+ static inline SlotIndex getEmptyKey() {
+ return SlotIndex::getEmptyKey();
+ }
+ static inline SlotIndex getTombstoneKey() {
+ return SlotIndex::getTombstoneKey();
+ }
+ static inline unsigned getHashValue(const SlotIndex &v) {
+ return SlotIndex::getHashValue(v);
+ }
+ static inline bool isEqual(const SlotIndex &LHS, const SlotIndex &RHS) {
+ return (LHS == RHS);
+ }
+ };
+
+ template <> struct isPodLike<SlotIndex> { static const bool value = true; };
+
+
+ inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
+ li.print(os);
+ return os;
+ }
+
+ typedef std::pair<SlotIndex, MachineBasicBlock*> IdxMBBPair;
+
+ inline bool operator<(SlotIndex V, const IdxMBBPair &IM) {
+ return V < IM.first;
+ }
+
+ inline bool operator<(const IdxMBBPair &IM, SlotIndex V) {
+ return IM.first < V;
+ }
+
+ struct Idx2MBBCompare {
+ bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
+ return LHS.first < RHS.first;
+ }
+ };
+
+ /// SlotIndexes pass.
+ ///
+ /// This pass assigns indexes to each instruction.
+ class SlotIndexes : public MachineFunctionPass {
+ private:
+
+ typedef ilist<IndexListEntry> IndexList;
+ IndexList indexList;
+
+ MachineFunction *mf;
+ unsigned functionSize;
+
+ typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap;
+ Mi2IndexMap mi2iMap;
+
+ /// MBBRanges - Map MBB number to (start, stop) indexes.
+ SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges;
+
+ /// Idx2MBBMap - Sorted list of pairs of index of first instruction
+ /// and MBB id.
+ SmallVector<IdxMBBPair, 8> idx2MBBMap;
+
+ // IndexListEntry allocator.
+ BumpPtrAllocator ileAllocator;
+
+ IndexListEntry* createEntry(MachineInstr *mi, unsigned index) {
+ IndexListEntry *entry =
+ static_cast<IndexListEntry*>(
+ ileAllocator.Allocate(sizeof(IndexListEntry),
+ alignOf<IndexListEntry>()));
+
+ new (entry) IndexListEntry(mi, index);
+
+ return entry;
+ }
+
+ /// Renumber locally after inserting curItr.
+ void renumberIndexes(IndexList::iterator curItr);
+
+ public:
+ static char ID;
+
+ SlotIndexes() : MachineFunctionPass(ID) {
+ initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &au) const;
+ virtual void releaseMemory();
+
+ virtual bool runOnMachineFunction(MachineFunction &fn);
+
+ /// Dump the indexes.
+ void dump() const;
+
+ /// Renumber the index list, providing space for new instructions.
+ void renumberIndexes();
+
+ /// Returns the zero index for this analysis.
+ SlotIndex getZeroIndex() {
+ assert(indexList.front().getIndex() == 0 && "First index is not 0?");
+ return SlotIndex(&indexList.front(), 0);
+ }
+
+ /// Returns the base index of the last slot in this analysis.
+ SlotIndex getLastIndex() {
+ return SlotIndex(&indexList.back(), 0);
+ }
+
+ /// Returns the distance between the highest and lowest indexes allocated
+ /// so far.
+ unsigned getIndexesLength() const {
+ assert(indexList.front().getIndex() == 0 &&
+ "Initial index isn't zero?");
+ return indexList.back().getIndex();
+ }
+
+ /// Returns the number of instructions in the function.
+ unsigned getFunctionSize() const {
+ return functionSize;
+ }
+
+ /// Returns true if the given machine instr is mapped to an index,
+ /// otherwise returns false.
+ bool hasIndex(const MachineInstr *instr) const {
+ return mi2iMap.count(instr);
+ }
+
+ /// Returns the base index for the given instruction.
+ SlotIndex getInstructionIndex(const MachineInstr *MI) const {
+ // Instructions inside a bundle have the same number as the bundle itself.
+ Mi2IndexMap::const_iterator itr = mi2iMap.find(getBundleStart(MI));
+ assert(itr != mi2iMap.end() && "Instruction not found in maps.");
+ return itr->second;
+ }
+
+ /// Returns the instruction for the given index, or null if the given
+ /// index has no instruction associated with it.
+ MachineInstr* getInstructionFromIndex(SlotIndex index) const {
+ return index.isValid() ? index.listEntry()->getInstr() : 0;
+ }
+
+ /// Returns the next non-null index.
+ SlotIndex getNextNonNullIndex(SlotIndex index) {
+ IndexList::iterator itr(index.listEntry());
+ ++itr;
+ while (itr != indexList.end() && itr->getInstr() == 0) { ++itr; }
+ return SlotIndex(itr, index.getSlot());
+ }
+
+ /// getIndexBefore - Returns the index of the last indexed instruction
+ /// before MI, or the the start index of its basic block.
+ /// MI is not required to have an index.
+ SlotIndex getIndexBefore(const MachineInstr *MI) const {
+ const MachineBasicBlock *MBB = MI->getParent();
+ assert(MBB && "MI must be inserted inna basic block");
+ MachineBasicBlock::const_iterator I = MI, B = MBB->begin();
+ for (;;) {
+ if (I == B)
+ return getMBBStartIdx(MBB);
+ --I;
+ Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I);
+ if (MapItr != mi2iMap.end())
+ return MapItr->second;
+ }
+ }
+
+ /// getIndexAfter - Returns the index of the first indexed instruction
+ /// after MI, or the end index of its basic block.
+ /// MI is not required to have an index.
+ SlotIndex getIndexAfter(const MachineInstr *MI) const {
+ const MachineBasicBlock *MBB = MI->getParent();
+ assert(MBB && "MI must be inserted inna basic block");
+ MachineBasicBlock::const_iterator I = MI, E = MBB->end();
+ for (;;) {
+ ++I;
+ if (I == E)
+ return getMBBEndIdx(MBB);
+ Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I);
+ if (MapItr != mi2iMap.end())
+ return MapItr->second;
+ }
+ }
+
+ /// Return the (start,end) range of the given basic block number.
+ const std::pair<SlotIndex, SlotIndex> &
+ getMBBRange(unsigned Num) const {
+ return MBBRanges[Num];
+ }
+
+ /// Return the (start,end) range of the given basic block.
+ const std::pair<SlotIndex, SlotIndex> &
+ getMBBRange(const MachineBasicBlock *MBB) const {
+ return getMBBRange(MBB->getNumber());
+ }
+
+ /// Returns the first index in the given basic block number.
+ SlotIndex getMBBStartIdx(unsigned Num) const {
+ return getMBBRange(Num).first;
+ }
+
+ /// Returns the first index in the given basic block.
+ SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const {
+ return getMBBRange(mbb).first;
+ }
+
+ /// Returns the last index in the given basic block number.
+ SlotIndex getMBBEndIdx(unsigned Num) const {
+ return getMBBRange(Num).second;
+ }
+
+ /// Returns the last index in the given basic block.
+ SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const {
+ return getMBBRange(mbb).second;
+ }
+
+ /// Returns the basic block which the given index falls in.
+ MachineBasicBlock* getMBBFromIndex(SlotIndex index) const {
+ if (MachineInstr *MI = getInstructionFromIndex(index))
+ return MI->getParent();
+ SmallVectorImpl<IdxMBBPair>::const_iterator I =
+ std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index);
+ // Take the pair containing the index
+ SmallVectorImpl<IdxMBBPair>::const_iterator J =
+ ((I != idx2MBBMap.end() && I->first > index) ||
+ (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I;
+
+ assert(J != idx2MBBMap.end() && J->first <= index &&
+ index < getMBBEndIdx(J->second) &&
+ "index does not correspond to an MBB");
+ return J->second;
+ }
+
+ bool findLiveInMBBs(SlotIndex start, SlotIndex end,
+ SmallVectorImpl<MachineBasicBlock*> &mbbs) const {
+ SmallVectorImpl<IdxMBBPair>::const_iterator itr =
+ std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
+ bool resVal = false;
+
+ while (itr != idx2MBBMap.end()) {
+ if (itr->first >= end)
+ break;
+ mbbs.push_back(itr->second);
+ resVal = true;
+ ++itr;
+ }
+ return resVal;
+ }
+
+ /// Returns the MBB covering the given range, or null if the range covers
+ /// more than one basic block.
+ MachineBasicBlock* getMBBCoveringRange(SlotIndex start, SlotIndex end) const {
+
+ assert(start < end && "Backwards ranges not allowed.");
+
+ SmallVectorImpl<IdxMBBPair>::const_iterator itr =
+ std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
+
+ if (itr == idx2MBBMap.end()) {
+ itr = prior(itr);
+ return itr->second;
+ }
+
+ // Check that we don't cross the boundary into this block.
+ if (itr->first < end)
+ return 0;
+
+ itr = prior(itr);
+
+ if (itr->first <= start)
+ return itr->second;
+
+ return 0;
+ }
+
+ /// Insert the given machine instruction into the mapping. Returns the
+ /// assigned index.
+ /// If Late is set and there are null indexes between mi's neighboring
+ /// instructions, create the new index after the null indexes instead of
+ /// before them.
+ SlotIndex insertMachineInstrInMaps(MachineInstr *mi, bool Late = false) {
+ assert(!mi->isInsideBundle() &&
+ "Instructions inside bundles should use bundle start's slot.");
+ assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed.");
+ // Numbering DBG_VALUE instructions could cause code generation to be
+ // affected by debug information.
+ assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions.");
+
+ assert(mi->getParent() != 0 && "Instr must be added to function.");
+
+ // Get the entries where mi should be inserted.
+ IndexList::iterator prevItr, nextItr;
+ if (Late) {
+ // Insert mi's index immediately before the following instruction.
+ nextItr = getIndexAfter(mi).listEntry();
+ prevItr = prior(nextItr);
+ } else {
+ // Insert mi's index immediately after the preceeding instruction.
+ prevItr = getIndexBefore(mi).listEntry();
+ nextItr = llvm::next(prevItr);
+ }
+
+ // Get a number for the new instr, or 0 if there's no room currently.
+ // In the latter case we'll force a renumber later.
+ unsigned dist = ((nextItr->getIndex() - prevItr->getIndex())/2) & ~3u;
+ unsigned newNumber = prevItr->getIndex() + dist;
+
+ // Insert a new list entry for mi.
+ IndexList::iterator newItr =
+ indexList.insert(nextItr, createEntry(mi, newNumber));
+
+ // Renumber locally if we need to.
+ if (dist == 0)
+ renumberIndexes(newItr);
+
+ SlotIndex newIndex(&*newItr, SlotIndex::Slot_Block);
+ mi2iMap.insert(std::make_pair(mi, newIndex));
+ return newIndex;
+ }
+
+ /// Remove the given machine instruction from the mapping.
+ void removeMachineInstrFromMaps(MachineInstr *mi) {
+ // remove index -> MachineInstr and
+ // MachineInstr -> index mappings
+ Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
+ if (mi2iItr != mi2iMap.end()) {
+ IndexListEntry *miEntry(mi2iItr->second.listEntry());
+ assert(miEntry->getInstr() == mi && "Instruction indexes broken.");
+ // FIXME: Eventually we want to actually delete these indexes.
+ miEntry->setInstr(0);
+ mi2iMap.erase(mi2iItr);
+ }
+ }
+
+ /// ReplaceMachineInstrInMaps - Replacing a machine instr with a new one in
+ /// maps used by register allocator.
+ void replaceMachineInstrInMaps(MachineInstr *mi, MachineInstr *newMI) {
+ Mi2IndexMap::iterator mi2iItr = mi2iMap.find(mi);
+ if (mi2iItr == mi2iMap.end())
+ return;
+ SlotIndex replaceBaseIndex = mi2iItr->second;
+ IndexListEntry *miEntry(replaceBaseIndex.listEntry());
+ assert(miEntry->getInstr() == mi &&
+ "Mismatched instruction in index tables.");
+ miEntry->setInstr(newMI);
+ mi2iMap.erase(mi2iItr);
+ mi2iMap.insert(std::make_pair(newMI, replaceBaseIndex));
+ }
+
+ /// Add the given MachineBasicBlock into the maps.
+ void insertMBBInMaps(MachineBasicBlock *mbb) {
+ MachineFunction::iterator nextMBB =
+ llvm::next(MachineFunction::iterator(mbb));
+ IndexListEntry *startEntry = createEntry(0, 0);
+ IndexListEntry *stopEntry = createEntry(0, 0);
+ IndexListEntry *nextEntry = 0;
+
+ if (nextMBB == mbb->getParent()->end()) {
+ nextEntry = indexList.end();
+ } else {
+ nextEntry = getMBBStartIdx(nextMBB).listEntry();
+ }
+
+ indexList.insert(nextEntry, startEntry);
+ indexList.insert(nextEntry, stopEntry);
+
+ SlotIndex startIdx(startEntry, SlotIndex::Slot_Block);
+ SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block);
+
+ assert(unsigned(mbb->getNumber()) == MBBRanges.size() &&
+ "Blocks must be added in order");
+ MBBRanges.push_back(std::make_pair(startIdx, endIdx));
+
+ idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
+
+ renumberIndexes();
+ std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
+ }
+
+ };
+
+
+ // 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;
+ }
+ };
+
+}
+
+#endif // LLVM_CODEGEN_SLOTINDEXES_H
diff --git a/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
new file mode 100644
index 000000000000..5a4213625bae
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -0,0 +1,133 @@
+//==-- llvm/CodeGen/TargetLoweringObjectFileImpl.h - Object Info -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
+
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+ class MachineModuleInfo;
+ class Mangler;
+ class MCAsmInfo;
+ class MCExpr;
+ class MCSection;
+ class MCSectionMachO;
+ class MCSymbol;
+ class MCContext;
+ class GlobalValue;
+ class TargetMachine;
+
+
+class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
+public:
+ virtual ~TargetLoweringObjectFileELF() {}
+
+ virtual void emitPersonalityValue(MCStreamer &Streamer,
+ const TargetMachine &TM,
+ const MCSymbol *Sym) const;
+
+ /// getSectionForConstant - Given a constant with the SectionKind, return a
+ /// section that it should be placed in.
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ /// getExprForDwarfGlobalReference - 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;
+
+ // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
+ virtual MCSymbol *
+ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI) const;
+
+ virtual const MCSection *
+ getStaticCtorSection(unsigned Priority = 65535) const;
+ virtual const MCSection *
+ getStaticDtorSection(unsigned Priority = 65535) const;
+};
+
+
+
+class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+public:
+ virtual ~TargetLoweringObjectFileMachO() {}
+
+ /// emitModuleFlags - Emit the module flags that specify the garbage
+ /// collection information.
+ virtual void emitModuleFlags(MCStreamer &Streamer,
+ ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+ /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
+ /// decide not to emit the UsedDirective for some symbols in llvm.used.
+ /// FIXME: REMOVE this (rdar://7071300)
+ virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
+ Mangler *) const;
+
+ /// getExprForDwarfGlobalReference - 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;
+
+ // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
+ virtual MCSymbol *
+ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI) const;
+};
+
+
+
+class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+public:
+ virtual ~TargetLoweringObjectFileCOFF() {}
+
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.h b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h
new file mode 100644
index 000000000000..76c2357a552f
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.h
@@ -0,0 +1,715 @@
+//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the set of low-level target independent types which various
+// values in the code generator are. This allows the target specific behavior
+// of instructions to be described to target independent passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_VALUETYPES_H
+#define LLVM_CODEGEN_VALUETYPES_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+ class Type;
+ class LLVMContext;
+ struct EVT;
+
+ /// MVT - Machine Value Type. Every type that is supported natively by some
+ /// processor targeted by LLVM occurs here. This means that any legal value
+ /// type can be represented by a MVT.
+ class MVT {
+ public:
+ enum SimpleValueType {
+ // If you change this numbering, you must change the values in
+ // ValueTypes.td as well!
+ Other = 0, // This is a non-standard value
+ i1 = 1, // This is a 1 bit integer value
+ i8 = 2, // This is an 8 bit integer value
+ i16 = 3, // This is a 16 bit integer value
+ i32 = 4, // This is a 32 bit integer value
+ i64 = 5, // This is a 64 bit integer value
+ i128 = 6, // This is a 128 bit integer value
+
+ FIRST_INTEGER_VALUETYPE = i1,
+ LAST_INTEGER_VALUETYPE = i128,
+
+ f16 = 7, // This is a 16 bit floating point value
+ f32 = 8, // This is a 32 bit floating point value
+ f64 = 9, // This is a 64 bit floating point value
+ f80 = 10, // This is a 80 bit floating point value
+ f128 = 11, // This is a 128 bit floating point value
+ ppcf128 = 12, // This is a PPC 128-bit floating point value
+
+ 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
+ v1i64 = 25, // 1 x i64
+ v2i64 = 26, // 2 x i64
+ v4i64 = 27, // 4 x i64
+ v8i64 = 28, // 8 x i64
+
+ v2f16 = 29, // 2 x f16
+ v2f32 = 30, // 2 x f32
+ v4f32 = 31, // 4 x f32
+ v8f32 = 32, // 8 x f32
+ v2f64 = 33, // 2 x f64
+ v4f64 = 34, // 4 x f64
+
+ FIRST_VECTOR_VALUETYPE = v2i8,
+ LAST_VECTOR_VALUETYPE = v4f64,
+ FIRST_FP_VECTOR_VALUETYPE = v2f16,
+ LAST_FP_VECTOR_VALUETYPE = v4f64,
+
+ x86mmx = 35, // This is an X86 MMX value
+
+ Glue = 36, // This glues nodes together during pre-RA sched
+
+ isVoid = 37, // This has no value
+
+ Untyped = 38, // This value takes a register, but has
+ // unspecified type. The register class
+ // will be determined by the opcode.
+
+ LAST_VALUETYPE = 39, // 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
+ // This value must be a multiple of 32.
+ MAX_ALLOWED_VALUETYPE = 64,
+
+ // Metadata - This is MDNode or MDString.
+ Metadata = 250,
+
+ // iPTRAny - An int value the size of the pointer of the current
+ // target to any address space. This must only be used internal to
+ // tblgen. Other than for overloading, we treat iPTRAny the same as iPTR.
+ iPTRAny = 251,
+
+ // vAny - A vector with any length and element size. This is used
+ // for intrinsics that have overloadings based on vector types.
+ // This is only for tblgen's consumption!
+ vAny = 252,
+
+ // fAny - Any floating-point or vector floating-point value. This is used
+ // for intrinsics that have overloadings based on floating-point types.
+ // This is only for tblgen's consumption!
+ fAny = 253,
+
+ // iAny - An integer or vector integer value of any bit width. This is
+ // used for intrinsics that have overloadings based on integer bit widths.
+ // This is only for tblgen's consumption!
+ iAny = 254,
+
+ // 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
+ };
+
+ SimpleValueType SimpleTy;
+
+ MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {}
+ MVT(SimpleValueType SVT) : SimpleTy(SVT) { }
+
+ bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; }
+ bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; }
+ bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; }
+ bool operator!=(const MVT& S) const { return SimpleTy != S.SimpleTy; }
+ bool operator>=(const MVT& S) const { return SimpleTy >= S.SimpleTy; }
+ bool operator<=(const MVT& S) const { return SimpleTy <= S.SimpleTy; }
+
+ /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+ bool isFloatingPoint() const {
+ return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE &&
+ SimpleTy <= MVT::LAST_FP_VALUETYPE) ||
+ (SimpleTy >= MVT::FIRST_FP_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE));
+ }
+
+ /// isInteger - Return true if this is an integer, or a vector integer type.
+ bool isInteger() const {
+ return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
+ SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
+ (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64));
+ }
+
+ /// isVector - Return true if this is a vector value type.
+ bool isVector() const {
+ return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
+ }
+
+ /// isPow2VectorType - Returns true if the given vector is a power of 2.
+ bool isPow2VectorType() const {
+ unsigned NElts = getVectorNumElements();
+ return !(NElts & (NElts - 1));
+ }
+
+ /// getPow2VectorType - Widens the length of the given vector MVT up to
+ /// the nearest power of 2 and returns that type.
+ MVT getPow2VectorType() const {
+ if (isPow2VectorType())
+ return *this;
+
+ unsigned NElts = getVectorNumElements();
+ unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
+ return MVT::getVectorVT(getVectorElementType(), Pow2NElts);
+ }
+
+ /// getScalarType - If this is a vector type, return the element type,
+ /// otherwise return this.
+ MVT getScalarType() const {
+ return isVector() ? getVectorElementType() : *this;
+ }
+
+ MVT getVectorElementType() const {
+ switch (SimpleTy) {
+ default:
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ case v2i8 :
+ case v4i8 :
+ case v8i8 :
+ case v16i8:
+ case v32i8: return i8;
+ case v2i16:
+ case v4i16:
+ case v8i16:
+ case v16i16: return i16;
+ case v2i32:
+ case v4i32:
+ case v8i32: return i32;
+ case v1i64:
+ case v2i64:
+ case v4i64:
+ case v8i64: return i64;
+ case v2f16: return f16;
+ case v2f32:
+ case v4f32:
+ case v8f32: return f32;
+ case v2f64:
+ case v4f64: return f64;
+ }
+ }
+
+ unsigned getVectorNumElements() const {
+ switch (SimpleTy) {
+ default:
+ return ~0U;
+ case v32i8: return 32;
+ case v16i8:
+ case v16i16: return 16;
+ case v8i8 :
+ case v8i16:
+ case v8i32:
+ case v8i64:
+ case v8f32: return 8;
+ case v4i8:
+ case v4i16:
+ case v4i32:
+ case v4i64:
+ case v4f32:
+ case v4f64: return 4;
+ case v2i8:
+ case v2i16:
+ case v2i32:
+ case v2i64:
+ case v2f16:
+ case v2f32:
+ case v2f64: return 2;
+ case v1i64: return 1;
+ }
+ }
+
+ unsigned getSizeInBits() const {
+ switch (SimpleTy) {
+ case iPTR:
+ llvm_unreachable("Value type size is target-dependent. Ask TLI.");
+ case iPTRAny:
+ case iAny:
+ case fAny:
+ llvm_unreachable("Value type is overloaded.");
+ default:
+ llvm_unreachable("getSizeInBits called on extended MVT.");
+ case i1 : return 1;
+ case i8 : return 8;
+ case i16 :
+ case f16:
+ case v2i8: return 16;
+ case f32 :
+ case i32 :
+ case v4i8:
+ case v2i16:
+ case v2f16: return 32;
+ case x86mmx:
+ case f64 :
+ case i64 :
+ case v8i8:
+ case v4i16:
+ case v2i32:
+ case v1i64:
+ case v2f32: return 64;
+ case f80 : return 80;
+ case f128:
+ case ppcf128:
+ case i128:
+ case v16i8:
+ case v8i16:
+ case v4i32:
+ case v2i64:
+ case v4f32:
+ case v2f64: return 128;
+ case v32i8:
+ case v16i16:
+ case v8i32:
+ case v4i64:
+ case v8f32:
+ case v4f64: return 256;
+ case v8i64: return 512;
+ }
+ }
+
+ /// getStoreSize - Return the number of bytes overwritten by a store
+ /// of the specified value type.
+ unsigned getStoreSize() const {
+ return (getSizeInBits() + 7) / 8;
+ }
+
+ /// getStoreSizeInBits - Return the number of bits overwritten by a store
+ /// of the specified value type.
+ unsigned getStoreSizeInBits() const {
+ return getStoreSize() * 8;
+ }
+
+ static MVT getFloatingPointVT(unsigned BitWidth) {
+ switch (BitWidth) {
+ default:
+ llvm_unreachable("Bad bit width!");
+ case 16:
+ return MVT::f16;
+ case 32:
+ return MVT::f32;
+ case 64:
+ return MVT::f64;
+ case 80:
+ return MVT::f80;
+ case 128:
+ return MVT::f128;
+ }
+ }
+
+ static MVT getIntegerVT(unsigned BitWidth) {
+ switch (BitWidth) {
+ default:
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ case 1:
+ return MVT::i1;
+ case 8:
+ return MVT::i8;
+ case 16:
+ return MVT::i16;
+ case 32:
+ return MVT::i32;
+ case 64:
+ return MVT::i64;
+ case 128:
+ return MVT::i128;
+ }
+ }
+
+ static MVT getVectorVT(MVT VT, unsigned NumElements) {
+ switch (VT.SimpleTy) {
+ default:
+ 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;
+ break;
+ case MVT::i16:
+ if (NumElements == 2) return MVT::v2i16;
+ if (NumElements == 4) return MVT::v4i16;
+ if (NumElements == 8) return MVT::v8i16;
+ if (NumElements == 16) return MVT::v16i16;
+ break;
+ case MVT::i32:
+ if (NumElements == 2) return MVT::v2i32;
+ if (NumElements == 4) return MVT::v4i32;
+ if (NumElements == 8) return MVT::v8i32;
+ break;
+ case MVT::i64:
+ if (NumElements == 1) return MVT::v1i64;
+ if (NumElements == 2) return MVT::v2i64;
+ if (NumElements == 4) return MVT::v4i64;
+ if (NumElements == 8) return MVT::v8i64;
+ break;
+ case MVT::f16:
+ if (NumElements == 2) return MVT::v2f16;
+ break;
+ case MVT::f32:
+ if (NumElements == 2) return MVT::v2f32;
+ if (NumElements == 4) return MVT::v4f32;
+ if (NumElements == 8) return MVT::v8f32;
+ break;
+ case MVT::f64:
+ if (NumElements == 2) return MVT::v2f64;
+ if (NumElements == 4) return MVT::v4f64;
+ break;
+ }
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ }
+ };
+
+
+ /// EVT - Extended Value Type. Capable of holding value types which are not
+ /// native for any processor (such as the i12345 type), as well as the types
+ /// a MVT can represent.
+ struct EVT {
+ private:
+ MVT V;
+ Type *LLVMTy;
+
+ public:
+ EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)),
+ LLVMTy(0) {}
+ EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(0) { }
+ EVT(MVT S) : V(S), LLVMTy(0) {}
+
+ bool operator==(EVT VT) const {
+ return !(*this != VT);
+ }
+ bool operator!=(EVT VT) const {
+ if (V.SimpleTy != VT.V.SimpleTy)
+ return true;
+ if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return LLVMTy != VT.LLVMTy;
+ return false;
+ }
+
+ /// getFloatingPointVT - Returns the EVT that represents a floating point
+ /// type with the given number of bits. There are two floating point types
+ /// with 128 bits - this returns f128 rather than ppcf128.
+ static EVT getFloatingPointVT(unsigned BitWidth) {
+ return MVT::getFloatingPointVT(BitWidth);
+ }
+
+ /// getIntegerVT - Returns the EVT that represents an integer with the given
+ /// number of bits.
+ static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
+ MVT M = MVT::getIntegerVT(BitWidth);
+ if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
+ return M;
+ return getExtendedIntegerVT(Context, BitWidth);
+ }
+
+ /// getVectorVT - Returns the EVT that represents a vector NumElements in
+ /// 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)
+ return M;
+ return getExtendedVectorVT(Context, VT, NumElements);
+ }
+
+ /// changeVectorElementTypeToInteger - Return a vector with the same number
+ /// of elements as this vector, but with the element type converted to an
+ /// integer type with the same bitwidth.
+ EVT changeVectorElementTypeToInteger() const {
+ if (!isSimple())
+ return changeExtendedVectorElementTypeToInteger();
+ MVT EltTy = getSimpleVT().getVectorElementType();
+ unsigned BitWidth = EltTy.getSizeInBits();
+ MVT IntTy = MVT::getIntegerVT(BitWidth);
+ MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements());
+ assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
+ "Simple vector VT not representable by simple integer vector VT!");
+ return VecTy;
+ }
+
+ /// isSimple - Test if the given EVT is simple (as opposed to being
+ /// extended).
+ bool isSimple() const {
+ return V.SimpleTy <= MVT::LastSimpleValueType;
+ }
+
+ /// isExtended - Test if the given EVT is extended (as opposed to
+ /// being simple).
+ bool isExtended() const {
+ return !isSimple();
+ }
+
+ /// isFloatingPoint - Return true if this is a FP, or a vector FP type.
+ bool isFloatingPoint() const {
+ return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
+ }
+
+ /// isInteger - Return true if this is an integer, or a vector integer type.
+ bool isInteger() const {
+ return isSimple() ? V.isInteger() : isExtendedInteger();
+ }
+
+ /// isVector - Return true if this is a vector value type.
+ bool isVector() const {
+ return isSimple() ? V.isVector() : isExtendedVector();
+ }
+
+ /// is64BitVector - Return true if this is a 64-bit vector type.
+ bool is64BitVector() const {
+ if (!isSimple())
+ return isExtended64BitVector();
+
+ return (V == MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 ||
+ V == MVT::v1i64 || V==MVT::v2f32);
+ }
+
+ /// is128BitVector - Return true if this is a 128-bit vector type.
+ bool is128BitVector() const {
+ if (!isSimple())
+ return isExtended128BitVector();
+ return (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 ||
+ V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64);
+ }
+
+ /// is256BitVector - Return true if this is a 256-bit vector type.
+ inline bool is256BitVector() const {
+ if (!isSimple())
+ return isExtended256BitVector();
+ return (V == MVT::v8f32 || V == MVT::v4f64 || V == MVT::v32i8 ||
+ V == MVT::v16i16 || V == MVT::v8i32 || V == MVT::v4i64);
+ }
+
+ /// is512BitVector - Return true if this is a 512-bit vector type.
+ inline bool is512BitVector() const {
+ return isSimple() ? (V == MVT::v8i64) : isExtended512BitVector();
+ }
+
+ /// isOverloaded - Return true if this is an overloaded type for TableGen.
+ bool isOverloaded() const {
+ return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny);
+ }
+
+ /// isByteSized - Return true if the bit size is a multiple of 8.
+ bool isByteSized() const {
+ return (getSizeInBits() & 7) == 0;
+ }
+
+ /// isRound - Return true if the size is a power-of-two number of bytes.
+ bool isRound() const {
+ unsigned BitSize = getSizeInBits();
+ return BitSize >= 8 && !(BitSize & (BitSize - 1));
+ }
+
+ /// bitsEq - Return true if this has the same number of bits as VT.
+ bool bitsEq(EVT VT) const {
+ if (EVT::operator==(VT)) return true;
+ return getSizeInBits() == VT.getSizeInBits();
+ }
+
+ /// bitsGT - Return true if this has more bits than VT.
+ bool bitsGT(EVT VT) const {
+ if (EVT::operator==(VT)) return false;
+ return getSizeInBits() > VT.getSizeInBits();
+ }
+
+ /// bitsGE - Return true if this has no less bits than VT.
+ bool bitsGE(EVT VT) const {
+ if (EVT::operator==(VT)) return true;
+ return getSizeInBits() >= VT.getSizeInBits();
+ }
+
+ /// bitsLT - Return true if this has less bits than VT.
+ bool bitsLT(EVT VT) const {
+ if (EVT::operator==(VT)) return false;
+ return getSizeInBits() < VT.getSizeInBits();
+ }
+
+ /// bitsLE - Return true if this has no more bits than VT.
+ bool bitsLE(EVT VT) const {
+ if (EVT::operator==(VT)) return true;
+ return getSizeInBits() <= VT.getSizeInBits();
+ }
+
+
+ /// getSimpleVT - Return the SimpleValueType held in the specified
+ /// simple EVT.
+ MVT getSimpleVT() const {
+ assert(isSimple() && "Expected a SimpleValueType!");
+ return V;
+ }
+
+ /// getScalarType - If this is a vector type, return the element type,
+ /// otherwise return this.
+ EVT getScalarType() const {
+ return isVector() ? getVectorElementType() : *this;
+ }
+
+ /// getVectorElementType - Given a vector type, return the type of
+ /// each element.
+ EVT getVectorElementType() const {
+ assert(isVector() && "Invalid vector type!");
+ if (isSimple())
+ return V.getVectorElementType();
+ return getExtendedVectorElementType();
+ }
+
+ /// getVectorNumElements - Given a vector type, return the number of
+ /// elements it contains.
+ unsigned getVectorNumElements() const {
+ assert(isVector() && "Invalid vector type!");
+ if (isSimple())
+ return V.getVectorNumElements();
+ return getExtendedVectorNumElements();
+ }
+
+ /// getSizeInBits - Return the size of the specified value type in bits.
+ unsigned getSizeInBits() const {
+ if (isSimple())
+ return V.getSizeInBits();
+ return getExtendedSizeInBits();
+ }
+
+ /// getStoreSize - Return the number of bytes overwritten by a store
+ /// of the specified value type.
+ unsigned getStoreSize() const {
+ return (getSizeInBits() + 7) / 8;
+ }
+
+ /// getStoreSizeInBits - Return the number of bits overwritten by a store
+ /// of the specified value type.
+ unsigned getStoreSizeInBits() const {
+ return getStoreSize() * 8;
+ }
+
+ /// getRoundIntegerType - Rounds the bit-width of the given integer EVT up
+ /// to the nearest power of two (and at least to eight), and returns the
+ /// integer EVT with that number of bits.
+ EVT getRoundIntegerType(LLVMContext &Context) const {
+ assert(isInteger() && !isVector() && "Invalid integer type!");
+ unsigned BitWidth = getSizeInBits();
+ if (BitWidth <= 8)
+ return EVT(MVT::i8);
+ return getIntegerVT(Context, 1 << Log2_32_Ceil(BitWidth));
+ }
+
+ /// getHalfSizedIntegerVT - Finds the smallest simple value type that is
+ /// greater than or equal to half the width of this EVT. If no simple
+ /// value type can be found, an extended integer value type of half the
+ /// size (rounded up) is returned.
+ EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
+ assert(isInteger() && !isVector() && "Invalid integer type!");
+ unsigned EVTSize = getSizeInBits();
+ for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
+ IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
+ EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
+ if (HalfVT.getSizeInBits() * 2 >= EVTSize)
+ return HalfVT;
+ }
+ return getIntegerVT(Context, (EVTSize + 1) / 2);
+ }
+
+ /// isPow2VectorType - Returns true if the given vector is a power of 2.
+ bool isPow2VectorType() const {
+ unsigned NElts = getVectorNumElements();
+ return !(NElts & (NElts - 1));
+ }
+
+ /// getPow2VectorType - Widens the length of the given vector EVT up to
+ /// the nearest power of 2 and returns that type.
+ EVT getPow2VectorType(LLVMContext &Context) const {
+ if (!isPow2VectorType()) {
+ unsigned NElts = getVectorNumElements();
+ unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
+ return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts);
+ }
+ else {
+ return *this;
+ }
+ }
+
+ /// getEVTString - This function returns value type as a string,
+ /// e.g. "i32".
+ std::string getEVTString() const;
+
+ /// getTypeForEVT - This method returns an LLVM type corresponding to the
+ /// specified EVT. For integer types, this returns an unsigned type. Note
+ /// that this will abort for types that cannot be represented.
+ Type *getTypeForEVT(LLVMContext &Context) const;
+
+ /// getEVT - 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 EVT getEVT(Type *Ty, bool HandleUnknown = false);
+
+ intptr_t getRawBits() {
+ if (isSimple())
+ return V.SimpleTy;
+ else
+ return (intptr_t)(LLVMTy);
+ }
+
+ /// compareRawBits - A meaningless but well-behaved order, useful for
+ /// constructing containers.
+ struct compareRawBits {
+ bool operator()(EVT L, EVT R) const {
+ if (L.V.SimpleTy == R.V.SimpleTy)
+ return L.LLVMTy < R.LLVMTy;
+ else
+ return L.V.SimpleTy < R.V.SimpleTy;
+ }
+ };
+
+ private:
+ // Methods for handling the Extended-type case in functions above.
+ // These are all out-of-line to prevent users of this header file
+ // from having a dependency on Type.h.
+ EVT changeExtendedVectorElementTypeToInteger() const;
+ static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
+ static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
+ unsigned NumElements);
+ bool isExtendedFloatingPoint() const;
+ bool isExtendedInteger() const;
+ bool isExtendedVector() const;
+ bool isExtended64BitVector() const;
+ bool isExtended128BitVector() const;
+ bool isExtended256BitVector() const;
+ bool isExtended512BitVector() const;
+ EVT getExtendedVectorElementType() const;
+ unsigned getExtendedVectorNumElements() const;
+ unsigned getExtendedSizeInBits() const;
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/CodeGen/ValueTypes.td b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td
new file mode 100644
index 000000000000..6c2269052a11
--- /dev/null
+++ b/contrib/llvm/include/llvm/CodeGen/ValueTypes.td
@@ -0,0 +1,81 @@
+//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Value types - These values correspond to the register types defined in the
+// ValueTypes.h file. If you update anything here, you must update it there as
+// well!
+//
+//===----------------------------------------------------------------------===//
+
+class ValueType<int size, int value> {
+ string Namespace = "MVT";
+ int Size = size;
+ int Value = value;
+}
+
+def OtherVT: ValueType<0 , 0>; // "Other" value
+def i1 : ValueType<1 , 1>; // One bit boolean value
+def i8 : ValueType<8 , 2>; // 8-bit integer value
+def i16 : ValueType<16 , 3>; // 16-bit integer value
+def i32 : ValueType<32 , 4>; // 32-bit integer value
+def i64 : ValueType<64 , 5>; // 64-bit integer value
+def i128 : ValueType<128, 6>; // 128-bit integer value
+def f16 : ValueType<16 , 7>; // 32-bit floating point value
+def f32 : ValueType<32 , 8>; // 32-bit floating point value
+def f64 : ValueType<64 , 9>; // 64-bit floating point value
+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 v1i64 : ValueType<64 , 25>; // 1 x i64 vector value
+def v2i64 : ValueType<128, 26>; // 2 x i64 vector value
+def v4i64 : ValueType<256, 27>; // 4 x i64 vector value
+def v8i64 : ValueType<512, 28>; // 8 x i64 vector value
+
+def v2f16 : ValueType<32 , 29>; // 2 x f16 vector value
+def v2f32 : ValueType<64 , 30>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 31>; // 4 x f32 vector value
+def v8f32 : ValueType<256, 32>; // 8 x f32 vector value
+def v2f64 : ValueType<128, 33>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 34>; // 4 x f64 vector value
+
+def x86mmx : ValueType<64 , 35>; // X86 MMX value
+def FlagVT : ValueType<0 , 36>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 37>; // Produces no value
+def untyped: ValueType<8 , 38>; // Produces an untyped value
+
+def MetadataVT: ValueType<0, 250>; // Metadata
+
+// Pseudo valuetype mapped to the current pointer size to any address space.
+// Should only be used in TableGen.
+def iPTRAny : ValueType<0, 251>;
+
+// Pseudo valuetype to represent "vector of any size"
+def vAny : ValueType<0 , 252>;
+
+// Pseudo valuetype to represent "float of any format"
+def fAny : ValueType<0 , 253>;
+
+// Pseudo valuetype to represent "integer of any bit width"
+def iAny : ValueType<0 , 254>;
+
+// Pseudo valuetype mapped to the current pointer size.
+def iPTR : ValueType<0 , 255>;
diff --git a/contrib/llvm/include/llvm/Constant.h b/contrib/llvm/include/llvm/Constant.h
new file mode 100644
index 000000000000..13acdc66b892
--- /dev/null
+++ b/contrib/llvm/include/llvm/Constant.h
@@ -0,0 +1,158 @@
+//===-- llvm/Constant.h - Constant class definition -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Constant class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CONSTANT_H
+#define LLVM_CONSTANT_H
+
+#include "llvm/User.h"
+
+namespace llvm {
+ class APInt;
+
+ template<typename T> class SmallVectorImpl;
+
+/// This is an important base class in LLVM. It provides the common facilities
+/// of all constant values in an LLVM program. A constant is a value that is
+/// immutable at runtime. Functions are constants because their address is
+/// immutable. Same with global variables.
+///
+/// All constants share the capabilities provided in this class. All constants
+/// can have a null value. They can have an operand list. Constants can be
+/// simple (integer and floating point values), complex (arrays and structures),
+/// or expression based (computations yielding a constant value composed of
+/// only certain operators and other constant values).
+///
+/// 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.
+/// Constants are created on demand as needed and never deleted: thus clients
+/// 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
+ virtual void anchor();
+
+protected:
+ Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
+ : User(ty, vty, Ops, NumOps) {}
+
+ void destroyConstantImpl();
+public:
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue.
+ bool isNullValue() const;
+
+ /// isAllOnesValue - Return true if this is the value that would be returned by
+ /// getAllOnesValue.
+ bool isAllOnesValue() const;
+
+ /// isNegativeZeroValue - Return true if the value is what would be returned
+ /// by getZeroValueForNegation.
+ bool isNegativeZeroValue() const;
+
+ /// canTrap - Return true if evaluation of this constant could trap. This is
+ /// true for things like constant expressions that could divide by zero.
+ bool canTrap() const;
+
+ /// isConstantUsed - Return true if the constant has users other than constant
+ /// exprs and other dangling things.
+ bool isConstantUsed() const;
+
+ enum PossibleRelocationsTy {
+ NoRelocation = 0,
+ LocalRelocation = 1,
+ GlobalRelocations = 2
+ };
+
+ /// getRelocationInfo - This method classifies the entry according to
+ /// whether or not it may generate a relocation entry. This must be
+ /// conservative, so if it might codegen to a relocatable entry, it should say
+ /// so. The return values are:
+ ///
+ /// NoRelocation: This constant pool entry is guaranteed to never have a
+ /// relocation applied to it (because it holds a simple constant like
+ /// '4').
+ /// LocalRelocation: This entry has relocations, but the entries are
+ /// guaranteed to be resolvable by the static linker, so the dynamic
+ /// linker will never see them.
+ /// GlobalRelocations: This entry may have arbitrary relocations.
+ ///
+ /// FIXME: This really should not be in VMCore.
+ PossibleRelocationsTy getRelocationInfo() const;
+
+ /// getAggregateElement - For aggregates (struct/array/vector) return the
+ /// constant that corresponds to the specified element if possible, or null if
+ /// not. This can return null if the element index is a ConstantExpr, or if
+ /// 'this' is a constant expr.
+ Constant *getAggregateElement(unsigned Elt) const;
+ Constant *getAggregateElement(Constant *Elt) 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
+ /// implementation must be sure to remove the constant from the list of
+ /// available cached constants. Implementations should call
+ /// destroyConstantImpl as the last thing they do, to destroy all users and
+ /// delete this.
+ 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;
+ }
+
+ /// replaceUsesOfWithOnConstant - This method is a special form of
+ /// User::replaceUsesOfWith (which does not work on constants) that does work
+ /// on constants. Basically this method goes through the trouble of building
+ /// a new constant that is equivalent to the current one, with all uses of
+ /// From replaced with uses of To. After this construction is completed, all
+ /// of the users of 'this' are replaced to use the new constant, and then
+ /// 'this' is deleted. In general, you should not call this method, instead,
+ /// use Value::replaceAllUsesWith, which automatically dispatches to this
+ /// method as needed.
+ ///
+ virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) {
+ // Provide a default implementation for constants (like integers) that
+ // cannot use any other values. This cannot be called at runtime, but needs
+ // to be here to avoid link errors.
+ assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be "
+ "implemented for all constants that have operands!");
+ llvm_unreachable("Constants that do not have operands cannot be using "
+ "'From'!");
+ }
+
+ static Constant *getNullValue(Type* Ty);
+
+ /// @returns the value for an integer constant of the given type that has all
+ /// its bits set to true.
+ /// @brief Get the all ones value
+ static Constant *getAllOnesValue(Type* Ty);
+
+ /// getIntegerValue - Return the value for an integer or pointer constant,
+ /// or a vector thereof, with the given scalar value.
+ static Constant *getIntegerValue(Type* Ty, const APInt &V);
+
+ /// removeDeadConstantUsers - If there are any dead constant users dangling
+ /// off of this constant, remove them. This method is useful for clients
+ /// that want to check to see if a global is unused, but don't want to deal
+ /// with potentially dead constants hanging off of the globals.
+ void removeDeadConstantUsers() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Constants.h b/contrib/llvm/include/llvm/Constants.h
new file mode 100644
index 000000000000..0abe17d365d4
--- /dev/null
+++ b/contrib/llvm/include/llvm/Constants.h
@@ -0,0 +1,1159 @@
+//===-- llvm/Constants.h - Constant class subclass definitions --*- 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 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
+/// 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
+/// worry about the lifetime of the objects.
+//
+//===----------------------------------------------------------------------===//
+
+#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/ArrayRef.h"
+
+namespace llvm {
+
+class ArrayType;
+class IntegerType;
+class StructType;
+class PointerType;
+class VectorType;
+class SequentialType;
+
+template<class ConstantClass, class TypeClass, class ValType>
+struct ConstantCreator;
+template<class ConstantClass, class TypeClass>
+struct ConstantArrayCreator;
+template<class ConstantClass, class TypeClass>
+struct ConvertConstantType;
+
+//===----------------------------------------------------------------------===//
+/// 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
+ ConstantInt(IntegerType *Ty, const APInt& V);
+ APInt Val;
+protected:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+public:
+ static ConstantInt *getTrue(LLVMContext &Context);
+ 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
+ /// be interpreted as a 64-bit signed integer and sign-extended to fit
+ /// the type.
+ /// @brief Get a ConstantInt for a specific value.
+ static ConstantInt *get(IntegerType *Ty, uint64_t V,
+ bool isSigned = false);
+
+ /// Return a ConstantInt with the specified value for the specified type. The
+ /// value V will be canonicalized to a an unsigned APInt. Accessing it with
+ /// either getSExtValue() or getZExtValue() will yield a correctly sized and
+ /// signed value for the type Ty.
+ /// @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.
+ 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(); }
+
+ /// Return the constant as a 64-bit unsigned integer value after it
+ /// has been zero extended as appropriate for the type of this constant. Note
+ /// that this method can assert if the value does not fit in 64 bits.
+ /// @deprecated
+ /// @brief Return the zero extended value.
+ inline uint64_t getZExtValue() const {
+ return Val.getZExtValue();
+ }
+
+ /// Return the constant as a 64-bit integer value after it has been sign
+ /// extended as appropriate for the type of this constant. Note that
+ /// this method can assert if the value does not fit in 64 bits.
+ /// @deprecated
+ /// @brief Return the sign extended value.
+ inline int64_t getSExtValue() const {
+ 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,
+ /// 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 {
+ return Val == V;
+ }
+
+ /// getType - Specialize the getType() method to always return an IntegerType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline IntegerType *getType() const {
+ 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
+ /// 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,
+ /// 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
+ /// @brief Determine if the value is in range for the given type.
+ static bool isValueValidForType(Type *Ty, uint64_t V);
+ static bool isValueValidForType(Type *Ty, int64_t V);
+
+ bool isNegative() const { return Val.isNegative(); }
+
+ /// This is just a convenience method to make client code smaller for a
+ /// common code. It also correctly performs the comparison without the
+ /// potential for an assertion from getZExtValue().
+ bool isZero() const {
+ return Val == 0;
+ }
+
+ /// 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.
+ bool isOne() const {
+ return Val == 1;
+ }
+
+ /// This function will return true iff every bit in this constant is set
+ /// 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 {
+ 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
+ /// by this type.
+ /// @brief Determine if the value is maximal.
+ bool isMaxValue(bool isSigned) const {
+ if (isSigned)
+ return Val.isMaxSignedValue();
+ else
+ return Val.isMaxValue();
+ }
+
+ /// 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
+ /// this type.
+ /// @brief Determine if the value is minimal.
+ bool isMinValue(bool isSigned) const {
+ if (isSigned)
+ return Val.isMinSignedValue();
+ else
+ return Val.isMinValue();
+ }
+
+ /// This function will return true iff this constant represents a value with
+ /// active bits bigger than 64 bits or a value greater than the given uint64_t
+ /// value.
+ /// @returns true iff this constant is greater or equal to the given number.
+ /// @brief Determine if the value is greater or equal to the given number.
+ bool uge(uint64_t Num) const {
+ return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num;
+ }
+
+ /// getLimitedValue - If the value is smaller than the specified limit,
+ /// return it, otherwise return the limit value. This causes the value
+ /// to saturate to the limit.
+ /// @returns the min of the value of the constant and the specified value
+ /// @brief Get the constant's value with a saturation limit
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return Val.getLimitedValue(Limit);
+ }
+
+ /// @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;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantFP - Floating Point Values [float, double]
+///
+class ConstantFP : public Constant {
+ APFloat Val;
+ virtual void anchor();
+ void *operator new(size_t, unsigned);// DO NOT IMPLEMENT
+ ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT
+ friend class LLVMContextImpl;
+protected:
+ ConstantFP(Type *Ty, const APFloat& V);
+protected:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+public:
+ /// Floating point negation must be implemented with f(x) = -0.0 - x. This
+ /// 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
+ /// known-valid both as host double and as the target format.
+ static Constant *get(Type* Ty, double V);
+ static Constant *get(Type* Ty, StringRef Str);
+ 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; }
+
+ /// isZero - Return true if the value is positive or negative zero.
+ bool isZero() const { return Val.isZero(); }
+
+ /// isNegative - Return true if the sign bit is set.
+ bool isNegative() const { return Val.isNegative(); }
+
+ /// isNaN - Return true if the value is a NaN.
+ bool isNaN() const { return Val.isNaN(); }
+
+ /// isExactlyValue - We don't rely on operator== working on double values, as
+ /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
+ /// As such, this method can be used to do an exact bit-for-bit comparison of
+ /// two floating point values. The version with a double operand is retained
+ /// because it's so convenient to write isExactlyValue(2.0), but please use
+ /// it only for simple constants.
+ bool isExactlyValue(const APFloat &V) const;
+
+ 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;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantAggregateZero - All zero aggregate value
+///
+class ConstantAggregateZero : public Constant {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT
+protected:
+ explicit ConstantAggregateZero(Type *ty)
+ : Constant(ty, ConstantAggregateZeroVal, 0, 0) {}
+protected:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+public:
+ static ConstantAggregateZero *get(Type *Ty);
+
+ virtual void destroyConstant();
+
+ /// getSequentialElement - If this CAZ has array or vector type, return a zero
+ /// with the right element type.
+ Constant *getSequentialElement() const;
+
+ /// getStructElement - If this CAZ has struct type, return a zero with the
+ /// right element type for the specified element.
+ Constant *getStructElement(unsigned Elt) const;
+
+ /// getElementValue - Return a zero of the right value for the specified GEP
+ /// index.
+ Constant *getElementValue(Constant *C) const;
+
+ /// getElementValue - Return a zero of the right value for the specified GEP
+ /// index.
+ Constant *getElementValue(unsigned Idx) const;
+
+ /// 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;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantArray - Constant Array Declarations
+///
+class ConstantArray : public Constant {
+ friend struct ConstantArrayCreator<ConstantArray, ArrayType>;
+ ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT
+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);
+
+ /// getType - Specialize the getType() method to always return an ArrayType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline ArrayType *getType() const {
+ return reinterpret_cast<ArrayType*>(Value::getType());
+ }
+
+ 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 ConstantArray *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantArrayVal;
+ }
+};
+
+template <>
+struct OperandTraits<ConstantArray> :
+ public VariadicOperandTraits<ConstantArray> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant)
+
+//===----------------------------------------------------------------------===//
+// ConstantStruct - Constant Struct Declarations
+//
+class ConstantStruct : public Constant {
+ friend struct ConstantArrayCreator<ConstantStruct, StructType>;
+ ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT
+protected:
+ ConstantStruct(StructType *T, ArrayRef<Constant *> Val);
+public:
+ // ConstantStruct accessors
+ static Constant *get(StructType *T, ArrayRef<Constant*> V);
+ static Constant *get(StructType *T, ...) END_WITH_NULL;
+
+ /// getAnon - Return an anonymous struct that has the specified
+ /// elements. If the struct is possibly empty, then you must specify a
+ /// context.
+ static Constant *getAnon(ArrayRef<Constant*> V, bool Packed = false) {
+ return get(getTypeForElements(V, Packed), V);
+ }
+ static Constant *getAnon(LLVMContext &Ctx,
+ ArrayRef<Constant*> V, bool Packed = false) {
+ return get(getTypeForElements(Ctx, V, Packed), V);
+ }
+
+ /// getTypeForElements - Return an anonymous struct type to use for a constant
+ /// with the specified set of elements. The list must not be empty.
+ static StructType *getTypeForElements(ArrayRef<Constant*> V,
+ bool Packed = false);
+ /// getTypeForElements - This version of the method allows an empty list.
+ static StructType *getTypeForElements(LLVMContext &Ctx,
+ ArrayRef<Constant*> V,
+ bool Packed = false);
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ /// getType() specialization - Reduce amount of casting...
+ ///
+ inline StructType *getType() const {
+ return reinterpret_cast<StructType*>(Value::getType());
+ }
+
+ 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 ConstantStruct *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantStructVal;
+ }
+};
+
+template <>
+struct OperandTraits<ConstantStruct> :
+ public VariadicOperandTraits<ConstantStruct> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant)
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantVector - Constant Vector Declarations
+///
+class ConstantVector : public Constant {
+ friend struct ConstantArrayCreator<ConstantVector, VectorType>;
+ ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT
+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);
+
+ /// 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());
+ }
+
+ /// 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;
+
+ 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 ConstantVector *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantVectorVal;
+ }
+};
+
+template <>
+struct OperandTraits<ConstantVector> :
+ public VariadicOperandTraits<ConstantVector> {
+};
+
+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
+protected:
+ explicit ConstantPointerNull(PointerType *T)
+ : Constant(reinterpret_cast<Type*>(T),
+ Value::ConstantPointerNullVal, 0, 0) {}
+
+protected:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+public:
+ /// get() - Static factory methods - Return objects of the specified value
+ static ConstantPointerNull *get(PointerType *T);
+
+ virtual void destroyConstant();
+
+ /// getType - Specialize the getType() method to always return an PointerType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline PointerType *getType() const {
+ return reinterpret_cast<PointerType*>(Value::getType());
+ }
+
+ /// 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
+/// simple data values (i.e. ConstantInt/ConstantFP). This Constant node has no
+/// operands because it stores all of the elements of the constant as densely
+/// packed data, instead of as Value*'s.
+///
+/// This is the common base class of ConstantDataArray and ConstantDataVector.
+///
+class ConstantDataSequential : public Constant {
+ friend class LLVMContextImpl;
+ /// 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
+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:
+ // allocate space for exactly zero operands.
+ void *operator new(size_t s) {
+ 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;
+
+ /// getElementAsAPFloat - If this is a sequential container of floating point
+ /// type, return the specified element as an APFloat.
+ APFloat getElementAsAPFloat(unsigned i) const;
+
+ /// 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;
+
+ /// getElementByteSize - Return the size (in bytes) of each element in the
+ /// array/vector. The size of the elements is known to be a multiple of one
+ /// 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.
+ ///
+ StringRef getAsString() const {
+ 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.
+ ///
+ StringRef getAsCString() const {
+ assert(isCString() && "Isn't a C string");
+ 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;
+ }
+private:
+ const char *getElementPointer(unsigned Elt) const;
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantDataArray - An array constant whose element type is a simple
+/// 1/2/4/8-byte integer or float/double, and whose elements are just simple
+/// data values (i.e. ConstantInt/ConstantFP). This Constant node has no
+/// 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
+ virtual void anchor();
+ friend class ConstantDataSequential;
+ explicit ConstantDataArray(Type *ty, const char *Data)
+ : ConstantDataSequential(ty, ConstantDataArrayVal, Data) {}
+protected:
+ // allocate space for exactly zero operands.
+ void *operator new(size_t s) {
+ 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.
+ static Constant *get(LLVMContext &Context, ArrayRef<uint8_t> Elts);
+ static Constant *get(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+ static Constant *get(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+ 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
+ /// one more than the StringRef would normally indicate. Pass AddNull=false
+ /// to disable this behavior.
+ static Constant *getString(LLVMContext &Context, StringRef Initializer,
+ bool AddNull = true);
+
+ /// getType - Specialize the getType() method to always return an ArrayType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ 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
+/// data values (i.e. ConstantInt/ConstantFP). This Constant node has no
+/// 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
+ virtual void anchor();
+ friend class ConstantDataSequential;
+ explicit ConstantDataVector(Type *ty, const char *Data)
+ : ConstantDataSequential(ty, ConstantDataVectorVal, Data) {}
+protected:
+ // allocate space for exactly zero operands.
+ void *operator new(size_t s) {
+ 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.
+ static Constant *get(LLVMContext &Context, ArrayRef<uint8_t> Elts);
+ static Constant *get(LLVMContext &Context, ArrayRef<uint16_t> Elts);
+ static Constant *get(LLVMContext &Context, ArrayRef<uint32_t> Elts);
+ 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.
+ static Constant *getSplat(unsigned NumElts, Constant *Elt);
+
+ /// 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;
+ }
+};
+
+
+
+/// 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 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;
+ }
+};
+
+template <>
+struct OperandTraits<BlockAddress> :
+ public FixedNumOperandTraits<BlockAddress, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value)
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantExpr - a constant value that is initialized with an expression using
+/// other constant values.
+///
+/// This class uses the standard Instruction opcodes to define the various
+/// constant expressions. The Opcode field for the ConstantExpr class is
+/// maintained in the Value::SubclassData field.
+class ConstantExpr : public Constant {
+ friend struct ConstantCreator<ConstantExpr,Type,
+ std::pair<unsigned, std::vector<Constant*> > >;
+ friend struct ConvertConstantType<ConstantExpr, Type>;
+
+protected:
+ ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps)
+ : Constant(ty, ConstantExprVal, Ops, NumOps) {
+ // Operation type (an Instruction opcode) is stored as the SubclassData.
+ setValueSubclassData(Opcode);
+ }
+
+public:
+ // Static methods to construct a ConstantExpr of different kinds. Note that
+ // these methods may return a object that is not an instance of the
+ // ConstantExpr class, because they will attempt to fold the constant
+ // expression into something simpler if possible.
+
+ /// 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
+ /// target independent way (Note: the return type is an i64).
+ ///
+ static Constant *getOffsetOf(StructType *STy, unsigned FieldNo);
+
+ /// getOffsetOf constant expr - This is a generalized form of getOffsetOf,
+ /// 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);
+ static Constant *getAdd(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
+ static Constant *getFAdd(Constant *C1, Constant *C2);
+ static Constant *getSub(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
+ static Constant *getFSub(Constant *C1, Constant *C2);
+ static Constant *getMul(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
+ static Constant *getFMul(Constant *C1, Constant *C2);
+ static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getFDiv(Constant *C1, Constant *C2);
+ static Constant *getURem(Constant *C1, Constant *C2);
+ static Constant *getSRem(Constant *C1, Constant *C2);
+ static Constant *getFRem(Constant *C1, Constant *C2);
+ static Constant *getAnd(Constant *C1, Constant *C2);
+ static Constant *getOr(Constant *C1, Constant *C2);
+ static Constant *getXor(Constant *C1, Constant *C2);
+ static Constant *getShl(Constant *C1, Constant *C2,
+ bool HasNUW = false, bool HasNSW = false);
+ static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false);
+ static Constant *getTrunc (Constant *C, Type *Ty);
+ static Constant *getSExt (Constant *C, Type *Ty);
+ static Constant *getZExt (Constant *C, Type *Ty);
+ static Constant *getFPTrunc (Constant *C, Type *Ty);
+ static Constant *getFPExtend(Constant *C, Type *Ty);
+ static Constant *getUIToFP (Constant *C, Type *Ty);
+ static Constant *getSIToFP (Constant *C, Type *Ty);
+ static Constant *getFPToUI (Constant *C, Type *Ty);
+ static Constant *getFPToSI (Constant *C, Type *Ty);
+ static Constant *getPtrToInt(Constant *C, Type *Ty);
+ static Constant *getIntToPtr(Constant *C, Type *Ty);
+ static Constant *getBitCast (Constant *C, Type *Ty);
+
+ static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); }
+ static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); }
+ static Constant *getNSWAdd(Constant *C1, Constant *C2) {
+ return getAdd(C1, C2, false, true);
+ }
+ static Constant *getNUWAdd(Constant *C1, Constant *C2) {
+ return getAdd(C1, C2, true, false);
+ }
+ static Constant *getNSWSub(Constant *C1, Constant *C2) {
+ return getSub(C1, C2, false, true);
+ }
+ static Constant *getNUWSub(Constant *C1, Constant *C2) {
+ return getSub(C1, C2, true, false);
+ }
+ static Constant *getNSWMul(Constant *C1, Constant *C2) {
+ return getMul(C1, C2, false, true);
+ }
+ static Constant *getNUWMul(Constant *C1, Constant *C2) {
+ return getMul(C1, C2, true, false);
+ }
+ static Constant *getNSWShl(Constant *C1, Constant *C2) {
+ return getShl(C1, C2, false, true);
+ }
+ static Constant *getNUWShl(Constant *C1, Constant *C2) {
+ return getShl(C1, C2, true, false);
+ }
+ static Constant *getExactSDiv(Constant *C1, Constant *C2) {
+ return getSDiv(C1, C2, true);
+ }
+ static Constant *getExactUDiv(Constant *C1, Constant *C2) {
+ return getUDiv(C1, C2, true);
+ }
+ static Constant *getExactAShr(Constant *C1, Constant *C2) {
+ return getAShr(C1, C2, true);
+ }
+ static Constant *getExactLShr(Constant *C1, Constant *C2) {
+ return getLShr(C1, C2, true);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ // @brief Convenience function for getting one of the casting operations
+ // using a CastOps opcode.
+ static Constant *getCast(
+ unsigned ops, ///< The opcode for the conversion
+ Constant *C, ///< The constant to be converted
+ Type *Ty ///< The type to which the constant is converted
+ );
+
+ // @brief Create a ZExt or BitCast cast constant expression
+ static Constant *getZExtOrBitCast(
+ Constant *C, ///< The constant to zext or bitcast
+ Type *Ty ///< The type to zext or bitcast C to
+ );
+
+ // @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
+ );
+
+ // @brief Create a Trunc or BitCast cast constant expression
+ static Constant *getTruncOrBitCast(
+ Constant *C, ///< The constant to trunc or bitcast
+ Type *Ty ///< The type to trunc or bitcast C to
+ );
+
+ /// @brief Create a BitCast or a PtrToInt cast constant expression
+ static Constant *getPointerCast(
+ Constant *C, ///< The pointer value to be casted (operand 0)
+ Type *Ty ///< The type to which cast should be made
+ );
+
+ /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
+ static Constant *getIntegerCast(
+ 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
+ Type *Ty ///< The integer type to cast to
+ );
+
+ /// @brief Return true if this is a convert constant expression
+ bool isCast() const;
+
+ /// @brief Return true if this is a compare constant expression
+ bool isCompare() const;
+
+ /// @brief Return true if this is an insertvalue or extractvalue expression,
+ /// and the getIndices() method may be used.
+ bool hasIndices() const;
+
+ /// @brief Return true if this is a getelementptr expression and all
+ /// the index operands are compile-time known integers within the
+ /// corresponding notional static array extents. Note that this is
+ /// not equivalant to, a subset of, or a superset of the "inbounds"
+ /// property.
+ bool isGEPWithNoNotionalOverIndexing() const;
+
+ /// Select constant expr
+ ///
+ static Constant *getSelect(Constant *C, Constant *V1, Constant *V2);
+
+ /// get - Return a binary or shift operator constant expression,
+ /// folding if possible.
+ ///
+ static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
+ unsigned Flags = 0);
+
+ /// @brief Return an ICmp or FCmp comparison operator constant expression.
+ static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
+
+ /// get* - Return some common constants without having to
+ /// specify the full Instruction::OPCODE identifier.
+ ///
+ static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
+ static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
+
+ /// Getelementptr form. Value* is only accepted for convenience;
+ /// all elements must be Constant's.
+ ///
+ static Constant *getGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList,
+ bool InBounds = false) {
+ return getGetElementPtr(C, makeArrayRef((Value * const *)IdxList.data(),
+ IdxList.size()),
+ InBounds);
+ }
+ static Constant *getGetElementPtr(Constant *C,
+ Constant *Idx,
+ bool InBounds = false) {
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ return getGetElementPtr(C, cast<Value>(Idx), InBounds);
+ }
+ static Constant *getGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList,
+ bool InBounds = false);
+
+ /// Create an "inbounds" getelementptr. See the documentation for the
+ /// "inbounds" flag in LangRef.html for details.
+ static Constant *getInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) {
+ return getGetElementPtr(C, IdxList, true);
+ }
+ static Constant *getInBoundsGetElementPtr(Constant *C,
+ Constant *Idx) {
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ return getGetElementPtr(C, Idx, true);
+ }
+ static Constant *getInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) {
+ return getGetElementPtr(C, IdxList, true);
+ }
+
+ static Constant *getExtractElement(Constant *Vec, Constant *Idx);
+ static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
+ static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
+ static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
+ static Constant *getInsertValue(Constant *Agg, Constant *Val,
+ ArrayRef<unsigned> Idxs);
+
+ /// getOpcode - Return the opcode at the root of this constant expression
+ unsigned getOpcode() const { return getSubclassDataFromValue(); }
+
+ /// getPredicate - Return the ICMP or FCMP predicate value. Assert if this is
+ /// not an ICMP or FCMP constant expression.
+ unsigned getPredicate() const;
+
+ /// getIndices - Assert that this is an insertvalue or exactvalue
+ /// expression and return the list of indices.
+ ArrayRef<unsigned> getIndices() const;
+
+ /// getOpcodeName - Return a string representation for an opcode.
+ const char *getOpcodeName() const;
+
+ /// 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.
+ Constant *getWithOperands(ArrayRef<Constant*> Ops) const {
+ return getWithOperands(Ops, getType());
+ }
+
+ /// getWithOperands - This returns the current constant expression with the
+ /// operands replaced with the specified values and with the specified result
+ /// type. The specified array must have the same number of operands as our
+ /// current one.
+ Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const;
+
+ 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.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<ConstantExpr> :
+ public VariadicOperandTraits<ConstantExpr, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant)
+
+//===----------------------------------------------------------------------===//
+/// UndefValue - 'undef' values are things that do not have specified contents.
+/// These are used for a variety of purposes, including global variable
+/// initializers and operands to instructions. 'undef' values can occur with
+/// any first-class type.
+///
+/// Undef values aren't exactly constants; if they have multiple uses, they
+/// can appear to have different bit patterns at each use. See
+/// LangRef.html#undefvalues for details.
+///
+class UndefValue : public Constant {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ UndefValue(const UndefValue &); // DO NOT IMPLEMENT
+protected:
+ explicit UndefValue(Type *T) : Constant(T, UndefValueVal, 0, 0) {}
+protected:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+public:
+ /// get() - Static factory methods - Return an 'undef' object of the specified
+ /// type.
+ ///
+ static UndefValue *get(Type *T);
+
+ /// 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;
+
+ /// getElementValue - Return an undef of the right value for the specified GEP
+ /// index.
+ UndefValue *getElementValue(unsigned Idx) const;
+
+ 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;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/DIContext.h b/contrib/llvm/include/llvm/DebugInfo/DIContext.h
new file mode 100644
index 000000000000..64f80c506504
--- /dev/null
+++ b/contrib/llvm/include/llvm/DebugInfo/DIContext.h
@@ -0,0 +1,68 @@
+//===-- DIContext.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 defines DIContext, an abstract data structure that holds
+// debug information data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DICONTEXT_H
+#define LLVM_DEBUGINFO_DICONTEXT_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+
+namespace llvm {
+
+class raw_ostream;
+
+/// DILineInfo - a format-neutral container for source line information.
+class DILineInfo {
+ const char *FileName;
+ uint32_t Line;
+ uint32_t Column;
+public:
+ DILineInfo() : FileName("<invalid>"), Line(0), Column(0) {}
+ DILineInfo(const char *fileName, uint32_t line, uint32_t column)
+ : FileName(fileName), Line(line), Column(column) {}
+
+ const char *getFileName() const { return FileName; }
+ uint32_t getLine() const { return Line; }
+ uint32_t getColumn() const { return Column; }
+
+ bool operator==(const DILineInfo &RHS) const {
+ return Line == RHS.Line && Column == RHS.Column &&
+ std::strcmp(FileName, RHS.FileName) == 0;
+ }
+ bool operator!=(const DILineInfo &RHS) const {
+ return !(*this == RHS);
+ }
+};
+
+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());
+
+ virtual void dump(raw_ostream &OS) = 0;
+
+ virtual DILineInfo getLineInfoForAddress(uint64_t address) = 0;
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DefaultPasses.h b/contrib/llvm/include/llvm/DefaultPasses.h
new file mode 100644
index 000000000000..929569d543d9
--- /dev/null
+++ b/contrib/llvm/include/llvm/DefaultPasses.h
@@ -0,0 +1,168 @@
+//===- 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/contrib/llvm/include/llvm/DerivedTypes.h b/contrib/llvm/include/llvm/DerivedTypes.h
new file mode 100644
index 000000000000..da5ad27b1f1c
--- /dev/null
+++ b/contrib/llvm/include/llvm/DerivedTypes.h
@@ -0,0 +1,462 @@
+//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations of classes that represent "derived
+// types". These are things like "arrays of x" or "structure of x, y, z" or
+// "function returning x taking (y,z) as parameters", etc...
+//
+// The implementations of these classes live in the Type.cpp file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DERIVED_TYPES_H
+#define LLVM_DERIVED_TYPES_H
+
+#include "llvm/Type.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class Value;
+class APInt;
+class LLVMContext;
+template<typename T> class ArrayRef;
+class StringRef;
+
+/// Class to represent integer types. Note that this class is also used to
+/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
+/// Int64Ty.
+/// @brief Integer representation type
+class IntegerType : public Type {
+ friend class LLVMContextImpl;
+
+protected:
+ explicit IntegerType(LLVMContext &C, unsigned NumBits) : Type(C, IntegerTyID){
+ setSubclassData(NumBits);
+ }
+public:
+ /// This enum is just used to hold constants we need for IntegerType.
+ enum {
+ MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified
+ MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
+ ///< Note that bit width is stored in the Type classes SubclassData field
+ ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
+ };
+
+ /// This static method is the primary way of constructing an IntegerType.
+ /// If an IntegerType with the same NumBits value was previously instantiated,
+ /// that instance will be returned. Otherwise a new one will be created. Only
+ /// one instance with a given NumBits value is ever created.
+ /// @brief Get or create an IntegerType instance.
+ static IntegerType *get(LLVMContext &C, unsigned NumBits);
+
+ /// @brief Get the number of bits in this IntegerType
+ unsigned getBitWidth() const { return getSubclassData(); }
+
+ /// getBitMask - Return a bitmask with ones set for all of the bits
+ /// that can be set by an unsigned version of this type. This is 0xFF for
+ /// i8, 0xFFFF for i16, etc.
+ uint64_t getBitMask() const {
+ return ~uint64_t(0UL) >> (64-getBitWidth());
+ }
+
+ /// getSignBit - Return a uint64_t with just the most significant bit set (the
+ /// sign bit, if the value is treated as a signed number).
+ uint64_t getSignBit() const {
+ return 1ULL << (getBitWidth()-1);
+ }
+
+ /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc.
+ /// @returns a bit mask with ones set for all the bits of this type.
+ /// @brief Get a bit mask for this type.
+ APInt getMask() const;
+
+ /// This method determines if the width of this IntegerType is a power-of-2
+ /// in terms of 8 bit bytes.
+ /// @returns true if this is a power-of-2 byte width.
+ /// @brief Is this a power-of-2 byte-width IntegerType ?
+ 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;
+ }
+};
+
+
+/// 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(Type *Result, ArrayRef<Type*> Params, bool IsVarArgs);
+
+public:
+ /// FunctionType::get - This static method is the primary way of constructing
+ /// a FunctionType.
+ ///
+ static FunctionType *get(Type *Result,
+ ArrayRef<Type*> Params, bool isVarArg);
+
+ /// FunctionType::get - Create a FunctionType taking no parameters.
+ ///
+ static FunctionType *get(Type *Result, bool isVarArg);
+
+ /// isValidReturnType - Return true if the specified type is valid as a return
+ /// type.
+ static bool isValidReturnType(Type *RetTy);
+
+ /// isValidArgumentType - Return true if the specified type is valid as an
+ /// argument type.
+ static bool isValidArgumentType(Type *ArgTy);
+
+ bool isVarArg() const { return getSubclassData(); }
+ Type *getReturnType() const { return ContainedTys[0]; }
+
+ typedef Type::subtype_iterator param_iterator;
+ param_iterator param_begin() const { return ContainedTys + 1; }
+ param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
+
+ // Parameter type accessors.
+ Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
+
+ /// getNumParams - Return the number of fixed parameters this function type
+ /// requires. This does not consider varargs.
+ ///
+ 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;
+ }
+};
+
+
+/// CompositeType - Common super class of ArrayType, StructType, PointerType
+/// and VectorType.
+class CompositeType : public Type {
+protected:
+ explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) { }
+public:
+
+ /// getTypeAtIndex - Given an index value into the type, return the type of
+ /// the element.
+ ///
+ Type *getTypeAtIndex(const Value *V);
+ Type *getTypeAtIndex(unsigned Idx);
+ bool indexValid(const Value *V) const;
+ 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 ||
+ T->getTypeID() == PointerTyID ||
+ T->getTypeID() == VectorTyID;
+ }
+};
+
+
+/// StructType - Class to represent struct types. There are two different kinds
+/// of struct types: Literal structs and Identified structs.
+///
+/// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must
+/// always have a body when created. You can get one of these by using one of
+/// the StructType::get() forms.
+///
+/// Identified structs (e.g. %foo or %42) may optionally have a name and are not
+/// uniqued. The names for identified structs are managed at the LLVMContext
+/// level, so there can only be a single identified struct with a given name in
+/// a particular LLVMContext. Identified structs may also optionally be opaque
+/// (have no body specified). You get one of these by using one of the
+/// StructType::create() forms.
+///
+/// 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
+/// generator for a target expects).
+///
+class StructType : public CompositeType {
+ StructType(const StructType &); // Do not implement
+ const StructType &operator=(const StructType &); // Do not implement
+ StructType(LLVMContext &C)
+ : CompositeType(C, StructTyID), SymbolTableEntry(0) {}
+ enum {
+ // This is the contents of the SubClassData field.
+ SCDB_HasBody = 1,
+ SCDB_Packed = 2,
+ SCDB_IsLiteral = 4,
+ SCDB_IsSized = 8
+ };
+
+ /// SymbolTableEntry - For a named struct that actually has a name, this is a
+ /// pointer to the symbol table entry (maintained by LLVMContext) for the
+ /// struct. This is null if the type is an literal struct or if it is
+ /// a identified type that has an empty name.
+ ///
+ void *SymbolTableEntry;
+public:
+ ~StructType() {
+ delete [] ContainedTys; // Delete the body.
+ }
+
+ /// StructType::create - This creates an identified struct.
+ static StructType *create(LLVMContext &Context, StringRef Name);
+ static StructType *create(LLVMContext &Context);
+
+ static StructType *create(ArrayRef<Type*> Elements,
+ StringRef Name,
+ bool isPacked = false);
+ static StructType *create(ArrayRef<Type*> Elements);
+ static StructType *create(LLVMContext &Context,
+ ArrayRef<Type*> Elements,
+ StringRef Name,
+ bool isPacked = false);
+ static StructType *create(LLVMContext &Context, ArrayRef<Type*> Elements);
+ static StructType *create(StringRef Name, Type *elt1, ...) END_WITH_NULL;
+
+ /// StructType::get - This static method is the primary way to create a
+ /// literal StructType.
+ static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
+ bool isPacked = false);
+
+ /// StructType::get - Create an empty structure type.
+ ///
+ static StructType *get(LLVMContext &Context, bool isPacked = false);
+
+ /// StructType::get - This static method is a convenience method for creating
+ /// structure types by specifying the elements as arguments. Note that this
+ /// method always returns a non-packed struct, and requires at least one
+ /// element type.
+ static StructType *get(Type *elt1, ...) END_WITH_NULL;
+
+ bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
+
+ /// isLiteral - Return true if this type is uniqued by structural
+ /// equivalence, false if it is a struct definition.
+ bool isLiteral() const { return (getSubclassData() & SCDB_IsLiteral) != 0; }
+
+ /// isOpaque - Return true if this is a type with an identity that has no body
+ /// specified yet. These prints as 'opaque' in .ll files.
+ bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; }
+
+ /// isSized - Return true if this is a sized type.
+ bool isSized() const;
+
+ /// hasName - Return true if this is a named struct that has a non-empty name.
+ bool hasName() const { return SymbolTableEntry != 0; }
+
+ /// getName - Return the name for this struct type if it has an identity.
+ /// This may return an empty string for an unnamed struct type. Do not call
+ /// this on an literal type.
+ StringRef getName() const;
+
+ /// setName - Change the name of this type to the specified name, or to a name
+ /// with a suffix if there is a collision. Do not call this on an literal
+ /// type.
+ void setName(StringRef Name);
+
+ /// setBody - Specify a body for an opaque identified type.
+ void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
+ void setBody(Type *elt1, ...) END_WITH_NULL;
+
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(Type *ElemTy);
+
+
+ // Iterator access to the elements.
+ typedef Type::subtype_iterator element_iterator;
+ element_iterator element_begin() const { return ContainedTys; }
+ element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
+
+ /// isLayoutIdentical - Return true if this is layout identical to the
+ /// specified struct.
+ bool isLayoutIdentical(StructType *Other) const;
+
+ // Random access to the elements
+ unsigned getNumElements() const { return NumContainedTys; }
+ Type *getElementType(unsigned N) const {
+ assert(N < NumContainedTys && "Element number out of range!");
+ return ContainedTys[N];
+ }
+
+ // 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;
+ }
+};
+
+/// SequentialType - This is the superclass of the array, pointer and vector
+/// type classes. All of these represent "arrays" in memory. The array type
+/// represents a specifically sized array, pointer types are unsized/unknown
+/// size arrays, vector types represent specifically sized arrays that
+/// allow for use of SIMD instructions. SequentialType holds the common
+/// features of all, which stem from the fact that all three lay their
+/// components out in memory identically.
+///
+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!
+
+protected:
+ SequentialType(TypeID TID, Type *ElType)
+ : CompositeType(ElType->getContext(), TID), ContainedType(ElType) {
+ ContainedTys = &ContainedType;
+ NumContainedTys = 1;
+ }
+
+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 ||
+ T->getTypeID() == VectorTyID;
+ }
+};
+
+
+/// ArrayType - Class to represent array types.
+///
+class ArrayType : public SequentialType {
+ uint64_t NumElements;
+
+ ArrayType(const ArrayType &); // Do not implement
+ const ArrayType &operator=(const ArrayType &); // Do not implement
+ ArrayType(Type *ElType, uint64_t NumEl);
+public:
+ /// ArrayType::get - This static method is the primary way to construct an
+ /// ArrayType
+ ///
+ static ArrayType *get(Type *ElementType, uint64_t NumElements);
+
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(Type *ElemTy);
+
+ 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;
+ }
+};
+
+/// VectorType - Class to represent vector types.
+///
+class VectorType : public SequentialType {
+ unsigned NumElements;
+
+ VectorType(const VectorType &); // Do not implement
+ const VectorType &operator=(const VectorType &); // Do not implement
+ VectorType(Type *ElType, unsigned NumEl);
+public:
+ /// VectorType::get - This static method is the primary way to construct an
+ /// VectorType.
+ ///
+ static VectorType *get(Type *ElementType, unsigned NumElements);
+
+ /// VectorType::getInteger - This static method gets a VectorType with the
+ /// same number of elements as the input type, and the element type is an
+ /// integer type of the same width as the input element type.
+ ///
+ static VectorType *getInteger(VectorType *VTy) {
+ unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+ assert(EltBits && "Element size must be of a non-zero size");
+ Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
+ return VectorType::get(EltTy, VTy->getNumElements());
+ }
+
+ /// VectorType::getExtendedElementVectorType - This static method is like
+ /// getInteger except that the element types are twice as wide as the
+ /// elements in the input type.
+ ///
+ static VectorType *getExtendedElementVectorType(VectorType *VTy) {
+ unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+ Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
+ return VectorType::get(EltTy, VTy->getNumElements());
+ }
+
+ /// VectorType::getTruncatedElementVectorType - This static method is like
+ /// getInteger except that the element types are half as wide as the
+ /// elements in the input type.
+ ///
+ static VectorType *getTruncatedElementVectorType(VectorType *VTy) {
+ unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+ assert((EltBits & 1) == 0 &&
+ "Cannot truncate vector element with odd bit-width");
+ Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
+ return VectorType::get(EltTy, VTy->getNumElements());
+ }
+
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(Type *ElemTy);
+
+ /// @brief Return the number of elements in the Vector type.
+ unsigned getNumElements() const { return NumElements; }
+
+ /// @brief Return the number of bits in the Vector type.
+ /// Returns zero when the vector is a vector of pointers.
+ unsigned getBitWidth() const {
+ return NumElements * getElementType()->getPrimitiveSizeInBits();
+ }
+
+ // 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;
+ }
+};
+
+
+/// PointerType - Class to represent pointers.
+///
+class PointerType : public SequentialType {
+ PointerType(const PointerType &); // Do not implement
+ const PointerType &operator=(const PointerType &); // Do not implement
+ explicit PointerType(Type *ElType, unsigned AddrSpace);
+public:
+ /// PointerType::get - This constructs a pointer to an object of the specified
+ /// type in a numbered address space.
+ static PointerType *get(Type *ElementType, unsigned AddressSpace);
+
+ /// PointerType::getUnqual - This constructs a pointer to an object of the
+ /// specified type in the generic address space (address space zero).
+ static PointerType *getUnqual(Type *ElementType) {
+ return PointerType::get(ElementType, 0);
+ }
+
+ /// isValidElementType - Return true if the specified type is valid as a
+ /// element type.
+ static bool isValidElementType(Type *ElemTy);
+
+ /// @brief Return the address space of the Pointer type.
+ 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;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
new file mode 100644
index 000000000000..e920e98a0bf6
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -0,0 +1,623 @@
+//===- ExecutionEngine.h - Abstract Execution Engine Interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the abstract interface that implements execution support
+// for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_H
+#define LLVM_EXECUTION_ENGINE_H
+
+#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/ValueMap.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ValueHandle.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include <vector>
+#include <map>
+#include <string>
+
+namespace llvm {
+
+struct GenericValue;
+class Constant;
+class ExecutionEngine;
+class Function;
+class GlobalVariable;
+class GlobalValue;
+class JITEventListener;
+class JITMemoryManager;
+class MachineCodeInfo;
+class Module;
+class MutexGuard;
+class TargetData;
+class Triple;
+class Type;
+
+/// \brief Helper class for helping synchronize access to the global address map
+/// table.
+class ExecutionEngineState {
+public:
+ struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> {
+ typedef ExecutionEngineState *ExtraData;
+ static sys::Mutex *getMutex(ExecutionEngineState *EES);
+ static void onDelete(ExecutionEngineState *EES, const GlobalValue *Old);
+ static void onRAUW(ExecutionEngineState *, const GlobalValue *,
+ const GlobalValue *);
+ };
+
+ typedef ValueMap<const GlobalValue *, void *, AddressMapConfig>
+ GlobalAddressMapTy;
+
+private:
+ ExecutionEngine &EE;
+
+ /// GlobalAddressMap - A mapping between LLVM global values and their
+ /// actualized version...
+ GlobalAddressMapTy GlobalAddressMap;
+
+ /// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap,
+ /// used to convert raw addresses into the LLVM global value that is emitted
+ /// at the address. This map is not computed unless getGlobalValueAtAddress
+ /// is called at some point.
+ std::map<void *, AssertingVH<const GlobalValue> > GlobalAddressReverseMap;
+
+public:
+ ExecutionEngineState(ExecutionEngine &EE);
+
+ GlobalAddressMapTy &getGlobalAddressMap(const MutexGuard &) {
+ return GlobalAddressMap;
+ }
+
+ std::map<void*, AssertingVH<const GlobalValue> > &
+ getGlobalAddressReverseMap(const MutexGuard &) {
+ return GlobalAddressReverseMap;
+ }
+
+ /// \brief Erase an entry from the mapping table.
+ ///
+ /// \returns The address that \arg ToUnmap was happed to.
+ void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap);
+};
+
+/// \brief Abstract interface for implementation execution of LLVM modules,
+/// designed to support both interpreter and just-in-time (JIT) compiler
+/// implementations.
+class ExecutionEngine {
+ /// The state object holding the global address mapping, which must be
+ /// accessed synchronously.
+ //
+ // FIXME: There is no particular need the entire map needs to be
+ // synchronized. Wouldn't a reader-writer design be better here?
+ ExecutionEngineState EEState;
+
+ /// The target data for the platform for which execution is being performed.
+ const TargetData *TD;
+
+ /// Whether lazy JIT compilation is enabled.
+ bool CompilingLazily;
+
+ /// Whether JIT compilation of external global variables is allowed.
+ bool GVCompilationDisabled;
+
+ /// Whether the JIT should perform lookups of external symbols (e.g.,
+ /// using dlsym).
+ bool SymbolSearchingDisabled;
+
+ friend class EngineBuilder; // To allow access to JITCtor and InterpCtor.
+
+protected:
+ /// The list of Modules that we are JIT'ing from. We use a SmallVector to
+ /// optimize for the case where there is only one module.
+ SmallVector<Module*, 1> Modules;
+
+ void setTargetData(const TargetData *td) { TD = td; }
+
+ /// getMemoryforGV - Allocate memory for a global variable.
+ virtual char *getMemoryForGV(const GlobalVariable *GV);
+
+ // To avoid having libexecutionengine depend on the JIT and interpreter
+ // libraries, the execution engine implementations set these functions to ctor
+ // pointers at startup time if they are linked in.
+ static ExecutionEngine *(*JITCtor)(
+ Module *M,
+ std::string *ErrorStr,
+ JITMemoryManager *JMM,
+ bool GVsWithCode,
+ TargetMachine *TM);
+ static ExecutionEngine *(*MCJITCtor)(
+ Module *M,
+ std::string *ErrorStr,
+ JITMemoryManager *JMM,
+ bool GVsWithCode,
+ TargetMachine *TM);
+ static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr);
+
+ /// LazyFunctionCreator - If an unknown function is needed, this function
+ /// pointer is invoked to create it. If this returns null, the JIT will
+ /// abort.
+ void *(*LazyFunctionCreator)(const std::string &);
+
+ /// ExceptionTableRegister - If Exception Handling is set, the JIT will
+ /// register dwarf tables with this function.
+ typedef void (*EERegisterFn)(void*);
+ EERegisterFn ExceptionTableRegister;
+ EERegisterFn ExceptionTableDeregister;
+ /// This maps functions to their exception tables frames.
+ DenseMap<const Function*, void*> AllExceptionTables;
+
+
+public:
+ /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and
+ /// JITEmitter classes. It must be held while changing the internal state of
+ /// any of those classes.
+ sys::Mutex lock;
+
+ //===--------------------------------------------------------------------===//
+ // ExecutionEngine Startup
+ //===--------------------------------------------------------------------===//
+
+ virtual ~ExecutionEngine();
+
+ /// create - This is the factory method for creating an execution engine which
+ /// is appropriate for the current machine. This takes ownership of the
+ /// module.
+ ///
+ /// \param GVsWithCode - Allocating globals with code breaks
+ /// freeMachineCodeForFunction and is probably unsafe and bad for performance.
+ /// However, we have clients who depend on this behavior, so we must support
+ /// it. Eventually, when we're willing to break some backwards compatibility,
+ /// this flag should be flipped to false, so that by default
+ /// freeMachineCodeForFunction works.
+ static ExecutionEngine *create(Module *M,
+ bool ForceInterpreter = false,
+ std::string *ErrorStr = 0,
+ CodeGenOpt::Level OptLevel =
+ CodeGenOpt::Default,
+ bool GVsWithCode = true);
+
+ /// createJIT - This is the factory method for creating a JIT for the current
+ /// machine, it does not fall back to the interpreter. This takes ownership
+ /// of the Module and JITMemoryManager if successful.
+ ///
+ /// Clients should make sure to initialize targets prior to calling this
+ /// function.
+ static ExecutionEngine *createJIT(Module *M,
+ std::string *ErrorStr = 0,
+ JITMemoryManager *JMM = 0,
+ CodeGenOpt::Level OptLevel =
+ CodeGenOpt::Default,
+ bool GVsWithCode = true,
+ Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CMM =
+ CodeModel::JITDefault);
+
+ /// addModule - Add a Module to the list of modules that we can JIT from.
+ /// Note that this takes ownership of the Module: when the ExecutionEngine is
+ /// destroyed, it destroys the Module as well.
+ virtual void addModule(Module *M) {
+ Modules.push_back(M);
+ }
+
+ //===--------------------------------------------------------------------===//
+
+ const TargetData *getTargetData() const { return TD; }
+
+ /// removeModule - Remove a Module from the list of modules. Returns true if
+ /// M is found.
+ virtual bool removeModule(Module *M);
+
+ /// FindFunctionNamed - Search all of the active modules to find the one that
+ /// defines FnName. This is very slow operation and shouldn't be used for
+ /// general code.
+ Function *FindFunctionNamed(const char *FnName);
+
+ /// runFunction - Execute the specified function with the specified arguments,
+ /// and return the result.
+ virtual GenericValue runFunction(Function *F,
+ const std::vector<GenericValue> &ArgValues) = 0;
+
+ /// getPointerToNamedFunction - This method returns the address of the
+ /// specified function by using the dlsym function call. 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;
+
+ /// mapSectionAddress - 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.
+ virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) {
+ llvm_unreachable("Re-mapping of section addresses not supported with this "
+ "EE!");
+ }
+
+ /// runStaticConstructorsDestructors - This method is used to execute all of
+ /// the static constructors or destructors for a program.
+ ///
+ /// \param isDtors - Run the destructors instead of constructors.
+ void runStaticConstructorsDestructors(bool isDtors);
+
+ /// runStaticConstructorsDestructors - This method is used to execute all of
+ /// the static constructors or destructors for a particular module.
+ ///
+ /// \param isDtors - Run the destructors instead of constructors.
+ void runStaticConstructorsDestructors(Module *module, bool isDtors);
+
+
+ /// runFunctionAsMain - This is a helper function which wraps runFunction to
+ /// handle the common task of starting up main with the specified argc, argv,
+ /// and envp parameters.
+ int runFunctionAsMain(Function *Fn, const std::vector<std::string> &argv,
+ const char * const * envp);
+
+
+ /// addGlobalMapping - Tell the execution engine that the specified global is
+ /// at the specified location. This is used internally as functions are JIT'd
+ /// and as global variables are laid out in memory. It can and should also be
+ /// used by clients of the EE that want to have an LLVM global overlay
+ /// existing data in memory. Mappings are automatically removed when their
+ /// GlobalValue is destroyed.
+ void addGlobalMapping(const GlobalValue *GV, void *Addr);
+
+ /// clearAllGlobalMappings - Clear all global mappings and start over again,
+ /// for use in dynamic compilation scenarios to move globals.
+ void clearAllGlobalMappings();
+
+ /// clearGlobalMappingsFromModule - Clear all global mappings that came from a
+ /// particular module, because it has been removed from the JIT.
+ void clearGlobalMappingsFromModule(Module *M);
+
+ /// updateGlobalMapping - Replace an existing mapping for GV with a new
+ /// address. This updates both maps as required. If "Addr" is null, the
+ /// entry for the global is removed from the mappings. This returns the old
+ /// value of the pointer, or null if it was not in the map.
+ void *updateGlobalMapping(const GlobalValue *GV, void *Addr);
+
+ /// getPointerToGlobalIfAvailable - This returns the address of the specified
+ /// global value if it is has already been codegen'd, otherwise it returns
+ /// null.
+ void *getPointerToGlobalIfAvailable(const GlobalValue *GV);
+
+ /// getPointerToGlobal - This returns the address of the specified global
+ /// value. This may involve code generation if it's a function.
+ void *getPointerToGlobal(const GlobalValue *GV);
+
+ /// getPointerToFunction - The different EE's represent function bodies in
+ /// different ways. They should each implement this to say what a function
+ /// pointer should look like. When F is destroyed, the ExecutionEngine will
+ /// remove its global mapping and free any machine code. Be sure no threads
+ /// are running inside F when that happens.
+ virtual void *getPointerToFunction(Function *F) = 0;
+
+ /// getPointerToBasicBlock - The different EE's represent basic blocks in
+ /// different ways. Return the representation for a blockaddress of the
+ /// specified block.
+ virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
+
+ /// getPointerToFunctionOrStub - If the specified function has been
+ /// code-gen'd, return a pointer to the function. If not, compile it, or use
+ /// a stub to implement lazy compilation if available. See
+ /// getPointerToFunction for the requirements on destroying F.
+ virtual void *getPointerToFunctionOrStub(Function *F) {
+ // Default implementation, just codegen the function.
+ return getPointerToFunction(F);
+ }
+
+ // The JIT overrides a version that actually does this.
+ virtual void runJITOnFunction(Function *, MachineCodeInfo * = 0) { }
+
+ /// getGlobalValueAtAddress - Return the LLVM global value object that starts
+ /// at the specified address.
+ ///
+ const GlobalValue *getGlobalValueAtAddress(void *Addr);
+
+ /// StoreValueToMemory - Stores the data in Val of type Ty at address Ptr.
+ /// Ptr is the address of the memory at which to store Val, cast to
+ /// GenericValue *. It is not a pointer to a GenericValue containing the
+ /// address at which to store Val.
+ void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr,
+ Type *Ty);
+
+ void InitializeMemory(const Constant *Init, void *Addr);
+
+ /// recompileAndRelinkFunction - This method is used to force a function which
+ /// has already been compiled to be compiled again, possibly after it has been
+ /// modified. Then the entry to the old copy is overwritten with a branch to
+ /// the new copy. If there was no old copy, this acts just like
+ /// VM::getPointerToFunction().
+ virtual void *recompileAndRelinkFunction(Function *F) = 0;
+
+ /// freeMachineCodeForFunction - Release memory in the ExecutionEngine
+ /// corresponding to the machine code emitted to execute this function, useful
+ /// for garbage-collecting generated code.
+ virtual void freeMachineCodeForFunction(Function *F) = 0;
+
+ /// getOrEmitGlobalVariable - Return the address of the specified global
+ /// variable, possibly emitting it to memory if needed. This is used by the
+ /// Emitter.
+ virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) {
+ return getPointerToGlobal((GlobalValue*)GV);
+ }
+
+ /// Registers a listener to be called back on various events within
+ /// the JIT. See JITEventListener.h for more details. Does not
+ /// take ownership of the argument. The argument may be NULL, in
+ /// which case these functions do nothing.
+ virtual void RegisterJITEventListener(JITEventListener *) {}
+ virtual void UnregisterJITEventListener(JITEventListener *) {}
+
+ /// DisableLazyCompilation - When lazy compilation is off (the default), the
+ /// JIT will eagerly compile every function reachable from the argument to
+ /// getPointerToFunction. If lazy compilation is turned on, the JIT will only
+ /// compile the one function and emit stubs to compile the rest when they're
+ /// first called. If lazy compilation is turned off again while some lazy
+ /// stubs are still around, and one of those stubs is called, the program will
+ /// abort.
+ ///
+ /// In order to safely compile lazily in a threaded program, the user must
+ /// ensure that 1) only one thread at a time can call any particular lazy
+ /// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock
+ /// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a
+ /// lazy stub. See http://llvm.org/PR5184 for details.
+ void DisableLazyCompilation(bool Disabled = true) {
+ CompilingLazily = !Disabled;
+ }
+ bool isCompilingLazily() const {
+ return CompilingLazily;
+ }
+ // Deprecated in favor of isCompilingLazily (to reduce double-negatives).
+ // Remove this in LLVM 2.8.
+ bool isLazyCompilationDisabled() const {
+ return !CompilingLazily;
+ }
+
+ /// DisableGVCompilation - If called, the JIT will abort if it's asked to
+ /// allocate space and populate a GlobalVariable that is not internal to
+ /// the module.
+ void DisableGVCompilation(bool Disabled = true) {
+ GVCompilationDisabled = Disabled;
+ }
+ bool isGVCompilationDisabled() const {
+ return GVCompilationDisabled;
+ }
+
+ /// DisableSymbolSearching - If called, the JIT will not try to lookup unknown
+ /// symbols with dlsym. A client can still use InstallLazyFunctionCreator to
+ /// resolve symbols in a custom way.
+ void DisableSymbolSearching(bool Disabled = true) {
+ SymbolSearchingDisabled = Disabled;
+ }
+ bool isSymbolSearchingDisabled() const {
+ return SymbolSearchingDisabled;
+ }
+
+ /// InstallLazyFunctionCreator - If an unknown function is needed, the
+ /// specified function pointer is invoked to create it. If it returns null,
+ /// the JIT will abort.
+ void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
+ LazyFunctionCreator = P;
+ }
+
+ /// InstallExceptionTableRegister - The JIT will use the given function
+ /// to register the exception tables it generates.
+ void InstallExceptionTableRegister(EERegisterFn F) {
+ ExceptionTableRegister = F;
+ }
+ void InstallExceptionTableDeregister(EERegisterFn F) {
+ ExceptionTableDeregister = F;
+ }
+
+ /// RegisterTable - Registers the given pointer as an exception table. It
+ /// uses the ExceptionTableRegister function.
+ void RegisterTable(const Function *fn, void* res) {
+ if (ExceptionTableRegister) {
+ ExceptionTableRegister(res);
+ AllExceptionTables[fn] = res;
+ }
+ }
+
+ /// DeregisterTable - Deregisters the exception frame previously registered
+ /// for the given function.
+ void DeregisterTable(const Function *Fn) {
+ if (ExceptionTableDeregister) {
+ DenseMap<const Function*, void*>::iterator frame =
+ AllExceptionTables.find(Fn);
+ if(frame != AllExceptionTables.end()) {
+ ExceptionTableDeregister(frame->second);
+ AllExceptionTables.erase(frame);
+ }
+ }
+ }
+
+ /// DeregisterAllTables - Deregisters all previously registered pointers to an
+ /// exception tables. It uses the ExceptionTableoDeregister function.
+ void DeregisterAllTables();
+
+protected:
+ explicit ExecutionEngine(Module *M);
+
+ void emitGlobals();
+
+ void EmitGlobalVariable(const GlobalVariable *GV);
+
+ GenericValue getConstantValue(const Constant *C);
+ void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
+ Type *Ty);
+};
+
+namespace EngineKind {
+ // These are actually bitmasks that get or-ed together.
+ enum Kind {
+ JIT = 0x1,
+ Interpreter = 0x2
+ };
+ const static Kind Either = (Kind)(JIT | Interpreter);
+}
+
+/// EngineBuilder - Builder class for ExecutionEngines. Use this by
+/// stack-allocating a builder, chaining the various set* methods, and
+/// terminating it with a .create() call.
+class EngineBuilder {
+private:
+ Module *M;
+ EngineKind::Kind WhichEngine;
+ std::string *ErrorStr;
+ CodeGenOpt::Level OptLevel;
+ JITMemoryManager *JMM;
+ bool AllocateGVsWithCode;
+ TargetOptions Options;
+ Reloc::Model RelocModel;
+ CodeModel::Model CMModel;
+ std::string MArch;
+ std::string MCPU;
+ SmallVector<std::string, 4> MAttrs;
+ bool UseMCJIT;
+
+ /// InitEngine - Does the common initialization of default options.
+ void InitEngine() {
+ WhichEngine = EngineKind::Either;
+ ErrorStr = NULL;
+ OptLevel = CodeGenOpt::Default;
+ JMM = NULL;
+ Options = TargetOptions();
+ AllocateGVsWithCode = false;
+ RelocModel = Reloc::Default;
+ CMModel = CodeModel::JITDefault;
+ UseMCJIT = false;
+ }
+
+public:
+ /// EngineBuilder - Constructor for EngineBuilder. If create() is called and
+ /// is successful, the created engine takes ownership of the module.
+ EngineBuilder(Module *m) : M(m) {
+ InitEngine();
+ }
+
+ /// setEngineKind - Controls whether the user wants the interpreter, the JIT,
+ /// or whichever engine works. This option defaults to EngineKind::Either.
+ EngineBuilder &setEngineKind(EngineKind::Kind w) {
+ WhichEngine = w;
+ return *this;
+ }
+
+ /// setJITMemoryManager - Sets the memory manager to use. This allows
+ /// clients to customize their memory allocation policies. If create() is
+ /// called and is successful, the created engine takes ownership of the
+ /// memory manager. This option defaults to NULL.
+ EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) {
+ JMM = jmm;
+ return *this;
+ }
+
+ /// setErrorStr - Set the error string to write to on error. This option
+ /// defaults to NULL.
+ EngineBuilder &setErrorStr(std::string *e) {
+ ErrorStr = e;
+ return *this;
+ }
+
+ /// setOptLevel - Set the optimization level for the JIT. This option
+ /// defaults to CodeGenOpt::Default.
+ EngineBuilder &setOptLevel(CodeGenOpt::Level l) {
+ OptLevel = l;
+ return *this;
+ }
+
+ /// setTargetOptions - Set the target options that the ExecutionEngine
+ /// target is using. Defaults to TargetOptions().
+ EngineBuilder &setTargetOptions(const TargetOptions &Opts) {
+ Options = Opts;
+ return *this;
+ }
+
+ /// setRelocationModel - Set the relocation model that the ExecutionEngine
+ /// target is using. Defaults to target specific default "Reloc::Default".
+ EngineBuilder &setRelocationModel(Reloc::Model RM) {
+ RelocModel = RM;
+ return *this;
+ }
+
+ /// setCodeModel - Set the CodeModel that the ExecutionEngine target
+ /// data is using. Defaults to target specific default
+ /// "CodeModel::JITDefault".
+ EngineBuilder &setCodeModel(CodeModel::Model M) {
+ CMModel = M;
+ return *this;
+ }
+
+ /// setAllocateGVsWithCode - Sets whether global values should be allocated
+ /// into the same buffer as code. For most applications this should be set
+ /// to false. Allocating globals with code breaks freeMachineCodeForFunction
+ /// and is probably unsafe and bad for performance. However, we have clients
+ /// who depend on this behavior, so we must support it. This option defaults
+ /// to false so that users of the new API can safely use the new memory
+ /// manager and free machine code.
+ EngineBuilder &setAllocateGVsWithCode(bool a) {
+ AllocateGVsWithCode = a;
+ return *this;
+ }
+
+ /// setMArch - Override the architecture set by the Module's triple.
+ EngineBuilder &setMArch(StringRef march) {
+ MArch.assign(march.begin(), march.end());
+ return *this;
+ }
+
+ /// setMCPU - Target a specific cpu type.
+ EngineBuilder &setMCPU(StringRef mcpu) {
+ MCPU.assign(mcpu.begin(), mcpu.end());
+ return *this;
+ }
+
+ /// setUseMCJIT - Set whether the MC-JIT implementation should be used
+ /// (experimental).
+ EngineBuilder &setUseMCJIT(bool Value) {
+ UseMCJIT = Value;
+ return *this;
+ }
+
+ /// setMAttrs - Set cpu-specific attributes.
+ template<typename StringSequence>
+ EngineBuilder &setMAttrs(const StringSequence &mattrs) {
+ MAttrs.clear();
+ MAttrs.append(mattrs.begin(), mattrs.end());
+ return *this;
+ }
+
+ TargetMachine *selectTarget();
+
+ /// selectTarget - Pick a target either via -march or by guessing the native
+ /// arch. Add any CPU features specified via -mcpu or -mattr.
+ TargetMachine *selectTarget(const Triple &TargetTriple,
+ StringRef MArch,
+ StringRef MCPU,
+ const SmallVectorImpl<std::string>& MAttrs);
+
+ ExecutionEngine *create() {
+ return create(selectTarget());
+ }
+
+ ExecutionEngine *create(TargetMachine *TM);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h b/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h
new file mode 100644
index 000000000000..a2fed98c150e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/GenericValue.h
@@ -0,0 +1,44 @@
+//===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The GenericValue class is used to represent an LLVM value of arbitrary type.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef GENERIC_VALUE_H
+#define GENERIC_VALUE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+typedef void* PointerTy;
+class APInt;
+
+struct GenericValue {
+ union {
+ double DoubleVal;
+ float FloatVal;
+ PointerTy PointerVal;
+ struct { unsigned int first; unsigned int second; } UIntPairVal;
+ unsigned char Untyped[8];
+ };
+ APInt IntVal; // also used for long doubles
+
+ GenericValue() : DoubleVal(0.0), IntVal(1,0) {}
+ explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { }
+};
+
+inline GenericValue PTOGV(void *P) { return GenericValue(P); }
+inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; }
+
+} // End llvm namespace
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h b/contrib/llvm/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h
new file mode 100644
index 000000000000..ca873420299c
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/IntelJITEventsWrapper.h
@@ -0,0 +1,102 @@
+//===-- 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/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h b/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h
new file mode 100644
index 000000000000..7425cdbcfda8
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/Interpreter.h
@@ -0,0 +1,38 @@
+//===-- Interpreter.h - Abstract Execution Engine 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 forces the interpreter to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EXECUTION_ENGINE_INTERPRETER_H
+#define EXECUTION_ENGINE_INTERPRETER_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInInterpreter();
+
+namespace {
+ struct ForceInterpreterLinking {
+ ForceInterpreterLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ LLVMLinkInInterpreter();
+ }
+ } ForceInterpreterLinking;
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JIT.h b/contrib/llvm/include/llvm/ExecutionEngine/JIT.h
new file mode 100644
index 000000000000..6013db48ce69
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/JIT.h
@@ -0,0 +1,38 @@
+//===-- JIT.h - Abstract Execution Engine 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 forces the JIT to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_JIT_H
+#define LLVM_EXECUTION_ENGINE_JIT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInJIT();
+
+namespace {
+ struct ForceJITLinking {
+ ForceJITLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ LLVMLinkInJIT();
+ }
+ } ForceJITLinking;
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h b/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h
new file mode 100644
index 000000000000..eea603fcee2c
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/JITEventListener.h
@@ -0,0 +1,116 @@
+//===- JITEventListener.h - Exposes events from JIT compilation -*- 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 JITEventListener interface, which lets users get
+// callbacks when significant events happen during the JIT compilation process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
+#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
+
+#include "llvm/Config/config.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DebugLoc.h"
+
+#include <vector>
+
+namespace llvm {
+class Function;
+class MachineFunction;
+class OProfileWrapper;
+class IntelJITEventsWrapper;
+
+/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
+/// about a generated machine code function.
+struct JITEvent_EmittedFunctionDetails {
+ struct LineStart {
+ /// The address at which the current line changes.
+ uintptr_t Address;
+
+ /// The new location information. These can be translated to DebugLocTuples
+ /// using MF->getDebugLocTuple().
+ DebugLoc Loc;
+ };
+
+ /// The machine function the struct contains information for.
+ const MachineFunction *MF;
+
+ /// The list of line boundary information, sorted by address.
+ std::vector<LineStart> LineStarts;
+};
+
+/// JITEventListener - Abstract interface for use by the JIT to notify clients
+/// about significant events during compilation. For example, to notify
+/// profilers and debuggers that need to know where functions have been emitted.
+///
+/// The default implementation of each method does nothing.
+class JITEventListener {
+public:
+ typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
+
+public:
+ JITEventListener() {}
+ virtual ~JITEventListener();
+
+ /// NotifyFunctionEmitted - Called after a function has been successfully
+ /// emitted to memory. The function still has its MachineFunction attached,
+ /// if you should happen to need that.
+ virtual void NotifyFunctionEmitted(const Function &,
+ void *, size_t,
+ const EmittedFunctionDetails &) {}
+
+ /// NotifyFreeingMachineCode - Called from freeMachineCodeForFunction(), after
+ /// the global mapping is removed, but before the machine code is returned to
+ /// the allocator.
+ ///
+ /// OldPtr is the address of the machine code and will be the same as the Code
+ /// parameter to a previous NotifyFunctionEmitted call. The Function passed
+ /// to NotifyFunctionEmitted may have been destroyed by the time of the
+ /// matching NotifyFreeingMachineCode call.
+ virtual void NotifyFreeingMachineCode(void *) {}
+
+#if LLVM_USE_INTEL_JITEVENTS
+ // Construct an IntelJITEventListener
+ static JITEventListener *createIntelJITEventListener();
+
+ // Construct an IntelJITEventListener with a test Intel JIT API implementation
+ static JITEventListener *createIntelJITEventListener(
+ IntelJITEventsWrapper* AlternativeImpl);
+#else
+ static JITEventListener *createIntelJITEventListener() { return 0; }
+
+ static JITEventListener *createIntelJITEventListener(
+ IntelJITEventsWrapper* AlternativeImpl) {
+ return 0;
+ }
+#endif // USE_INTEL_JITEVENTS
+
+#if LLVM_USE_OPROFILE
+ // Construct an OProfileJITEventListener
+ static JITEventListener *createOProfileJITEventListener();
+
+ // Construct an OProfileJITEventListener with a test opagent implementation
+ static JITEventListener *createOProfileJITEventListener(
+ OProfileWrapper* AlternativeImpl);
+#else
+
+ static JITEventListener *createOProfileJITEventListener() { return 0; }
+
+ static JITEventListener *createOProfileJITEventListener(
+ OProfileWrapper* AlternativeImpl) {
+ return 0;
+ }
+#endif // USE_OPROFILE
+
+};
+
+} // end namespace llvm.
+
+#endif // defined LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h b/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h
new file mode 100644
index 000000000000..4c75b6ab970e
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -0,0 +1,206 @@
+//===-- JITMemoryManager.h - Interface JIT uses to Allocate Mem -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
+#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+
+ class Function;
+ class GlobalValue;
+
+/// JITMemoryManager - This interface is used by the JIT to allocate and manage
+/// 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 {
+protected:
+ bool HasGOT;
+
+public:
+ JITMemoryManager() : HasGOT(false) {}
+ virtual ~JITMemoryManager();
+
+ /// CreateDefaultMemManager - This is used to create the default
+ /// JIT Memory Manager if the client does not provide one to the JIT.
+ static JITMemoryManager *CreateDefaultMemManager();
+
+ /// setMemoryWritable - When code generation is in progress,
+ /// the code pages may need permissions changed.
+ virtual void setMemoryWritable() = 0;
+
+ /// setMemoryExecutable - When code generation is done and we're ready to
+ /// start execution, the code pages may need permissions changed.
+ virtual void setMemoryExecutable() = 0;
+
+ /// setPoisonMemory - Setting this flag to true makes the memory manager
+ /// garbage values over freed memory. This is useful for testing and
+ /// 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
+ //===--------------------------------------------------------------------===//
+
+ /// AllocateGOT - If the current table requires a Global Offset Table, this
+ /// method is invoked to allocate it. This method is required to set HasGOT
+ /// to true.
+ virtual void AllocateGOT() = 0;
+
+ /// isManagingGOT - Return true if the AllocateGOT method is called.
+ bool isManagingGOT() const {
+ return HasGOT;
+ }
+
+ /// getGOTBase - If this is managing a Global Offset Table, this method should
+ /// return a pointer to its base.
+ virtual uint8_t *getGOTBase() const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Main Allocation Functions
+ //===--------------------------------------------------------------------===//
+
+ /// startFunctionBody - When we start JITing a function, the JIT calls this
+ /// method to allocate a block of free RWX memory, which returns a pointer to
+ /// it. If the JIT wants to request a block of memory of at least a certain
+ /// size, it passes that value as ActualSize, and this method returns a block
+ /// with at least that much space. If the JIT doesn't know ahead of time how
+ /// much space it will need to emit the function, it passes 0 for the
+ /// ActualSize. In either case, this method is required to pass back the size
+ /// of the allocated block through ActualSize. The JIT will be careful to
+ /// not write more than the returned ActualSize bytes of memory.
+ virtual uint8_t *startFunctionBody(const Function *F,
+ uintptr_t &ActualSize) = 0;
+
+ /// allocateStub - This method is called by the JIT to allocate space for a
+ /// function stub (used to handle limited branch displacements) while it is
+ /// JIT compiling a function. For example, if foo calls bar, and if bar
+ /// either needs to be lazily compiled or is a native function that exists too
+ /// far away from the call site to work, this method will be used to make a
+ /// thunk for it. The stub should be "close" to the current function body,
+ /// but should not be included in the 'actualsize' returned by
+ /// startFunctionBody.
+ virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment) = 0;
+
+ /// endFunctionBody - This method is called when the JIT is done codegen'ing
+ /// the specified function. At this point we know the size of the JIT
+ /// compiled function. This passes in FunctionStart (which was returned by
+ /// the startFunctionBody method) and FunctionEnd which is a pointer to the
+ /// actual end of the function. This method should mark the space allocated
+ /// and remember where it is in case the client wants to deallocate it.
+ 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;
+
+ /// allocateGlobal - Allocate memory for a global.
+ virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0;
+
+ /// deallocateFunctionBody - Free the specified function body. The argument
+ /// must be the return value from a call to startFunctionBody() that hasn't
+ /// been deallocated yet. This is never called when the JIT is currently
+ /// emitting a function.
+ virtual void deallocateFunctionBody(void *Body) = 0;
+
+ /// startExceptionTable - When we finished JITing the function, if exception
+ /// handling is set, we emit the exception table.
+ virtual uint8_t* startExceptionTable(const Function* F,
+ uintptr_t &ActualSize) = 0;
+
+ /// endExceptionTable - This method is called when the JIT is done emitting
+ /// the exception table.
+ virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
+ uint8_t *TableEnd, uint8_t* FrameRegister) = 0;
+
+ /// deallocateExceptionTable - Free the specified exception table's memory.
+ /// The argument must be the return value from a call to startExceptionTable()
+ /// that hasn't been deallocated yet. This is never called when the JIT is
+ /// currently emitting an exception table.
+ virtual void deallocateExceptionTable(void *ET) = 0;
+
+ /// CheckInvariants - For testing only. Return true if all internal
+ /// invariants are preserved, or return false and set ErrorStr to a helpful
+ /// error message.
+ virtual bool CheckInvariants(std::string &) {
+ return true;
+ }
+
+ /// GetDefaultCodeSlabSize - For testing only. Returns DefaultCodeSlabSize
+ /// from DefaultJITMemoryManager.
+ virtual size_t GetDefaultCodeSlabSize() {
+ return 0;
+ }
+
+ /// GetDefaultDataSlabSize - For testing only. Returns DefaultCodeSlabSize
+ /// from DefaultJITMemoryManager.
+ virtual size_t GetDefaultDataSlabSize() {
+ return 0;
+ }
+
+ /// GetDefaultStubSlabSize - For testing only. Returns DefaultCodeSlabSize
+ /// from DefaultJITMemoryManager.
+ virtual size_t GetDefaultStubSlabSize() {
+ return 0;
+ }
+
+ /// GetNumCodeSlabs - For testing only. Returns the number of MemoryBlocks
+ /// allocated for code.
+ virtual unsigned GetNumCodeSlabs() {
+ return 0;
+ }
+
+ /// GetNumDataSlabs - For testing only. Returns the number of MemoryBlocks
+ /// allocated for data.
+ virtual unsigned GetNumDataSlabs() {
+ return 0;
+ }
+
+ /// GetNumStubSlabs - For testing only. Returns the number of MemoryBlocks
+ /// allocated for function stubs.
+ virtual unsigned GetNumStubSlabs() {
+ return 0;
+ }
+};
+
+} // end namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h b/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h
new file mode 100644
index 000000000000..f956a5029b17
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/MCJIT.h
@@ -0,0 +1,38 @@
+//===-- MCJIT.h - MC-Based Just-In-Time Execution Engine --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the MCJIT to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTION_ENGINE_MCJIT_H
+#define LLVM_EXECUTION_ENGINE_MCJIT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+extern "C" void LLVMLinkInMCJIT();
+
+namespace {
+ struct ForceMCJITLinking {
+ ForceMCJITLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ LLVMLinkInMCJIT();
+ }
+ } ForceMCJITLinking;
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h b/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h
new file mode 100644
index 000000000000..ab7f25e9d03d
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/OProfileWrapper.h
@@ -0,0 +1,124 @@
+//===-- OProfileWrapper.h - OProfile JIT 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 OProfileWrapper object that detects if the oprofile
+// daemon is running, and provides wrappers for opagent functions used to
+// communicate with the oprofile JIT interface. The dynamic library libopagent
+// does not need to be linked directly as this object lazily loads the library
+// when the first op_ function is called.
+//
+// See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the
+// definition of the interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPROFILE_WRAPPER_H
+#define OPROFILE_WRAPPER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <opagent.h>
+
+namespace llvm {
+
+
+class OProfileWrapper {
+ typedef op_agent_t (*op_open_agent_ptr_t)();
+ typedef int (*op_close_agent_ptr_t)(op_agent_t);
+ typedef int (*op_write_native_code_ptr_t)(op_agent_t,
+ const char*,
+ uint64_t,
+ void const*,
+ const unsigned int);
+ typedef int (*op_write_debug_line_info_ptr_t)(op_agent_t,
+ void const*,
+ size_t,
+ struct debug_line_info const*);
+ 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);
+
+ // This is not a part of the opagent API, but is useful nonetheless
+ typedef bool (*IsOProfileRunningPtrT)(void);
+
+
+ op_agent_t Agent;
+ op_open_agent_ptr_t OpenAgentFunc;
+ op_close_agent_ptr_t CloseAgentFunc;
+ op_write_native_code_ptr_t WriteNativeCodeFunc;
+ op_write_debug_line_info_ptr_t WriteDebugLineInfoFunc;
+ op_unload_native_code_ptr_t UnloadNativeCodeFunc;
+ op_major_version_ptr_t MajorVersionFunc;
+ op_major_version_ptr_t MinorVersionFunc;
+ IsOProfileRunningPtrT IsOProfileRunningFunc;
+
+ bool Initialized;
+
+public:
+ OProfileWrapper();
+
+ // For testing with a mock opagent implementation, skips the dynamic load and
+ // the function resolution.
+ OProfileWrapper(op_open_agent_ptr_t OpenAgentImpl,
+ op_close_agent_ptr_t CloseAgentImpl,
+ op_write_native_code_ptr_t WriteNativeCodeImpl,
+ op_write_debug_line_info_ptr_t WriteDebugLineInfoImpl,
+ op_unload_native_code_ptr_t UnloadNativeCodeImpl,
+ op_major_version_ptr_t MajorVersionImpl,
+ op_major_version_ptr_t MinorVersionImpl,
+ IsOProfileRunningPtrT MockIsOProfileRunningImpl = 0)
+ : OpenAgentFunc(OpenAgentImpl),
+ CloseAgentFunc(CloseAgentImpl),
+ WriteNativeCodeFunc(WriteNativeCodeImpl),
+ WriteDebugLineInfoFunc(WriteDebugLineInfoImpl),
+ UnloadNativeCodeFunc(UnloadNativeCodeImpl),
+ MajorVersionFunc(MajorVersionImpl),
+ MinorVersionFunc(MinorVersionImpl),
+ IsOProfileRunningFunc(MockIsOProfileRunningImpl),
+ Initialized(true)
+ {
+ }
+
+ // Calls op_open_agent in the oprofile JIT library and saves the returned
+ // op_agent_t handle internally so it can be used when calling all the other
+ // op_* functions. Callers of this class do not need to keep track of
+ // op_agent_t objects.
+ bool op_open_agent();
+
+ int op_close_agent();
+ int op_write_native_code(const char* name,
+ uint64_t addr,
+ void const* code,
+ const unsigned int size);
+ int op_write_debug_line_info(void const* code,
+ 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);
+
+ // Returns true if the oprofiled process is running, the opagent library is
+ // loaded and a connection to the agent has been established, and false
+ // otherwise.
+ bool isAgentAvailable();
+
+private:
+ // Loads the libopagent library and initializes this wrapper if the oprofile
+ // daemon is running
+ bool initialize();
+
+ // Searches /proc for the oprofile daemon and returns true if the process if
+ // found, or false otherwise.
+ bool checkForOProfileProcEntry();
+
+ bool isOProfileRunning();
+};
+
+} // namespace llvm
+
+#endif //OPROFILE_WRAPPER_H
diff --git a/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
new file mode 100644
index 000000000000..54c28f3ec142
--- /dev/null
+++ b/contrib/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -0,0 +1,87 @@
+//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface for the runtime dynamic linker facilities of the MC-JIT.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_RUNTIME_DYLD_H
+#define LLVM_RUNTIME_DYLD_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Memory.h"
+
+namespace llvm {
+
+class RuntimeDyldImpl;
+class MemoryBuffer;
+
+// 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.
+// 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
+public:
+ RTDyldMemoryManager() {}
+ virtual ~RTDyldMemoryManager();
+
+ /// allocateCodeSection - Allocate a memory block of (at least) the given
+ /// size suitable for executable code.
+ 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.
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID) = 0;
+
+ virtual void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true) = 0;
+};
+
+class RuntimeDyld {
+ RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT
+ void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT
+
+ // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
+ // interface.
+ RuntimeDyldImpl *Dyld;
+ RTDyldMemoryManager *MM;
+protected:
+ // Change the address associated with a section when resolving relocations.
+ // Any relocations already associated with the symbol will be re-resolved.
+ void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
+public:
+ RuntimeDyld(RTDyldMemoryManager*);
+ ~RuntimeDyld();
+
+ bool loadObject(MemoryBuffer *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
+ // and resolve relocatons based on where they put it).
+ void *getSymbolAddress(StringRef Name);
+ // Resolve the relocations for all symbols we currently know about.
+ void resolveRelocations();
+
+ /// mapSectionAddress - 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);
+
+ StringRef getErrorString();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Function.h b/contrib/llvm/include/llvm/Function.h
new file mode 100644
index 000000000000..e17cd87fe348
--- /dev/null
+++ b/contrib/llvm/include/llvm/Function.h
@@ -0,0 +1,458 @@
+//===-- llvm/Function.h - Class to represent a single function --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Function class, which represents a
+// single function/procedure in LLVM.
+//
+// A function basically consists of a list of basic blocks, a list of arguments,
+// and a symbol table.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/Compiler.h"
+
+namespace llvm {
+
+class FunctionType;
+class LLVMContext;
+
+// Traits for intrusive list of basic blocks...
+template<> struct ilist_traits<BasicBlock>
+ : public SymbolTableListTraits<BasicBlock, Function> {
+
+ // createSentinel is used to get hold of the node that marks the end of the
+ // list... (same trick used here as in ilist_traits<Instruction>)
+ BasicBlock *createSentinel() const {
+ return static_cast<BasicBlock*>(&Sentinel);
+ }
+ static void destroySentinel(BasicBlock*) {}
+
+ BasicBlock *provideInitialHead() const { return createSentinel(); }
+ BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
+ static void noteHead(BasicBlock*, BasicBlock*) {}
+
+ static ValueSymbolTable *getSymTab(Function *ItemParent);
+private:
+ mutable ilist_half_node<BasicBlock> Sentinel;
+};
+
+template<> struct ilist_traits<Argument>
+ : public SymbolTableListTraits<Argument, Function> {
+
+ Argument *createSentinel() const {
+ return static_cast<Argument*>(&Sentinel);
+ }
+ static void destroySentinel(Argument*) {}
+
+ Argument *provideInitialHead() const { return createSentinel(); }
+ Argument *ensureHead(Argument*) const { return createSentinel(); }
+ static void noteHead(Argument*, Argument*) {}
+
+ static ValueSymbolTable *getSymTab(Function *ItemParent);
+private:
+ mutable ilist_half_node<Argument> Sentinel;
+};
+
+class Function : public GlobalValue,
+ public ilist_node<Function> {
+public:
+ typedef iplist<Argument> ArgumentListType;
+ typedef iplist<BasicBlock> BasicBlockListType;
+
+ // BasicBlock iterators...
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+
+ typedef ArgumentListType::iterator arg_iterator;
+ typedef ArgumentListType::const_iterator const_arg_iterator;
+
+private:
+ // Important things that make up a function!
+ BasicBlockListType BasicBlocks; ///< The basic blocks
+ mutable ArgumentListType ArgumentList; ///< The formal arguments
+ ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
+ AttrListPtr AttributeList; ///< Parameter attributes
+
+ // HasLazyArguments is stored in Value::SubclassData.
+ /*bool HasLazyArguments;*/
+
+ // The Calling Convention is stored in Value::SubclassData.
+ /*CallingConv::ID CallingConvention;*/
+
+ friend class SymbolTableListTraits<Function, Module>;
+
+ void setParent(Module *parent);
+
+ /// hasLazyArguments/CheckLazyArguments - The argument list of a function is
+ /// built on demand, so that the list isn't allocated until the first client
+ /// needs it. The hasLazyArguments predicate returns true if the arg list
+ /// hasn't been set up yet.
+ bool hasLazyArguments() const {
+ return getSubclassDataFromValue() & 1;
+ }
+ void CheckLazyArguments() const {
+ if (hasLazyArguments())
+ BuildLazyArguments();
+ }
+ void BuildLazyArguments() const;
+
+ Function(const Function&); // DO NOT IMPLEMENT
+ void operator=(const Function&); // DO NOT IMPLEMENT
+
+ /// Function ctor - If the (optional) Module argument is specified, the
+ /// function is automatically inserted into the end of the function list for
+ /// the module.
+ ///
+ Function(FunctionType *Ty, LinkageTypes Linkage,
+ const Twine &N = "", Module *M = 0);
+
+public:
+ static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
+ const Twine &N = "", Module *M = 0) {
+ return new(0) Function(Ty, Linkage, N, M);
+ }
+
+ ~Function();
+
+ 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
+ /// function, or NULL if this function is not bound to a context yet.
+ LLVMContext &getContext() const;
+
+ /// isVarArg - Return true if this function takes a variable number of
+ /// arguments.
+ bool isVarArg() const;
+
+ /// getIntrinsicID - This method returns the ID number of the specified
+ /// function, or Intrinsic::not_intrinsic if the function is not an
+ /// instrinsic, or if the pointer is null. This value is always defined to be
+ /// zero to allow easy checking for whether a function is intrinsic or not.
+ /// The particular intrinsic functions which correspond to this value are
+ /// defined in llvm/Intrinsics.h.
+ ///
+ unsigned getIntrinsicID() const LLVM_READONLY;
+ bool isIntrinsic() const { return getIntrinsicID() != 0; }
+
+ /// getCallingConv()/setCallingConv(CC) - These method get and set the
+ /// calling convention of this function. The enum values for the known
+ /// calling conventions are defined in CallingConv.h.
+ CallingConv::ID getCallingConv() const {
+ return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 1);
+ }
+ void setCallingConv(CallingConv::ID CC) {
+ setValueSubclassData((getSubclassDataFromValue() & 1) |
+ (static_cast<unsigned>(CC) << 1));
+ }
+
+ /// getAttributes - Return the attribute list for this Function.
+ ///
+ const AttrListPtr &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);
+ }
+
+ /// addFnAttr - Add function attributes to this function.
+ ///
+ void addFnAttr(Attributes N) {
+ // Function Attributes are stored at ~0 index
+ addAttribute(~0U, N);
+ }
+
+ /// removeFnAttr - Remove function attributes from this function.
+ ///
+ void removeFnAttr(Attributes N) {
+ // Function Attributes are stored at ~0 index
+ removeAttribute(~0U, N);
+ }
+
+ /// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
+ /// to use during code generation.
+ bool hasGC() const;
+ const char *getGC() const;
+ 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);
+
+ /// removeAttribute - removes the attribute from the list of attributes.
+ void removeAttribute(unsigned i, Attributes attr);
+
+ /// @brief Extract the alignment for a call or parameter (0=unknown).
+ unsigned getParamAlignment(unsigned i) const {
+ return AttributeList.getParamAlignment(i);
+ }
+
+ /// @brief Determine if the function does not access memory.
+ bool doesNotAccessMemory() const {
+ return hasFnAttr(Attribute::ReadNone);
+ }
+ void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) {
+ if (DoesNotAccessMemory) addFnAttr(Attribute::ReadNone);
+ else removeFnAttr(Attribute::ReadNone);
+ }
+
+ /// @brief Determine if the function does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+ }
+ void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
+ if (OnlyReadsMemory) addFnAttr(Attribute::ReadOnly);
+ else removeFnAttr(Attribute::ReadOnly | Attribute::ReadNone);
+ }
+
+ /// @brief Determine if the function cannot return.
+ bool doesNotReturn() const {
+ return hasFnAttr(Attribute::NoReturn);
+ }
+ void setDoesNotReturn(bool DoesNotReturn = true) {
+ if (DoesNotReturn) addFnAttr(Attribute::NoReturn);
+ else removeFnAttr(Attribute::NoReturn);
+ }
+
+ /// @brief Determine if the function cannot unwind.
+ bool doesNotThrow() const {
+ return hasFnAttr(Attribute::NoUnwind);
+ }
+ void setDoesNotThrow(bool DoesNotThrow = true) {
+ if (DoesNotThrow) addFnAttr(Attribute::NoUnwind);
+ else removeFnAttr(Attribute::NoUnwind);
+ }
+
+ /// @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);
+ }
+ void setHasUWTable(bool HasUWTable = true) {
+ if (HasUWTable)
+ addFnAttr(Attribute::UWTable);
+ else
+ removeFnAttr(Attribute::UWTable);
+ }
+
+ /// @brief True if this function needs an unwind table.
+ bool needsUnwindTableEntry() const {
+ return hasUWTable() || !doesNotThrow();
+ }
+
+ /// @brief Determine if the function returns a structure through first
+ /// pointer argument.
+ bool hasStructRetAttr() const {
+ return paramHasAttr(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);
+ }
+ void setDoesNotAlias(unsigned n, bool DoesNotAlias = true) {
+ if (DoesNotAlias) addAttribute(n, Attribute::NoAlias);
+ else removeAttribute(n, 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);
+ }
+ void setDoesNotCapture(unsigned n, bool DoesNotCapture = true) {
+ if (DoesNotCapture) addAttribute(n, Attribute::NoCapture);
+ else removeAttribute(n, Attribute::NoCapture);
+ }
+
+ /// copyAttributesFrom - copy all additional attributes (those not needed to
+ /// create a Function) from the Function Src to this one.
+ void copyAttributesFrom(const GlobalValue *Src);
+
+ /// deleteBody - This method deletes the body of the function, and converts
+ /// the linkage to external.
+ ///
+ void deleteBody() {
+ dropAllReferences();
+ setLinkage(ExternalLinkage);
+ }
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ ///
+ virtual void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ ///
+ virtual void eraseFromParent();
+
+
+ /// Get the underlying elements of the Function... the basic block list is
+ /// empty for external functions.
+ ///
+ const ArgumentListType &getArgumentList() const {
+ CheckLazyArguments();
+ return ArgumentList;
+ }
+ ArgumentListType &getArgumentList() {
+ CheckLazyArguments();
+ return ArgumentList;
+ }
+ static iplist<Argument> Function::*getSublistAccess(Argument*) {
+ return &Function::ArgumentList;
+ }
+
+ const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
+ BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
+ static iplist<BasicBlock> Function::*getSublistAccess(BasicBlock*) {
+ return &Function::BasicBlocks;
+ }
+
+ const BasicBlock &getEntryBlock() const { return front(); }
+ BasicBlock &getEntryBlock() { return front(); }
+
+ //===--------------------------------------------------------------------===//
+ // Symbol Table Accessing functions...
+
+ /// getSymbolTable() - Return the symbol table...
+ ///
+ inline ValueSymbolTable &getValueSymbolTable() { return *SymTab; }
+ inline const ValueSymbolTable &getValueSymbolTable() const { return *SymTab; }
+
+
+ //===--------------------------------------------------------------------===//
+ // BasicBlock iterator forwarding functions
+ //
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ size_t size() const { return BasicBlocks.size(); }
+ bool empty() const { return BasicBlocks.empty(); }
+ const BasicBlock &front() const { return BasicBlocks.front(); }
+ BasicBlock &front() { return BasicBlocks.front(); }
+ const BasicBlock &back() const { return BasicBlocks.back(); }
+ BasicBlock &back() { return BasicBlocks.back(); }
+
+ //===--------------------------------------------------------------------===//
+ // Argument iterator forwarding functions
+ //
+ arg_iterator arg_begin() {
+ CheckLazyArguments();
+ return ArgumentList.begin();
+ }
+ const_arg_iterator arg_begin() const {
+ CheckLazyArguments();
+ return ArgumentList.begin();
+ }
+ arg_iterator arg_end() {
+ CheckLazyArguments();
+ return ArgumentList.end();
+ }
+ const_arg_iterator arg_end() const {
+ CheckLazyArguments();
+ return ArgumentList.end();
+ }
+
+ size_t arg_size() const;
+ bool arg_empty() const;
+
+ /// viewCFG - This function is meant for use from the debugger. You can just
+ /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+ /// program, displaying the CFG of the current function with the code for each
+ /// basic block inside. This depends on there being a 'dot' and 'gv' program
+ /// in your path.
+ ///
+ void viewCFG() const;
+
+ /// viewCFGOnly - This function is meant for use from the debugger. It works
+ /// just like viewCFG, but it does not include the contents of basic blocks
+ /// into the nodes, just the label. If you are only interested in the CFG
+ /// this can make the graph smaller.
+ ///
+ 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;
+ }
+
+ /// dropAllReferences() - This method causes all the subinstructions to "let
+ /// go" of all references that they are maintaining. This allows one to
+ /// 'delete' a whole module at a time, even though there may be circular
+ /// references... first all references are dropped, and all use counts go to
+ /// zero. Then everything is deleted for real. Note that no operations are
+ /// valid on an object that has "dropped all references", except operator
+ /// delete.
+ ///
+ /// Since no other object in the module can have references into the body of a
+ /// function, dropping all references deletes the entire body of the function,
+ /// including any contained basic blocks.
+ ///
+ void dropAllReferences();
+
+ /// hasAddressTaken - returns true if there are any uses of this function
+ /// other than direct calls or invokes to it. Optionally passes back the
+ /// offending user for diagnostic purposes.
+ ///
+ bool hasAddressTaken(const User** = 0) const;
+
+ /// isDefTriviallyDead - Return true if it is trivially safe to remove
+ /// this function definition from the module (because it isn't externally
+ /// visible, does not have its address taken, and has no callers). To make
+ /// this more accurate, call removeDeadConstantUsers first.
+ bool isDefTriviallyDead() const;
+
+ /// callsFunctionThatReturnsTwice - Return true if the function has a call to
+ /// setjmp or other function that gcc recognizes as "returning twice".
+ bool callsFunctionThatReturnsTwice() const;
+
+private:
+ // Shadow Value::setValueSubclassData with a private forwarding method so that
+ // subclasses cannot accidentally use it.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
+};
+
+inline ValueSymbolTable *
+ilist_traits<BasicBlock>::getSymTab(Function *F) {
+ return F ? &F->getValueSymbolTable() : 0;
+}
+
+inline ValueSymbolTable *
+ilist_traits<Argument>::getSymTab(Function *F) {
+ return F ? &F->getValueSymbolTable() : 0;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/GVMaterializer.h b/contrib/llvm/include/llvm/GVMaterializer.h
new file mode 100644
index 000000000000..c14355238867
--- /dev/null
+++ b/contrib/llvm/include/llvm/GVMaterializer.h
@@ -0,0 +1,66 @@
+//===-- llvm/GVMaterializer.h - Interface for GV materializers --*- 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 an abstract interface for loading a module from some
+// place. This interface allows incremental or random access loading of
+// functions from the file. This is useful for applications like JIT compilers
+// or interprocedural optimizers that do not need the entire program in memory
+// at the same time.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef GVMATERIALIZER_H
+#define GVMATERIALIZER_H
+
+#include <string>
+
+namespace llvm {
+
+class Function;
+class GlobalValue;
+class Module;
+
+class GVMaterializer {
+protected:
+ GVMaterializer() {}
+
+public:
+ virtual ~GVMaterializer();
+
+ /// isMaterializable - True if GV can be materialized from whatever backing
+ /// store this GVMaterializer uses and has not been materialized yet.
+ virtual bool isMaterializable(const GlobalValue *GV) const = 0;
+
+ /// isDematerializable - True if GV has been materialized and can be
+ /// dematerialized back to whatever backing store this GVMaterializer uses.
+ virtual bool isDematerializable(const GlobalValue *GV) const = 0;
+
+ /// Materialize - make sure the given GlobalValue is fully read. If the
+ /// module is corrupt, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ ///
+ virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0) = 0;
+
+ /// Dematerialize - If the given GlobalValue is read in, and if the
+ /// GVMaterializer supports it, release the memory for the GV, and set it up
+ /// to be materialized lazily. If the Materializer doesn't support this
+ /// capability, this method is a noop.
+ ///
+ virtual void Dematerialize(GlobalValue *) {}
+
+ /// MaterializeModule - make sure the entire Module has been completely read.
+ /// On error, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ ///
+ virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0) = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/GlobalAlias.h b/contrib/llvm/include/llvm/GlobalAlias.h
new file mode 100644
index 000000000000..164d976588d6
--- /dev/null
+++ b/contrib/llvm/include/llvm/GlobalAlias.h
@@ -0,0 +1,94 @@
+//===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the GlobalAlias class, which
+// represents a single function or variable alias in the IR.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class Module;
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+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 setParent(Module *parent);
+
+public:
+ // allocate space for exactly one operand
+ void *operator new(size_t s) {
+ return User::operator new(s, 1);
+ }
+ /// GlobalAlias ctor - If a parent module is specified, the alias is
+ /// automatically inserted into the end of the specified module's alias list.
+ GlobalAlias(Type *Ty, LinkageTypes Linkage, const Twine &Name = "",
+ Constant* Aliasee = 0, Module *Parent = 0);
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ ///
+ virtual void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ ///
+ virtual void eraseFromParent();
+
+ /// set/getAliasee - These methods retrive and set alias target.
+ void setAliasee(Constant *GV);
+ const Constant *getAliasee() const {
+ return getOperand(0);
+ }
+ Constant *getAliasee() {
+ return getOperand(0);
+ }
+ /// getAliasedGlobal() - Aliasee can be either global or bitcast of
+ /// global. This method retrives the global for both aliasee flavours.
+ const GlobalValue *getAliasedGlobal() const;
+
+ /// resolveAliasedGlobal() - This method tries to ultimately resolve the alias
+ /// by going through the aliasing chain and trying to find the very last
+ /// global. Returns NULL if a cycle was found. If stopOnWeak is false, then
+ /// the whole chain aliasing chain is traversed, otherwise - only strong
+ /// aliases.
+ 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;
+ }
+};
+
+template <>
+struct OperandTraits<GlobalAlias> :
+ public FixedNumOperandTraits<GlobalAlias, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Constant)
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/GlobalValue.h b/contrib/llvm/include/llvm/GlobalValue.h
new file mode 100644
index 000000000000..81a11a4c9258
--- /dev/null
+++ b/contrib/llvm/include/llvm/GlobalValue.h
@@ -0,0 +1,291 @@
+//===-- llvm/GlobalValue.h - Class to represent a global value --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a common base class of all globally definable objects. As such,
+// it is subclassed by GlobalVariable, GlobalAlias and by Function. This is
+// used because you can do certain things with these global objects that you
+// can't do to anything else. For example, use the address of one as a
+// constant.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GLOBALVALUE_H
+#define LLVM_GLOBALVALUE_H
+
+#include "llvm/Constant.h"
+
+namespace llvm {
+
+class PointerType;
+class Module;
+
+class GlobalValue : public Constant {
+ GlobalValue(const GlobalValue &); // do not implement
+public:
+ /// @brief An enumeration for the kinds of linkage for global values.
+ enum LinkageTypes {
+ ExternalLinkage = 0,///< Externally visible function
+ AvailableExternallyLinkage, ///< Available for inspection, not emission.
+ LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline)
+ LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent.
+ WeakAnyLinkage, ///< Keep one copy of named function when linking (weak)
+ WeakODRLinkage, ///< Same, but only replaced by something equivalent.
+ AppendingLinkage, ///< Special purpose, only applies to global arrays
+ InternalLinkage, ///< Rename collisions when linking (static functions).
+ PrivateLinkage, ///< Like Internal, but omit from symbol table.
+ LinkerPrivateLinkage, ///< Like Private, but linker removes.
+ LinkerPrivateWeakLinkage, ///< Like LinkerPrivate, but weak.
+ LinkerPrivateWeakDefAutoLinkage, ///< Like LinkerPrivateWeak, but possibly
+ /// hidden.
+ DLLImportLinkage, ///< Function to be imported from DLL
+ DLLExportLinkage, ///< Function to be accessible from DLL.
+ ExternalWeakLinkage,///< ExternalWeak linkage description.
+ CommonLinkage ///< Tentative definitions.
+ };
+
+ /// @brief An enumeration for the kinds of visibility of global values.
+ enum VisibilityTypes {
+ DefaultVisibility = 0, ///< The GV is visible
+ HiddenVisibility, ///< The GV is hidden
+ ProtectedVisibility ///< The GV is protected
+ };
+
+protected:
+ GlobalValue(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps,
+ LinkageTypes linkage, const Twine &Name)
+ : Constant(ty, vty, Ops, NumOps), Linkage(linkage),
+ Visibility(DefaultVisibility), Alignment(0), UnnamedAddr(0), Parent(0) {
+ setName(Name);
+ }
+
+ // Note: VC++ treats enums as signed, so an extra bit is required to prevent
+ // Linkage and Visibility from turning into negative values.
+ LinkageTypes Linkage : 5; // The linkage of this global
+ unsigned Visibility : 2; // The visibility style of this global
+ unsigned Alignment : 16; // Alignment of this symbol, must be power of two
+ unsigned UnnamedAddr : 1; // This value's address is not significant
+ Module *Parent; // The containing module.
+ std::string Section; // Section to emit this into, empty mean default
+public:
+ ~GlobalValue() {
+ removeDeadConstantUsers(); // remove any dead constants using this.
+ }
+
+ unsigned getAlignment() const {
+ return (1u << Alignment) >> 1;
+ }
+ void setAlignment(unsigned Align);
+
+ bool hasUnnamedAddr() const { return UnnamedAddr; }
+ void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
+
+ VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
+ bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
+ bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
+ bool hasProtectedVisibility() const {
+ return Visibility == ProtectedVisibility;
+ }
+ void setVisibility(VisibilityTypes V) { Visibility = V; }
+
+ bool hasSection() const { return !Section.empty(); }
+ const std::string &getSection() const { return Section; }
+ void setSection(StringRef S) { Section = S; }
+
+ /// If the usage is empty (except transitively dead constants), then this
+ /// global value can be safely deleted since the destructor will
+ /// delete the dead constants as well.
+ /// @brief Determine if the usage of this global value is empty except
+ /// for transitively dead constants.
+ bool use_empty_except_constants();
+
+ /// getType - Global values are always pointers.
+ inline PointerType *getType() const {
+ return reinterpret_cast<PointerType*>(User::getType());
+ }
+
+ static LinkageTypes getLinkOnceLinkage(bool ODR) {
+ return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
+ }
+ static LinkageTypes getWeakLinkage(bool ODR) {
+ return ODR ? WeakODRLinkage : WeakAnyLinkage;
+ }
+
+ static bool isExternalLinkage(LinkageTypes Linkage) {
+ return Linkage == ExternalLinkage;
+ }
+ static bool isAvailableExternallyLinkage(LinkageTypes Linkage) {
+ return Linkage == AvailableExternallyLinkage;
+ }
+ static bool isLinkOnceLinkage(LinkageTypes Linkage) {
+ return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage;
+ }
+ static bool isWeakLinkage(LinkageTypes Linkage) {
+ return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage;
+ }
+ static bool isAppendingLinkage(LinkageTypes Linkage) {
+ return Linkage == AppendingLinkage;
+ }
+ static bool isInternalLinkage(LinkageTypes Linkage) {
+ return Linkage == InternalLinkage;
+ }
+ static bool isPrivateLinkage(LinkageTypes Linkage) {
+ return Linkage == PrivateLinkage;
+ }
+ static bool isLinkerPrivateLinkage(LinkageTypes Linkage) {
+ return Linkage == LinkerPrivateLinkage;
+ }
+ static bool isLinkerPrivateWeakLinkage(LinkageTypes Linkage) {
+ return Linkage == LinkerPrivateWeakLinkage;
+ }
+ static bool isLinkerPrivateWeakDefAutoLinkage(LinkageTypes Linkage) {
+ return Linkage == LinkerPrivateWeakDefAutoLinkage;
+ }
+ static bool isLocalLinkage(LinkageTypes Linkage) {
+ return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) ||
+ isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage) ||
+ isLinkerPrivateWeakDefAutoLinkage(Linkage);
+ }
+ static bool isDLLImportLinkage(LinkageTypes Linkage) {
+ return Linkage == DLLImportLinkage;
+ }
+ static bool isDLLExportLinkage(LinkageTypes Linkage) {
+ return Linkage == DLLExportLinkage;
+ }
+ static bool isExternalWeakLinkage(LinkageTypes Linkage) {
+ return Linkage == ExternalWeakLinkage;
+ }
+ static bool isCommonLinkage(LinkageTypes Linkage) {
+ return Linkage == CommonLinkage;
+ }
+
+ /// mayBeOverridden - Whether the definition of this global may be replaced
+ /// by something non-equivalent at link time. For example, if a function has
+ /// weak linkage then the code defining it may be replaced by different code.
+ static bool mayBeOverridden(LinkageTypes Linkage) {
+ return Linkage == WeakAnyLinkage ||
+ Linkage == LinkOnceAnyLinkage ||
+ Linkage == CommonLinkage ||
+ Linkage == ExternalWeakLinkage ||
+ Linkage == LinkerPrivateWeakLinkage ||
+ Linkage == LinkerPrivateWeakDefAutoLinkage;
+ }
+
+ /// isWeakForLinker - Whether the definition of this global may be replaced at
+ /// link time. NB: Using this method outside of the code generators is almost
+ /// always a mistake: when working at the IR level use mayBeOverridden instead
+ /// as it knows about ODR semantics.
+ static bool isWeakForLinker(LinkageTypes Linkage) {
+ return Linkage == AvailableExternallyLinkage ||
+ Linkage == WeakAnyLinkage ||
+ Linkage == WeakODRLinkage ||
+ Linkage == LinkOnceAnyLinkage ||
+ Linkage == LinkOnceODRLinkage ||
+ Linkage == CommonLinkage ||
+ Linkage == ExternalWeakLinkage ||
+ Linkage == LinkerPrivateWeakLinkage ||
+ Linkage == LinkerPrivateWeakDefAutoLinkage;
+ }
+
+ bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
+ bool hasAvailableExternallyLinkage() const {
+ return isAvailableExternallyLinkage(Linkage);
+ }
+ bool hasLinkOnceLinkage() const {
+ return isLinkOnceLinkage(Linkage);
+ }
+ bool hasWeakLinkage() const {
+ return isWeakLinkage(Linkage);
+ }
+ bool hasAppendingLinkage() const { return isAppendingLinkage(Linkage); }
+ bool hasInternalLinkage() const { return isInternalLinkage(Linkage); }
+ bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); }
+ bool hasLinkerPrivateLinkage() const { return isLinkerPrivateLinkage(Linkage); }
+ bool hasLinkerPrivateWeakLinkage() const {
+ return isLinkerPrivateWeakLinkage(Linkage);
+ }
+ bool hasLinkerPrivateWeakDefAutoLinkage() const {
+ return isLinkerPrivateWeakDefAutoLinkage(Linkage);
+ }
+ bool hasLocalLinkage() const { return isLocalLinkage(Linkage); }
+ bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); }
+ bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); }
+ bool hasExternalWeakLinkage() const { return isExternalWeakLinkage(Linkage); }
+ bool hasCommonLinkage() const { return isCommonLinkage(Linkage); }
+
+ void setLinkage(LinkageTypes LT) { Linkage = LT; }
+ LinkageTypes getLinkage() const { return Linkage; }
+
+ bool mayBeOverridden() const { return mayBeOverridden(Linkage); }
+
+ bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
+
+ /// copyAttributesFrom - copy all additional attributes (those not needed to
+ /// create a GlobalValue) from the GlobalValue Src to this one.
+ virtual void copyAttributesFrom(const GlobalValue *Src);
+
+/// @name Materialization
+/// Materialization is used to construct functions only as they're needed. This
+/// is useful to reduce memory usage in LLVM or parsing work done by the
+/// BitcodeReader to load the Module.
+/// @{
+
+ /// isMaterializable - If this function's Module is being lazily streamed in
+ /// functions from disk or some other source, this method can be used to check
+ /// to see if the function has been read in yet or not.
+ bool isMaterializable() const;
+
+ /// isDematerializable - Returns true if this function was loaded from a
+ /// GVMaterializer that's still attached to its Module and that knows how to
+ /// dematerialize the function.
+ bool isDematerializable() const;
+
+ /// Materialize - make sure this GlobalValue is fully read. If the module is
+ /// corrupt, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ bool Materialize(std::string *ErrInfo = 0);
+
+ /// Dematerialize - If this GlobalValue is read in, and if the GVMaterializer
+ /// supports it, release the memory for the function, and set it up to be
+ /// materialized lazily. If !isDematerializable(), this method is a noop.
+ void Dematerialize();
+
+/// @}
+
+ /// Override from Constant class.
+ virtual void destroyConstant();
+
+ /// isDeclaration - Return true if the primary definition of this global
+ /// value is outside of the current translation unit.
+ bool isDeclaration() const;
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ virtual void removeFromParent() = 0;
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ virtual void eraseFromParent() = 0;
+
+ /// getParent - Get the module that this global value is contained inside
+ /// of...
+ inline Module *getParent() { return Parent; }
+ 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 ||
+ V->getValueID() == Value::GlobalAliasVal;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/GlobalVariable.h b/contrib/llvm/include/llvm/GlobalVariable.h
new file mode 100644
index 000000000000..034ade1fb031
--- /dev/null
+++ b/contrib/llvm/include/llvm/GlobalVariable.h
@@ -0,0 +1,175 @@
+//===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the GlobalVariable class, which
+// represents a single global variable (or constant) in the VM.
+//
+// Global variables are constant pointers that refer to hunks of space that are
+// allocated by either the VM, or by the linker in a static compiler. A global
+// variable may have an initial value, which is copied into the executables .data
+// area. Global Constants are required to have initializers.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class Module;
+class Constant;
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+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 setParent(Module *parent);
+
+ bool isConstantGlobal : 1; // Is this a global constant?
+ bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"?
+
+public:
+ // allocate space for exactly one operand
+ void *operator new(size_t s) {
+ return User::operator new(s, 1);
+ }
+ /// GlobalVariable ctor - If a parent module is specified, the global is
+ /// automatically inserted into the end of the specified modules global list.
+ GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
+ Constant *Initializer = 0, const Twine &Name = "",
+ bool ThreadLocal = false, unsigned AddressSpace = 0);
+ /// GlobalVariable ctor - This creates a global and inserts it before the
+ /// specified other global.
+ GlobalVariable(Module &M, Type *Ty, bool isConstant,
+ LinkageTypes Linkage, Constant *Initializer,
+ const Twine &Name,
+ GlobalVariable *InsertBefore = 0, bool ThreadLocal = false,
+ unsigned AddressSpace = 0);
+
+ ~GlobalVariable() {
+ NumOperands = 1; // FIXME: needed by operator delete
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// hasInitializer - Unless a global variable isExternal(), it has an
+ /// initializer. The initializer for the global variable/constant is held by
+ /// Initializer if an initializer is specified.
+ ///
+ inline bool hasInitializer() const { return !isDeclaration(); }
+
+ /// hasDefinitiveInitializer - Whether the global variable has an initializer,
+ /// and any other instances of the global (this can happen due to weak
+ /// linkage) are guaranteed to have the same initializer.
+ ///
+ /// Note that if you want to transform a global, you must use
+ /// hasUniqueInitializer() instead, because of the *_odr linkage type.
+ ///
+ /// Example:
+ ///
+ /// @a = global SomeType* null - Initializer is both definitive and unique.
+ ///
+ /// @b = global weak SomeType* null - Initializer is neither definitive nor
+ /// unique.
+ ///
+ /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
+ /// unique.
+ inline bool hasDefinitiveInitializer() const {
+ return hasInitializer() &&
+ // The initializer of a global variable with weak linkage may change at
+ // link time.
+ !mayBeOverridden();
+ }
+
+ /// hasUniqueInitializer - Whether the global variable has an initializer, and
+ /// any changes made to the initializer will turn up in the final executable.
+ inline bool hasUniqueInitializer() const {
+ return hasInitializer() &&
+ // It's not safe to modify initializers of global variables with weak
+ // linkage, because the linker might choose to discard the initializer and
+ // use the initializer from another instance of the global variable
+ // instead. It is wrong to modify the initializer of a global variable
+ // with *_odr linkage because then different instances of the global may
+ // have different initializers, breaking the One Definition Rule.
+ !isWeakForLinker();
+ }
+
+ /// getInitializer - Return the initializer for this global variable. It is
+ /// illegal to call this method if the global is external, because we cannot
+ /// tell what the value is initialized to!
+ ///
+ inline const Constant *getInitializer() const {
+ assert(hasInitializer() && "GV doesn't have initializer!");
+ return static_cast<Constant*>(Op<0>().get());
+ }
+ inline Constant *getInitializer() {
+ assert(hasInitializer() && "GV doesn't have initializer!");
+ return static_cast<Constant*>(Op<0>().get());
+ }
+ /// setInitializer - Sets the initializer for this global variable, removing
+ /// any existing initializer if InitVal==NULL. If this GV has type T*, the
+ /// initializer must have type T.
+ void setInitializer(Constant *InitVal);
+
+ /// If the value is a global constant, its value is immutable throughout the
+ /// runtime execution of the program. Assigning a value into the constant
+ /// leads to undefined behavior.
+ ///
+ bool isConstant() const { return isConstantGlobal; }
+ void setConstant(bool Val) { isConstantGlobal = Val; }
+
+ /// If the value is "Thread Local", its value isn't shared by the threads.
+ bool isThreadLocal() const { return isThreadLocalSymbol; }
+ void setThreadLocal(bool Val) { isThreadLocalSymbol = Val; }
+
+ /// copyAttributesFrom - copy all additional attributes (those not needed to
+ /// create a GlobalVariable) from the GlobalVariable Src to this one.
+ void copyAttributesFrom(const GlobalValue *Src);
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ ///
+ virtual void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ ///
+ virtual void eraseFromParent();
+
+ /// Override Constant's implementation of this method so we can
+ /// replace constant initializers.
+ 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;
+ }
+};
+
+template <>
+struct OperandTraits<GlobalVariable> :
+ public OptionalOperandTraits<GlobalVariable> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalVariable, Value)
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/InitializePasses.h b/contrib/llvm/include/llvm/InitializePasses.h
new file mode 100644
index 000000000000..33d20435de1d
--- /dev/null
+++ b/contrib/llvm/include/llvm/InitializePasses.h
@@ -0,0 +1,256 @@
+//===- llvm/InitializePasses.h -------- Initialize All Passes ---*- 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 declarations for the pass initialization routines
+// for the entire LLVM project.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INITIALIZEPASSES_H
+#define LLVM_INITIALIZEPASSES_H
+
+namespace llvm {
+
+class PassRegistry;
+
+/// initializeCore - Initialize all passes linked into the
+/// TransformUtils library.
+void initializeCore(PassRegistry&);
+
+/// initializeTransformUtils - Initialize all passes linked into the
+/// TransformUtils library.
+void initializeTransformUtils(PassRegistry&);
+
+/// initializeScalarOpts - Initialize all passes linked into the
+/// ScalarOpts library.
+void initializeScalarOpts(PassRegistry&);
+
+/// initializeVectorization - Initialize all passes linked into the
+/// Vectorize library.
+void initializeVectorization(PassRegistry&);
+
+/// initializeInstCombine - Initialize all passes linked into the
+/// ScalarOpts library.
+void initializeInstCombine(PassRegistry&);
+
+/// initializeIPO - Initialize all passes linked into the IPO library.
+void initializeIPO(PassRegistry&);
+
+/// initializeInstrumentation - Initialize all passes linked into the
+/// Instrumentation library.
+void initializeInstrumentation(PassRegistry&);
+
+/// initializeAnalysis - Initialize all passes linked into the Analysis library.
+void initializeAnalysis(PassRegistry&);
+
+/// initializeIPA - Initialize all passes linked into the IPA library.
+void initializeIPA(PassRegistry&);
+
+/// initializeCodeGen - Initialize all passes linked into the CodeGen library.
+void initializeCodeGen(PassRegistry&);
+
+/// initializeCodeGen - Initialize all passes linked into the CodeGen library.
+void initializeTarget(PassRegistry&);
+
+void initializeAAEvalPass(PassRegistry&);
+void initializeADCEPass(PassRegistry&);
+void initializeAliasAnalysisAnalysisGroup(PassRegistry&);
+void initializeAliasAnalysisCounterPass(PassRegistry&);
+void initializeAliasDebuggerPass(PassRegistry&);
+void initializeAliasSetPrinterPass(PassRegistry&);
+void initializeAlwaysInlinerPass(PassRegistry&);
+void initializeArgPromotionPass(PassRegistry&);
+void initializeBasicAliasAnalysisPass(PassRegistry&);
+void initializeBasicCallGraphPass(PassRegistry&);
+void initializeBlockExtractorPassPass(PassRegistry&);
+void initializeBlockFrequencyInfoPass(PassRegistry&);
+void initializeBlockPlacementPass(PassRegistry&);
+void initializeBranchFolderPassPass(PassRegistry&);
+void initializeBranchProbabilityInfoPass(PassRegistry&);
+void initializeBreakCriticalEdgesPass(PassRegistry&);
+void initializeCFGOnlyPrinterPass(PassRegistry&);
+void initializeCFGOnlyViewerPass(PassRegistry&);
+void initializeCFGPrinterPass(PassRegistry&);
+void initializeCFGSimplifyPassPass(PassRegistry&);
+void initializeCFGViewerPass(PassRegistry&);
+void initializeCalculateSpillWeightsPass(PassRegistry&);
+void initializeCallGraphAnalysisGroup(PassRegistry&);
+void initializeCodeGenPreparePass(PassRegistry&);
+void initializeCodePlacementOptPass(PassRegistry&);
+void initializeConstantMergePass(PassRegistry&);
+void initializeConstantPropagationPass(PassRegistry&);
+void initializeMachineCopyPropagationPass(PassRegistry&);
+void initializeCorrelatedValuePropagationPass(PassRegistry&);
+void initializeDAEPass(PassRegistry&);
+void initializeDAHPass(PassRegistry&);
+void initializeDCEPass(PassRegistry&);
+void initializeDSEPass(PassRegistry&);
+void initializeDeadInstEliminationPass(PassRegistry&);
+void initializeDeadMachineInstructionElimPass(PassRegistry&);
+void initializeDomOnlyPrinterPass(PassRegistry&);
+void initializeDomOnlyViewerPass(PassRegistry&);
+void initializeDomPrinterPass(PassRegistry&);
+void initializeDomViewerPass(PassRegistry&);
+void initializeDominanceFrontierPass(PassRegistry&);
+void initializeDominatorTreePass(PassRegistry&);
+void initializeEdgeBundlesPass(PassRegistry&);
+void initializeEdgeProfilerPass(PassRegistry&);
+void initializeExpandPostRAPass(PassRegistry&);
+void initializePathProfilerPass(PassRegistry&);
+void initializeGCOVProfilerPass(PassRegistry&);
+void initializeAddressSanitizerPass(PassRegistry&);
+void initializeThreadSanitizerPass(PassRegistry&);
+void initializeEarlyCSEPass(PassRegistry&);
+void initializeExpandISelPseudosPass(PassRegistry&);
+void initializeFindUsedTypesPass(PassRegistry&);
+void initializeFunctionAttrsPass(PassRegistry&);
+void initializeGCInfoDeleterPass(PassRegistry&);
+void initializeGCMachineCodeAnalysisPass(PassRegistry&);
+void initializeGCModuleInfoPass(PassRegistry&);
+void initializeGVNPass(PassRegistry&);
+void initializeGlobalDCEPass(PassRegistry&);
+void initializeGlobalOptPass(PassRegistry&);
+void initializeGlobalsModRefPass(PassRegistry&);
+void initializeIPCPPass(PassRegistry&);
+void initializeIPSCCPPass(PassRegistry&);
+void initializeIVUsersPass(PassRegistry&);
+void initializeIfConverterPass(PassRegistry&);
+void initializeIndVarSimplifyPass(PassRegistry&);
+void initializeInstCombinerPass(PassRegistry&);
+void initializeInstCountPass(PassRegistry&);
+void initializeInstNamerPass(PassRegistry&);
+void initializeInternalizePassPass(PassRegistry&);
+void initializeIntervalPartitionPass(PassRegistry&);
+void initializeJumpThreadingPass(PassRegistry&);
+void initializeLCSSAPass(PassRegistry&);
+void initializeLICMPass(PassRegistry&);
+void initializeLazyValueInfoPass(PassRegistry&);
+void initializeLibCallAliasAnalysisPass(PassRegistry&);
+void initializeLintPass(PassRegistry&);
+void initializeLiveDebugVariablesPass(PassRegistry&);
+void initializeLiveIntervalsPass(PassRegistry&);
+void initializeLiveStacksPass(PassRegistry&);
+void initializeLiveVariablesPass(PassRegistry&);
+void initializeLoaderPassPass(PassRegistry&);
+void initializePathProfileLoaderPassPass(PassRegistry&);
+void initializeLocalStackSlotPassPass(PassRegistry&);
+void initializeLoopDeletionPass(PassRegistry&);
+void initializeLoopDependenceAnalysisPass(PassRegistry&);
+void initializeLoopExtractorPass(PassRegistry&);
+void initializeLoopInfoPass(PassRegistry&);
+void initializeLoopInstSimplifyPass(PassRegistry&);
+void initializeLoopRotatePass(PassRegistry&);
+void initializeLoopSimplifyPass(PassRegistry&);
+void initializeLoopStrengthReducePass(PassRegistry&);
+void initializeGlobalMergePass(PassRegistry&);
+void initializeLoopUnrollPass(PassRegistry&);
+void initializeLoopUnswitchPass(PassRegistry&);
+void initializeLoopIdiomRecognizePass(PassRegistry&);
+void initializeLowerAtomicPass(PassRegistry&);
+void initializeLowerExpectIntrinsicPass(PassRegistry&);
+void initializeLowerIntrinsicsPass(PassRegistry&);
+void initializeLowerInvokePass(PassRegistry&);
+void initializeLowerSwitchPass(PassRegistry&);
+void initializeMachineBlockFrequencyInfoPass(PassRegistry&);
+void initializeMachineBlockPlacementPass(PassRegistry&);
+void initializeMachineBlockPlacementStatsPass(PassRegistry&);
+void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
+void initializeMachineCSEPass(PassRegistry&);
+void initializeMachineDominatorTreePass(PassRegistry&);
+void initializeMachineLICMPass(PassRegistry&);
+void initializeMachineLoopInfoPass(PassRegistry&);
+void initializeMachineLoopRangesPass(PassRegistry&);
+void initializeMachineModuleInfoPass(PassRegistry&);
+void initializeMachineSchedulerPass(PassRegistry&);
+void initializeMachineSinkingPass(PassRegistry&);
+void initializeMachineVerifierPassPass(PassRegistry&);
+void initializeMemCpyOptPass(PassRegistry&);
+void initializeMemDepPrinterPass(PassRegistry&);
+void initializeMemoryDependenceAnalysisPass(PassRegistry&);
+void initializeMergeFunctionsPass(PassRegistry&);
+void initializeModuleDebugInfoPrinterPass(PassRegistry&);
+void initializeNoAAPass(PassRegistry&);
+void initializeNoProfileInfoPass(PassRegistry&);
+void initializeNoPathProfileInfoPass(PassRegistry&);
+void initializeObjCARCAliasAnalysisPass(PassRegistry&);
+void initializeObjCARCAPElimPass(PassRegistry&);
+void initializeObjCARCExpandPass(PassRegistry&);
+void initializeObjCARCContractPass(PassRegistry&);
+void initializeObjCARCOptPass(PassRegistry&);
+void initializeOptimalEdgeProfilerPass(PassRegistry&);
+void initializeOptimizePHIsPass(PassRegistry&);
+void initializePEIPass(PassRegistry&);
+void initializePHIEliminationPass(PassRegistry&);
+void initializePartialInlinerPass(PassRegistry&);
+void initializePeepholeOptimizerPass(PassRegistry&);
+void initializePostDomOnlyPrinterPass(PassRegistry&);
+void initializePostDomOnlyViewerPass(PassRegistry&);
+void initializePostDomPrinterPass(PassRegistry&);
+void initializePostDomViewerPass(PassRegistry&);
+void initializePostDominatorTreePass(PassRegistry&);
+void initializePostRASchedulerPass(PassRegistry&);
+void initializePreVerifierPass(PassRegistry&);
+void initializePrintDbgInfoPass(PassRegistry&);
+void initializePrintFunctionPassPass(PassRegistry&);
+void initializePrintModulePassPass(PassRegistry&);
+void initializeProcessImplicitDefsPass(PassRegistry&);
+void initializeProfileEstimatorPassPass(PassRegistry&);
+void initializeProfileInfoAnalysisGroup(PassRegistry&);
+void initializePathProfileInfoAnalysisGroup(PassRegistry&);
+void initializePathProfileVerifierPass(PassRegistry&);
+void initializeProfileVerifierPassPass(PassRegistry&);
+void initializePromotePassPass(PassRegistry&);
+void initializePruneEHPass(PassRegistry&);
+void initializeReassociatePass(PassRegistry&);
+void initializeRegToMemPass(PassRegistry&);
+void initializeRegionInfoPass(PassRegistry&);
+void initializeRegionOnlyPrinterPass(PassRegistry&);
+void initializeRegionOnlyViewerPass(PassRegistry&);
+void initializeRegionPrinterPass(PassRegistry&);
+void initializeRegionViewerPass(PassRegistry&);
+void initializeRenderMachineFunctionPass(PassRegistry&);
+void initializeSCCPPass(PassRegistry&);
+void initializeSROA_DTPass(PassRegistry&);
+void initializeSROA_SSAUpPass(PassRegistry&);
+void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
+void initializeScalarEvolutionPass(PassRegistry&);
+void initializeSimpleInlinerPass(PassRegistry&);
+void initializeRegisterCoalescerPass(PassRegistry&);
+void initializeSimplifyLibCallsPass(PassRegistry&);
+void initializeSingleLoopExtractorPass(PassRegistry&);
+void initializeSinkingPass(PassRegistry&);
+void initializeSlotIndexesPass(PassRegistry&);
+void initializeSpillPlacementPass(PassRegistry&);
+void initializeStackProtectorPass(PassRegistry&);
+void initializeStackSlotColoringPass(PassRegistry&);
+void initializeStripDeadDebugInfoPass(PassRegistry&);
+void initializeStripDeadPrototypesPassPass(PassRegistry&);
+void initializeStripDebugDeclarePass(PassRegistry&);
+void initializeStripNonDebugSymbolsPass(PassRegistry&);
+void initializeStripSymbolsPass(PassRegistry&);
+void initializeStrongPHIEliminationPass(PassRegistry&);
+void initializeTailCallElimPass(PassRegistry&);
+void initializeTailDuplicatePassPass(PassRegistry&);
+void initializeTargetPassConfigPass(PassRegistry&);
+void initializeTargetDataPass(PassRegistry&);
+void initializeTargetLibraryInfoPass(PassRegistry&);
+void initializeTwoAddressInstructionPassPass(PassRegistry&);
+void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
+void initializeUnifyFunctionExitNodesPass(PassRegistry&);
+void initializeUnreachableBlockElimPass(PassRegistry&);
+void initializeUnreachableMachineBlockElimPass(PassRegistry&);
+void initializeVerifierPass(PassRegistry&);
+void initializeVirtRegMapPass(PassRegistry&);
+void initializeInstSimplifierPass(PassRegistry&);
+void initializeUnpackMachineBundlesPass(PassRegistry&);
+void initializeFinalizeMachineBundlesPass(PassRegistry&);
+void initializeBBVectorizePass(PassRegistry&);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/InlineAsm.h b/contrib/llvm/include/llvm/InlineAsm.h
new file mode 100644
index 000000000000..37aa18bfff73
--- /dev/null
+++ b/contrib/llvm/include/llvm/InlineAsm.h
@@ -0,0 +1,297 @@
+//===-- llvm/InlineAsm.h - Class to represent inline asm strings-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents the inline asm strings, which are Value*'s that are
+// used as the callee operand of call instructions. InlineAsm's are uniqued
+// like constants, and created via InlineAsm::get(...).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INLINEASM_H
+#define LLVM_INLINEASM_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace llvm {
+
+class PointerType;
+class FunctionType;
+class Module;
+struct InlineAsmKeyType;
+template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
+ bool HasLargeKey>
+class ConstantUniqueMap;
+template<class ConstantClass, class TypeClass, class ValType>
+struct ConstantCreator;
+
+class InlineAsm : public Value {
+ friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>;
+ friend class ConstantUniqueMap<InlineAsmKeyType, const InlineAsmKeyType&,
+ PointerType, InlineAsm, false>;
+
+ InlineAsm(const InlineAsm &); // do not implement
+ void operator=(const InlineAsm&); // do not implement
+
+ std::string AsmString, Constraints;
+ bool HasSideEffects;
+ bool IsAlignStack;
+
+ InlineAsm(PointerType *Ty, const std::string &AsmString,
+ const std::string &Constraints, bool hasSideEffects,
+ bool isAlignStack);
+ virtual ~InlineAsm();
+
+ /// When the ConstantUniqueMap merges two types and makes two InlineAsms
+ /// identical, it destroys one of them with this method.
+ void destroyConstant();
+public:
+
+ /// InlineAsm::get - Return the specified uniqued inline asm string.
+ ///
+ static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
+ StringRef Constraints, bool hasSideEffects,
+ bool isAlignStack = false);
+
+ bool hasSideEffects() const { return HasSideEffects; }
+ bool isAlignStack() const { return IsAlignStack; }
+
+ /// getType - InlineAsm's are always pointers.
+ ///
+ PointerType *getType() const {
+ return reinterpret_cast<PointerType*>(Value::getType());
+ }
+
+ /// getFunctionType - InlineAsm's are always pointers to functions.
+ ///
+ FunctionType *getFunctionType() const;
+
+ const std::string &getAsmString() const { return AsmString; }
+ const std::string &getConstraintString() const { return Constraints; }
+
+ /// Verify - This static method can be used by the parser to check to see if
+ /// the specified constraint string is legal for the type. This returns true
+ /// if legal, false if not.
+ ///
+ static bool Verify(FunctionType *Ty, StringRef Constraints);
+
+ // Constraint String Parsing
+ enum ConstraintPrefix {
+ isInput, // 'x'
+ isOutput, // '=x'
+ isClobber // '~x'
+ };
+
+ typedef std::vector<std::string> ConstraintCodeVector;
+
+ struct SubConstraintInfo {
+ /// MatchingInput - If this is not -1, this is an output constraint where an
+ /// input constraint is required to match it (e.g. "0"). The value is the
+ /// constraint number that matches this one (for example, if this is
+ /// constraint #0 and constraint #4 has the value "0", this will be 4).
+ signed char MatchingInput;
+ /// Code - The constraint code, either the register name (in braces) or the
+ /// constraint letter/number.
+ ConstraintCodeVector Codes;
+ /// Default constructor.
+ SubConstraintInfo() : MatchingInput(-1) {}
+ };
+
+ typedef std::vector<SubConstraintInfo> SubConstraintInfoVector;
+ struct ConstraintInfo;
+ typedef std::vector<ConstraintInfo> ConstraintInfoVector;
+
+ struct ConstraintInfo {
+ /// Type - The basic type of the constraint: input/output/clobber
+ ///
+ ConstraintPrefix Type;
+
+ /// isEarlyClobber - "&": output operand writes result before inputs are all
+ /// read. This is only ever set for an output operand.
+ bool isEarlyClobber;
+
+ /// MatchingInput - If this is not -1, this is an output constraint where an
+ /// input constraint is required to match it (e.g. "0"). The value is the
+ /// constraint number that matches this one (for example, if this is
+ /// constraint #0 and constraint #4 has the value "0", this will be 4).
+ signed char MatchingInput;
+
+ /// hasMatchingInput - Return true if this is an output constraint that has
+ /// a matching input constraint.
+ bool hasMatchingInput() const { return MatchingInput != -1; }
+
+ /// isCommutative - This is set to true for a constraint that is commutative
+ /// with the next operand.
+ bool isCommutative;
+
+ /// isIndirect - True if this operand is an indirect operand. This means
+ /// that the address of the source or destination is present in the call
+ /// instruction, instead of it being returned or passed in explicitly. This
+ /// is represented with a '*' in the asm string.
+ bool isIndirect;
+
+ /// Code - The constraint code, either the register name (in braces) or the
+ /// constraint letter/number.
+ ConstraintCodeVector Codes;
+
+ /// isMultipleAlternative - '|': has multiple-alternative constraints.
+ bool isMultipleAlternative;
+
+ /// multipleAlternatives - If there are multiple alternative constraints,
+ /// this array will contain them. Otherwise it will be empty.
+ SubConstraintInfoVector multipleAlternatives;
+
+ /// The currently selected alternative constraint index.
+ unsigned currentAlternativeIndex;
+
+ ///Default constructor.
+ ConstraintInfo();
+
+ /// Copy constructor.
+ ConstraintInfo(const ConstraintInfo &other);
+
+ /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
+ /// fields in this structure. If the constraint string is not understood,
+ /// return true, otherwise return false.
+ bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
+
+ /// selectAlternative - Point this constraint to the alternative constraint
+ /// indicated by the index.
+ void selectAlternative(unsigned index);
+ };
+
+ /// ParseConstraints - Split up the constraint string into the specific
+ /// constraints and their prefixes. If this returns an empty vector, and if
+ /// the constraint string itself isn't empty, there was an error parsing.
+ static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
+
+ /// ParseConstraints - Parse the constraints of this inlineasm object,
+ /// returning them the same way that ParseConstraints(str) does.
+ ConstraintInfoVector ParseConstraints() const {
+ return ParseConstraints(Constraints);
+ }
+
+ // 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;
+ }
+
+
+ // These are helper methods for dealing with flags in the INLINEASM SDNode
+ // in the backend.
+
+ enum {
+ // Fixed operands on an INLINEASM SDNode.
+ Op_InputChain = 0,
+ Op_AsmString = 1,
+ Op_MDNode = 2,
+ Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack
+ Op_FirstOperand = 4,
+
+ // Fixed operands on an INLINEASM MachineInstr.
+ MIOp_AsmString = 0,
+ MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack
+ MIOp_FirstOperand = 2,
+
+ // Interpretation of the MIOp_ExtraInfo bit field.
+ Extra_HasSideEffects = 1,
+ Extra_IsAlignStack = 2,
+
+ // Inline asm operands map to multiple SDNode / MachineInstr operands.
+ // The first operand is an immediate describing the asm operand, the low
+ // bits is the kind:
+ Kind_RegUse = 1, // Input register, "r".
+ Kind_RegDef = 2, // Output register, "=r".
+ Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
+ Kind_Clobber = 4, // Clobbered register, "~r".
+ Kind_Imm = 5, // Immediate.
+ Kind_Mem = 6, // Memory operand, "m".
+
+ Flag_MatchingOperand = 0x80000000
+ };
+
+ static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
+ assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
+ assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind");
+ return Kind | (NumOps << 3);
+ }
+
+ /// getFlagWordForMatchingOp - Augment an existing flag word returned by
+ /// getFlagWord with information indicating that this input operand is tied
+ /// to a previous output operand.
+ static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
+ unsigned MatchedOperandNo) {
+ assert(MatchedOperandNo <= 0x7fff && "Too big matched operand");
+ assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+ return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
+ }
+
+ /// getFlagWordForRegClass - Augment an existing flag word returned by
+ /// getFlagWord with the required register class for the following register
+ /// operands.
+ /// A tied use operand cannot have a register class, use the register class
+ /// from the def operand instead.
+ static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
+ // Store RC + 1, reserve the value 0 to mean 'no register class'.
+ ++RC;
+ assert(RC <= 0x7fff && "Too large register class ID");
+ assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+ return InputFlag | (RC << 16);
+ }
+
+ static unsigned getKind(unsigned Flags) {
+ return Flags & 7;
+ }
+
+ static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
+ static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
+ static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
+ static bool isRegDefEarlyClobberKind(unsigned Flag) {
+ return getKind(Flag) == Kind_RegDefEarlyClobber;
+ }
+ static bool isClobberKind(unsigned Flag) {
+ return getKind(Flag) == Kind_Clobber;
+ }
+
+ /// getNumOperandRegisters - Extract the number of registers field from the
+ /// inline asm operand flag.
+ static unsigned getNumOperandRegisters(unsigned Flag) {
+ return (Flag & 0xffff) >> 3;
+ }
+
+ /// isUseOperandTiedToDef - Return true if the flag of the inline asm
+ /// operand indicates it is an use operand that's matched to a def operand.
+ static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
+ if ((Flag & Flag_MatchingOperand) == 0)
+ return false;
+ Idx = (Flag & ~Flag_MatchingOperand) >> 16;
+ return true;
+ }
+
+ /// hasRegClassConstraint - Returns true if the flag contains a register
+ /// class constraint. Sets RC to the register class ID.
+ static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) {
+ if (Flag & Flag_MatchingOperand)
+ return false;
+ unsigned High = Flag >> 16;
+ // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise
+ // stores RC + 1.
+ if (!High)
+ return false;
+ RC = High - 1;
+ return true;
+ }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/InstrTypes.h b/contrib/llvm/include/llvm/InstrTypes.h
new file mode 100644
index 000000000000..2529f24fe991
--- /dev/null
+++ b/contrib/llvm/include/llvm/InstrTypes.h
@@ -0,0 +1,854 @@
+//===-- llvm/InstrTypes.h - Important Instruction subclasses ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various meta classes of instructions that exist in the VM
+// representation. Specific concrete subclasses of these may be found in the
+// i*.h files...
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class LLVMContext;
+
+//===----------------------------------------------------------------------===//
+// TerminatorInst Class
+//===----------------------------------------------------------------------===//
+
+/// TerminatorInst - Subclasses of this class are all able to terminate a basic
+/// block. Thus, these are all the flow control type of operations.
+///
+class TerminatorInst : public Instruction {
+protected:
+ TerminatorInst(Type *Ty, Instruction::TermOps iType,
+ Use *Ops, unsigned NumOps,
+ Instruction *InsertBefore = 0)
+ : Instruction(Ty, iType, Ops, NumOps, InsertBefore) {}
+
+ TerminatorInst(Type *Ty, Instruction::TermOps iType,
+ Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
+ : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
+
+ // Out of line virtual method, so the vtable, etc has a home.
+ ~TerminatorInst();
+
+ /// Virtual methods - Terminators should overload these and provide inline
+ /// overrides of non-V methods.
+ virtual BasicBlock *getSuccessorV(unsigned idx) const = 0;
+ virtual unsigned getNumSuccessorsV() const = 0;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0;
+ virtual TerminatorInst *clone_impl() const = 0;
+public:
+
+ /// getNumSuccessors - Return the number of successors that this terminator
+ /// has.
+ unsigned getNumSuccessors() const {
+ return getNumSuccessorsV();
+ }
+
+ /// getSuccessor - Return the specified successor.
+ ///
+ BasicBlock *getSuccessor(unsigned idx) const {
+ return getSuccessorV(idx);
+ }
+
+ /// setSuccessor - Update the specified successor to point at the provided
+ /// block.
+ void setSuccessor(unsigned idx, BasicBlock *B) {
+ setSuccessorV(idx, B);
+ }
+
+ // 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();
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// UnaryInstruction Class
+//===----------------------------------------------------------------------===//
+
+class UnaryInstruction : public Instruction {
+ void *operator new(size_t, unsigned); // Do not implement
+
+protected:
+ UnaryInstruction(Type *Ty, unsigned iType, Value *V,
+ Instruction *IB = 0)
+ : Instruction(Ty, iType, &Op<0>(), 1, IB) {
+ Op<0>() = V;
+ }
+ UnaryInstruction(Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
+ : Instruction(Ty, iType, &Op<0>(), 1, IAE) {
+ Op<0>() = V;
+ }
+public:
+ // allocate space for exactly one operand
+ void *operator new(size_t s) {
+ return User::operator new(s, 1);
+ }
+
+ // Out of line virtual method, so the vtable, etc has a home.
+ ~UnaryInstruction();
+
+ /// Transparently provide more efficient getOperand methods.
+ 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 ||
+ I->getOpcode() == Instruction::VAArg ||
+ I->getOpcode() == Instruction::ExtractValue ||
+ (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<UnaryInstruction> :
+ public FixedNumOperandTraits<UnaryInstruction, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
+
+//===----------------------------------------------------------------------===//
+// BinaryOperator Class
+//===----------------------------------------------------------------------===//
+
+class BinaryOperator : public Instruction {
+ void *operator new(size_t, unsigned); // Do not implement
+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;
+public:
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// Create() - Construct a binary instruction, given the opcode and the two
+ /// operands. Optionally (if InstBefore is specified) insert the instruction
+ /// into a BasicBlock right before the specified instruction. The specified
+ /// Instruction is allowed to be a dereferenced end iterator.
+ ///
+ static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2,
+ const Twine &Name = Twine(),
+ Instruction *InsertBefore = 0);
+
+ /// Create() - Construct a binary instruction, given the opcode and the two
+ /// operands. Also automatically insert this instruction to the end of the
+ /// BasicBlock specified.
+ ///
+ static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2,
+ const Twine &Name, BasicBlock *InsertAtEnd);
+
+ /// Create* - These methods just forward to Create, and are useful when you
+ /// statically know what type of instruction you're going to create. These
+ /// helpers just save some typing.
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+ static BinaryOperator *Create##OPC(Value *V1, Value *V2, \
+ const Twine &Name = "") {\
+ return Create(Instruction::OPC, V1, V2, Name);\
+ }
+#include "llvm/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"
+#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"
+
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
+ BO->setHasNoSignedWrap(true);
+ return BO;
+ }
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+ BO->setHasNoSignedWrap(true);
+ return BO;
+ }
+ static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+ BO->setHasNoSignedWrap(true);
+ return BO;
+ }
+
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
+ BO->setHasNoUnsignedWrap(true);
+ return BO;
+ }
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+ BO->setHasNoUnsignedWrap(true);
+ return BO;
+ }
+ static BinaryOperator *CreateNUW(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+ BO->setHasNoUnsignedWrap(true);
+ return BO;
+ }
+
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name = "") {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name);
+ BO->setIsExact(true);
+ return BO;
+ }
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, BasicBlock *BB) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, BB);
+ BO->setIsExact(true);
+ return BO;
+ }
+ static BinaryOperator *CreateExact(BinaryOps Opc, Value *V1, Value *V2,
+ const Twine &Name, Instruction *I) {
+ BinaryOperator *BO = Create(Opc, V1, V2, Name, I);
+ BO->setIsExact(true);
+ return BO;
+ }
+
+#define DEFINE_HELPERS(OPC, NUWNSWEXACT) \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name = "") { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name); \
+ } \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name, BasicBlock *BB) { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, BB); \
+ } \
+ static BinaryOperator *Create ## NUWNSWEXACT ## OPC \
+ (Value *V1, Value *V2, const Twine &Name, Instruction *I) { \
+ return Create ## NUWNSWEXACT(Instruction::OPC, V1, V2, Name, I); \
+ }
+
+ DEFINE_HELPERS(Add, NSW) // CreateNSWAdd
+ DEFINE_HELPERS(Add, NUW) // CreateNUWAdd
+ DEFINE_HELPERS(Sub, NSW) // CreateNSWSub
+ DEFINE_HELPERS(Sub, NUW) // CreateNUWSub
+ DEFINE_HELPERS(Mul, NSW) // CreateNSWMul
+ DEFINE_HELPERS(Mul, NUW) // CreateNUWMul
+ DEFINE_HELPERS(Shl, NSW) // CreateNSWShl
+ DEFINE_HELPERS(Shl, NUW) // CreateNUWShl
+
+ DEFINE_HELPERS(SDiv, Exact) // CreateExactSDiv
+ DEFINE_HELPERS(UDiv, Exact) // CreateExactUDiv
+ DEFINE_HELPERS(AShr, Exact) // CreateExactAShr
+ DEFINE_HELPERS(LShr, Exact) // CreateExactLShr
+
+#undef DEFINE_HELPERS
+
+ /// Helper functions to construct and inspect unary operations (NEG and NOT)
+ /// via binary operators SUB and XOR:
+ ///
+ /// CreateNeg, CreateNot - Create the NEG and NOT
+ /// instructions out of SUB and XOR instructions.
+ ///
+ static BinaryOperator *CreateNeg(Value *Op, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *CreateNeg(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+ static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+ static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+ static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+ static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *CreateNot(Value *Op, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+
+ /// isNeg, isFNeg, isNot - Check if the given Value is a
+ /// NEG, FNeg, or NOT instruction.
+ ///
+ static bool isNeg(const Value *V);
+ static bool isFNeg(const Value *V);
+ static bool isNot(const Value *V);
+
+ /// getNegArgument, getNotArgument - Helper functions to extract the
+ /// unary argument of a NEG, FNEG or NOT operation implemented via
+ /// Sub, FSub, or Xor.
+ ///
+ static const Value *getNegArgument(const Value *BinOp);
+ static Value *getNegArgument( Value *BinOp);
+ static const Value *getFNegArgument(const Value *BinOp);
+ static Value *getFNegArgument( Value *BinOp);
+ static const Value *getNotArgument(const Value *BinOp);
+ static Value *getNotArgument( Value *BinOp);
+
+ BinaryOps getOpcode() const {
+ return static_cast<BinaryOps>(Instruction::getOpcode());
+ }
+
+ /// swapOperands - Exchange the two operands to this instruction.
+ /// This instruction is safe to use on any binary instruction and
+ /// does not modify the semantics of the instruction. If the instruction
+ /// cannot be reversed (ie, it's a Div), then return true.
+ ///
+ bool swapOperands();
+
+ /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction,
+ /// which must be an operator which supports this flag. See LangRef.html
+ /// for the meaning of this flag.
+ void setHasNoUnsignedWrap(bool b = true);
+
+ /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction,
+ /// which must be an operator which supports this flag. See LangRef.html
+ /// for the meaning of this flag.
+ void setHasNoSignedWrap(bool b = true);
+
+ /// setIsExact - Set or clear the exact flag on this instruction,
+ /// which must be an operator which supports this flag. See LangRef.html
+ /// for the meaning of this flag.
+ void setIsExact(bool b = true);
+
+ /// hasNoUnsignedWrap - Determine whether the no unsigned wrap flag is set.
+ bool hasNoUnsignedWrap() const;
+
+ /// hasNoSignedWrap - Determine whether the no signed wrap flag is set.
+ bool hasNoSignedWrap() const;
+
+ /// isExact - Determine whether the exact flag is set.
+ 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();
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<BinaryOperator> :
+ public FixedNumOperandTraits<BinaryOperator, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
+
+//===----------------------------------------------------------------------===//
+// CastInst Class
+//===----------------------------------------------------------------------===//
+
+/// CastInst - This is the base class for all instructions that perform data
+/// casts. It is simply provided so that instruction category testing
+/// can be performed with code like:
+///
+/// if (isa<CastInst>(Instr)) { ... }
+/// @brief Base class of casting instructions.
+class CastInst : public UnaryInstruction {
+ virtual void anchor();
+protected:
+ /// @brief Constructor with insert-before-instruction semantics for subclasses
+ CastInst(Type *Ty, unsigned iType, Value *S,
+ const Twine &NameStr = "", Instruction *InsertBefore = 0)
+ : UnaryInstruction(Ty, iType, S, InsertBefore) {
+ setName(NameStr);
+ }
+ /// @brief Constructor with insert-at-end-of-block semantics for subclasses
+ CastInst(Type *Ty, unsigned iType, Value *S,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : UnaryInstruction(Ty, iType, S, InsertAtEnd) {
+ setName(NameStr);
+ }
+public:
+ /// Provides a way to construct any of the CastInst subclasses using an
+ /// opcode instead of the subclass's constructor. The opcode must be in the
+ /// CastOps category (Instruction::isCast(opcode) returns true). This
+ /// constructor has insert-before-instruction semantics to automatically
+ /// insert the new CastInst before InsertBefore (if it is non-null).
+ /// @brief Construct any of the CastInst subclasses
+ static CastInst *Create(
+ Instruction::CastOps, ///< The opcode of the cast instruction
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which cast should be made
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+ /// Provides a way to construct any of the CastInst subclasses using an
+ /// opcode instead of the subclass's constructor. The opcode must be in the
+ /// CastOps category. This constructor has insert-at-end-of-block semantics
+ /// to automatically insert the new CastInst at the end of InsertAtEnd (if
+ /// its non-null).
+ /// @brief Construct any of the CastInst subclasses
+ static CastInst *Create(
+ Instruction::CastOps, ///< The opcode for the cast instruction
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which operand is casted
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a ZExt or BitCast cast instruction
+ static CastInst *CreateZExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which cast should be made
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt or BitCast cast instruction
+ static CastInst *CreateZExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which operand is casted
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a SExt or BitCast cast instruction
+ static CastInst *CreateSExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which cast should be made
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a SExt or BitCast cast instruction
+ static CastInst *CreateSExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which operand is casted
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a BitCast or a PtrToInt cast instruction
+ static CastInst *CreatePointerCast(
+ Value *S, ///< The pointer value to be casted (operand 0)
+ Type *Ty, ///< The type to which operand is casted
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a BitCast or a PtrToInt cast instruction
+ static CastInst *CreatePointerCast(
+ Value *S, ///< The pointer value to be casted (operand 0)
+ Type *Ty, ///< The type to which cast should be made
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+ static CastInst *CreateIntegerCast(
+ Value *S, ///< The pointer value to be casted (operand 0)
+ Type *Ty, ///< The type to which cast should be made
+ bool isSigned, ///< Whether to regard S as signed or not
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+ static CastInst *CreateIntegerCast(
+ Value *S, ///< The integer value to be casted (operand 0)
+ Type *Ty, ///< The integer type to which operand is casted
+ bool isSigned, ///< Whether to regard S as signed or not
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+ static CastInst *CreateFPCast(
+ Value *S, ///< The floating point value to be casted
+ Type *Ty, ///< The floating point type to cast to
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+ static CastInst *CreateFPCast(
+ Value *S, ///< The floating point value to be casted
+ Type *Ty, ///< The floating point type to cast to
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a Trunc or BitCast cast instruction
+ static CastInst *CreateTruncOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which cast should be made
+ const Twine &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a Trunc or BitCast cast instruction
+ static CastInst *CreateTruncOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ Type *Ty, ///< The type to which operand is casted
+ const Twine &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Check whether it is valid to call getCastOpcode for these types.
+ static bool isCastable(
+ Type *SrcTy, ///< The Type from which the value should be cast.
+ Type *DestTy ///< The Type to which the value should be cast.
+ );
+
+ /// Returns the opcode necessary to cast Val into Ty using usual casting
+ /// rules.
+ /// @brief Infer the opcode for cast operand and type
+ static Instruction::CastOps getCastOpcode(
+ const Value *Val, ///< The value to cast
+ bool SrcIsSigned, ///< Whether to treat the source as signed
+ Type *Ty, ///< The Type to which the value should be casted
+ bool DstIsSigned ///< Whether to treate the dest. as signed
+ );
+
+ /// There are several places where we need to know if a cast instruction
+ /// only deals with integer source and destination types. To simplify that
+ /// logic, this method is provided.
+ /// @returns true iff the cast has only integral typed operand and dest type.
+ /// @brief Determine if this is an integer-only cast.
+ bool isIntegerCast() const;
+
+ /// A lossless cast is one that does not alter the basic value. It implies
+ /// a no-op cast but is more stringent, preventing things like int->float,
+ /// long->double, or int->ptr.
+ /// @returns true iff the cast is lossless.
+ /// @brief Determine if this is a lossless cast.
+ bool isLosslessCast() const;
+
+ /// A no-op cast is one that can be effected without changing any bits.
+ /// It implies that the source and destination types are the same size. The
+ /// 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
+ /// 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.
+ static bool isNoopCast(
+ Instruction::CastOps Opcode, ///< Opcode of cast
+ Type *SrcTy, ///< SrcTy of cast
+ Type *DstTy, ///< DstTy of cast
+ Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null
+ );
+
+ /// @brief Determine if this cast is a no-op cast.
+ bool isNoopCast(
+ Type *IntPtrTy ///< Integer type corresponding to pointer
+ ) const;
+
+ /// Determine how a pair of casts can be eliminated, if they can be at all.
+ /// This is a helper function for both CastInst and ConstantExpr.
+ /// @returns 0 if the CastInst pair can't be eliminated
+ /// @returns Instruction::CastOps value for a cast that can replace
+ /// the pair, casting SrcTy to DstTy.
+ /// @brief Determine if a cast pair is eliminable
+ static unsigned isEliminableCastPair(
+ Instruction::CastOps firstOpcode, ///< Opcode of first cast
+ Instruction::CastOps secondOpcode, ///< Opcode of second cast
+ 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
+ );
+
+ /// @brief Return the opcode of this CastInst
+ Instruction::CastOps getOpcode() const {
+ return Instruction::CastOps(Instruction::getOpcode());
+ }
+
+ /// @brief Return the source type, as a convenience
+ Type* getSrcTy() const { return getOperand(0)->getType(); }
+ /// @brief Return the destination type, as a convenience
+ Type* getDestTy() const { return getType(); }
+
+ /// This method can be used to determine if a cast from S to DstTy using
+ /// Opcode op is valid or not.
+ /// @returns true iff the proposed cast is valid.
+ /// @brief Determine if a cast is valid without creating one.
+ 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();
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// CmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// 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
+protected:
+ CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
+ Value *LHS, Value *RHS, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+
+ CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
+ Value *LHS, Value *RHS, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+
+ virtual void Anchor() const; // Out of line virtual method.
+public:
+ /// This enumeration lists the possible predicates for CmpInst subclasses.
+ /// Values in the range 0-31 are reserved for FCmpInst, while values in the
+ /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
+ /// predicate values are not overlapping between the classes.
+ enum Predicate {
+ // Opcode U L G E Intuitive operation
+ FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
+ FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
+ FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
+ FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
+ FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
+ FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
+ FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
+ FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
+ FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
+ FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than
+ FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal
+ FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than
+ FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal
+ FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal
+ FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded)
+ FIRST_FCMP_PREDICATE = FCMP_FALSE,
+ LAST_FCMP_PREDICATE = FCMP_TRUE,
+ BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
+ ICMP_EQ = 32, ///< equal
+ ICMP_NE = 33, ///< not equal
+ ICMP_UGT = 34, ///< unsigned greater than
+ ICMP_UGE = 35, ///< unsigned greater or equal
+ ICMP_ULT = 36, ///< unsigned less than
+ ICMP_ULE = 37, ///< unsigned less or equal
+ ICMP_SGT = 38, ///< signed greater than
+ ICMP_SGE = 39, ///< signed greater or equal
+ ICMP_SLT = 40, ///< signed less than
+ ICMP_SLE = 41, ///< signed less or equal
+ FIRST_ICMP_PREDICATE = ICMP_EQ,
+ LAST_ICMP_PREDICATE = ICMP_SLE,
+ BAD_ICMP_PREDICATE = ICMP_SLE + 1
+ };
+
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+ /// Construct a compare instruction, given the opcode, the predicate and
+ /// the two operands. Optionally (if InstBefore is specified) insert the
+ /// instruction into a BasicBlock right before the specified instruction.
+ /// The specified Instruction is allowed to be a dereferenced end iterator.
+ /// @brief Create a CmpInst
+ static CmpInst *Create(OtherOps Op,
+ unsigned short predicate, Value *S1,
+ Value *S2, const Twine &Name = "",
+ Instruction *InsertBefore = 0);
+
+ /// Construct a compare instruction, given the opcode, the predicate and the
+ /// two operands. Also automatically insert this instruction to the end of
+ /// the BasicBlock specified.
+ /// @brief Create a CmpInst
+ static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1,
+ Value *S2, const Twine &Name, BasicBlock *InsertAtEnd);
+
+ /// @brief Get the opcode casted to the right type
+ OtherOps getOpcode() const {
+ return static_cast<OtherOps>(Instruction::getOpcode());
+ }
+
+ /// @brief Return the predicate for this instruction.
+ Predicate getPredicate() const {
+ return Predicate(getSubclassDataFromInstruction());
+ }
+
+ /// @brief Set the predicate for this instruction to the specified value.
+ void setPredicate(Predicate P) { setInstructionSubclassData(P); }
+
+ static bool isFPPredicate(Predicate P) {
+ return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE;
+ }
+
+ static bool isIntPredicate(Predicate P) {
+ return P >= FIRST_ICMP_PREDICATE && P <= LAST_ICMP_PREDICATE;
+ }
+
+ bool isFPPredicate() const { return isFPPredicate(getPredicate()); }
+ bool isIntPredicate() const { return isIntPredicate(getPredicate()); }
+
+
+ /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE,
+ /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+ /// @returns the inverse predicate for the instruction's current predicate.
+ /// @brief Return the inverse of the instruction's predicate.
+ Predicate getInversePredicate() const {
+ return getInversePredicate(getPredicate());
+ }
+
+ /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE,
+ /// OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+ /// @returns the inverse predicate for predicate provided in \p pred.
+ /// @brief Return the inverse of a given predicate
+ static Predicate getInversePredicate(Predicate pred);
+
+ /// For example, EQ->EQ, SLE->SGE, ULT->UGT,
+ /// OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
+ /// @returns the predicate that would be the result of exchanging the two
+ /// operands of the CmpInst instruction without changing the result
+ /// produced.
+ /// @brief Return the predicate as if the operands were swapped
+ Predicate getSwappedPredicate() const {
+ return getSwappedPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @brief Return the predicate as if the operands were swapped.
+ static Predicate getSwappedPredicate(Predicate pred);
+
+ /// @brief Provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Swap the operands and adjust predicate accordingly to retain
+ /// the same comparison.
+ void swapOperands();
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Determine if this CmpInst is commutative.
+ bool isCommutative() const;
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Determine if this is an equals/not equals predicate.
+ bool isEquality() const;
+
+ /// @returns true if the comparison is signed, false otherwise.
+ /// @brief Determine if this instruction is using a signed comparison.
+ bool isSigned() const {
+ return isSigned(getPredicate());
+ }
+
+ /// @returns true if the comparison is unsigned, false otherwise.
+ /// @brief Determine if this instruction is using an unsigned comparison.
+ bool isUnsigned() const {
+ return isUnsigned(getPredicate());
+ }
+
+ /// This is just a convenience.
+ /// @brief Determine if this is true when both operands are the same.
+ bool isTrueWhenEqual() const {
+ return isTrueWhenEqual(getPredicate());
+ }
+
+ /// This is just a convenience.
+ /// @brief Determine if this is false when both operands are the same.
+ bool isFalseWhenEqual() const {
+ return isFalseWhenEqual(getPredicate());
+ }
+
+ /// @returns true if the predicate is unsigned, false otherwise.
+ /// @brief Determine if the predicate is an unsigned operation.
+ static bool isUnsigned(unsigned short predicate);
+
+ /// @returns true if the predicate is signed, false otherwise.
+ /// @brief Determine if the predicate is an signed operation.
+ static bool isSigned(unsigned short predicate);
+
+ /// @brief Determine if the predicate is an ordered operation.
+ static bool isOrdered(unsigned short predicate);
+
+ /// @brief Determine if the predicate is an unordered operation.
+ static bool isUnordered(unsigned short predicate);
+
+ /// Determine if the predicate is true when comparing a value with itself.
+ static bool isTrueWhenEqual(unsigned short predicate);
+
+ /// Determine if the predicate is false when comparing a value with itself.
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+ /// @brief Create a result type for fcmp/icmp
+ static Type* makeCmpResultType(Type* opnd_type) {
+ if (VectorType* vt = dyn_cast<VectorType>(opnd_type)) {
+ return VectorType::get(Type::getInt1Ty(opnd_type->getContext()),
+ vt->getNumElements());
+ }
+ return Type::getInt1Ty(opnd_type->getContext());
+ }
+private:
+ // Shadow Value::setValueSubclassData with a private forwarding method so that
+ // subclasses cannot accidentally use it.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
+};
+
+
+// FIXME: these are redundant if CmpInst < BinaryOperator
+template <>
+struct OperandTraits<CmpInst> : public FixedNumOperandTraits<CmpInst, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Instruction.def b/contrib/llvm/include/llvm/Instruction.def
new file mode 100644
index 000000000000..e59a0528e90f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Instruction.def
@@ -0,0 +1,199 @@
+//===-- llvm/Instruction.def - File that describes Instructions -*- 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 descriptions of the various LLVM instructions. This is
+// used as a central place for enumerating the different instructions and
+// should eventually be the place to put comments about the instructions.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+// Provide definitions of macros so that users of this file do not have to
+// define everything to use it...
+//
+#ifndef FIRST_TERM_INST
+#define FIRST_TERM_INST(num)
+#endif
+#ifndef HANDLE_TERM_INST
+#ifndef HANDLE_INST
+#define HANDLE_TERM_INST(num, opcode, Class)
+#else
+#define HANDLE_TERM_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_TERM_INST
+#define LAST_TERM_INST(num)
+#endif
+
+#ifndef FIRST_BINARY_INST
+#define FIRST_BINARY_INST(num)
+#endif
+#ifndef HANDLE_BINARY_INST
+#ifndef HANDLE_INST
+#define HANDLE_BINARY_INST(num, opcode, instclass)
+#else
+#define HANDLE_BINARY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_BINARY_INST
+#define LAST_BINARY_INST(num)
+#endif
+
+#ifndef FIRST_MEMORY_INST
+#define FIRST_MEMORY_INST(num)
+#endif
+#ifndef HANDLE_MEMORY_INST
+#ifndef HANDLE_INST
+#define HANDLE_MEMORY_INST(num, opcode, Class)
+#else
+#define HANDLE_MEMORY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_MEMORY_INST
+#define LAST_MEMORY_INST(num)
+#endif
+
+#ifndef FIRST_CAST_INST
+#define FIRST_CAST_INST(num)
+#endif
+#ifndef HANDLE_CAST_INST
+#ifndef HANDLE_INST
+#define HANDLE_CAST_INST(num, opcode, Class)
+#else
+#define HANDLE_CAST_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_CAST_INST
+#define LAST_CAST_INST(num)
+#endif
+
+#ifndef FIRST_OTHER_INST
+#define FIRST_OTHER_INST(num)
+#endif
+#ifndef HANDLE_OTHER_INST
+#ifndef HANDLE_INST
+#define HANDLE_OTHER_INST(num, opcode, Class)
+#else
+#define HANDLE_OTHER_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_OTHER_INST
+#define LAST_OTHER_INST(num)
+#endif
+
+
+// Terminator Instructions - These instructions are used to terminate a basic
+// block of the program. Every basic block must end with one of these
+// instructions for it to be a well formed basic block.
+//
+ FIRST_TERM_INST ( 1)
+HANDLE_TERM_INST ( 1, Ret , ReturnInst)
+HANDLE_TERM_INST ( 2, Br , BranchInst)
+HANDLE_TERM_INST ( 3, Switch , SwitchInst)
+HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
+HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
+HANDLE_TERM_INST ( 6, Resume , ResumeInst)
+HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst)
+ LAST_TERM_INST ( 7)
+
+// Standard binary operators...
+ FIRST_BINARY_INST( 8)
+HANDLE_BINARY_INST( 8, Add , BinaryOperator)
+HANDLE_BINARY_INST( 9, FAdd , BinaryOperator)
+HANDLE_BINARY_INST(10, Sub , BinaryOperator)
+HANDLE_BINARY_INST(11, FSub , BinaryOperator)
+HANDLE_BINARY_INST(12, Mul , BinaryOperator)
+HANDLE_BINARY_INST(13, FMul , BinaryOperator)
+HANDLE_BINARY_INST(14, UDiv , BinaryOperator)
+HANDLE_BINARY_INST(15, SDiv , BinaryOperator)
+HANDLE_BINARY_INST(16, FDiv , BinaryOperator)
+HANDLE_BINARY_INST(17, URem , BinaryOperator)
+HANDLE_BINARY_INST(18, SRem , BinaryOperator)
+HANDLE_BINARY_INST(19, FRem , BinaryOperator)
+
+// Logical operators (integer operands)
+HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical)
+HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical)
+HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic)
+HANDLE_BINARY_INST(23, And , BinaryOperator)
+HANDLE_BINARY_INST(24, Or , BinaryOperator)
+HANDLE_BINARY_INST(25, Xor , BinaryOperator)
+ LAST_BINARY_INST(25)
+
+// Memory operators...
+ FIRST_MEMORY_INST(26)
+HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management
+HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs
+HANDLE_MEMORY_INST(28, Store , StoreInst )
+HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst)
+HANDLE_MEMORY_INST(30, Fence , FenceInst )
+HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst )
+HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst )
+ LAST_MEMORY_INST(32)
+
+// Cast operators ...
+// NOTE: The order matters here because CastInst::isEliminableCastPair
+// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
+ FIRST_CAST_INST(33)
+HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers
+HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers
+HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers
+HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt
+HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt
+HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point
+HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point
+HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point
+HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point
+HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer
+HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer
+HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast
+ LAST_CAST_INST(44)
+
+// Other operators...
+ FIRST_OTHER_INST(45)
+HANDLE_OTHER_INST(45, ICmp , ICmpInst ) // Integer comparison instruction
+HANDLE_OTHER_INST(46, FCmp , FCmpInst ) // Floating point comparison instr.
+HANDLE_OTHER_INST(47, PHI , PHINode ) // PHI node instruction
+HANDLE_OTHER_INST(48, Call , CallInst ) // Call a function
+HANDLE_OTHER_INST(49, Select , SelectInst ) // select instruction
+HANDLE_OTHER_INST(50, UserOp1, Instruction) // May be used internally in a pass
+HANDLE_OTHER_INST(51, UserOp2, Instruction) // Internal to passes only
+HANDLE_OTHER_INST(52, VAArg , VAArgInst ) // vaarg instruction
+HANDLE_OTHER_INST(53, ExtractElement, ExtractElementInst)// extract from vector
+HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector
+HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
+HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate
+HANDLE_OTHER_INST(57, InsertValue, InsertValueInst) // insert into aggregate
+HANDLE_OTHER_INST(58, LandingPad, LandingPadInst) // Landing pad instruction.
+ LAST_OTHER_INST(58)
+
+#undef FIRST_TERM_INST
+#undef HANDLE_TERM_INST
+#undef LAST_TERM_INST
+
+#undef FIRST_BINARY_INST
+#undef HANDLE_BINARY_INST
+#undef LAST_BINARY_INST
+
+#undef FIRST_MEMORY_INST
+#undef HANDLE_MEMORY_INST
+#undef LAST_MEMORY_INST
+
+#undef FIRST_CAST_INST
+#undef HANDLE_CAST_INST
+#undef LAST_CAST_INST
+
+#undef FIRST_OTHER_INST
+#undef HANDLE_OTHER_INST
+#undef LAST_OTHER_INST
+
+#ifdef HANDLE_INST
+#undef HANDLE_INST
+#endif
diff --git a/contrib/llvm/include/llvm/Instruction.h b/contrib/llvm/include/llvm/Instruction.h
new file mode 100644
index 000000000000..9c5ac4430f89
--- /dev/null
+++ b/contrib/llvm/include/llvm/Instruction.h
@@ -0,0 +1,377 @@
+//===-- llvm/Instruction.h - Instruction class definition -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Instruction class, which is the
+// base class for all of the LLVM instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INSTRUCTION_H
+#define LLVM_INSTRUCTION_H
+
+#include "llvm/User.h"
+#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/DebugLoc.h"
+
+namespace llvm {
+
+class LLVMContext;
+class MDNode;
+
+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
+
+ 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.
+ HasMetadataBit = 1 << 15
+ };
+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; }
+
+ /// removeFromParent - This method unlinks 'this' from the containing basic
+ /// block, but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing basic
+ /// block and deletes it.
+ ///
+ void eraseFromParent();
+
+ /// insertBefore - Insert an unlinked instructions into a basic block
+ /// immediately before the specified instruction.
+ void insertBefore(Instruction *InsertPos);
+
+ /// insertAfter - Insert an unlinked instructions into a basic block
+ /// immediately after the specified instruction.
+ void insertAfter(Instruction *InsertPos);
+
+ /// moveBefore - Unlink this instruction from its current basic block and
+ /// insert it into the basic block that MovePos lives in, right before
+ /// MovePos.
+ void moveBefore(Instruction *MovePos);
+
+ //===--------------------------------------------------------------------===//
+ // 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) {
+ return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
+ }
+
+ static inline bool isBinaryOp(unsigned Opcode) {
+ return Opcode >= BinaryOpsBegin && Opcode < BinaryOpsEnd;
+ }
+
+ /// @brief Determine if the Opcode is one of the shift instructions.
+ static inline bool isShift(unsigned Opcode) {
+ return Opcode >= Shl && Opcode <= AShr;
+ }
+
+ /// isLogicalShift - Return true if this is a logical shift left or a logical
+ /// shift right.
+ inline bool isLogicalShift() const {
+ return getOpcode() == Shl || getOpcode() == LShr;
+ }
+
+ /// isArithmeticShift - Return true if this is an arithmetic shift right.
+ inline bool isArithmeticShift() const {
+ return getOpcode() == AShr;
+ }
+
+ /// @brief Determine if the OpCode is one of the CastInst instructions.
+ static inline bool isCast(unsigned OpCode) {
+ return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // 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.
+ void getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs)const{
+ 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,
+ MDNode*> > &MDs) const {
+ 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.
+ void setMetadata(unsigned KindID, MDNode *Node);
+ void setMetadata(StringRef Kind, MDNode *Node);
+
+ /// 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; }
+
+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;
+ void getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned,MDNode*> > &)const;
+ void getAllMetadataOtherThanDebugLocImpl(SmallVectorImpl<std::pair<unsigned,
+ MDNode*> > &) const;
+ void clearMetadataHashEntries();
+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()); }
+ static bool isAssociative(unsigned op);
+
+ /// isCommutative - Return true if the instruction is commutative:
+ ///
+ /// Commutative operators satisfy: (x op y) === (y op x)
+ ///
+ /// In LLVM, these are the associative operators, plus SetEQ and SetNE, when
+ /// applied to any type.
+ ///
+ bool isCommutative() const { return isCommutative(getOpcode()); }
+ static bool isCommutative(unsigned op);
+
+ /// mayWriteToMemory - Return true if this instruction may modify memory.
+ ///
+ bool mayWriteToMemory() const;
+
+ /// mayReadFromMemory - Return true if this instruction may read memory.
+ ///
+ bool mayReadFromMemory() const;
+
+ /// mayReadOrWriteMemory - Return true if this instruction may read or
+ /// write memory.
+ ///
+ bool mayReadOrWriteMemory() const {
+ return mayReadFromMemory() || mayWriteToMemory();
+ }
+
+ /// mayThrow - Return true if this instruction may throw an exception.
+ ///
+ bool mayThrow() const;
+
+ /// mayHaveSideEffects - Return true if the instruction may have side effects.
+ ///
+ /// Note that this does not consider malloc and alloca to have side
+ /// effects because the newly allocated memory is completely invisible to
+ /// instructions which don't used the returned value. For cases where this
+ /// matters, isSafeToSpeculativelyExecute may be more appropriate.
+ bool mayHaveSideEffects() const {
+ return mayWriteToMemory() || mayThrow();
+ }
+
+ /// clone() - Create a copy of 'this' instruction that is identical in all
+ /// ways except the following:
+ /// * The instruction has no parent
+ /// * 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.
+ bool isIdenticalToWhenDefined(const Instruction *I) const;
+
+ /// 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
+ /// is similar to isIdenticalTo except the operands themselves don't have to
+ /// be identical.
+ /// @returns true if the specified instruction is the same operation as
+ /// the current one.
+ /// @brief Determine if one instruction is the same operation as another.
+ bool isSameOperationAs(const Instruction *I) 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;
+ }
+
+ //----------------------------------------------------------------------
+ // Exported enumerations.
+ //
+ enum TermOps { // These terminate basic blocks
+#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"
+ };
+
+ 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"
+ };
+
+ 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"
+ };
+
+ 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"
+ };
+
+ 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"
+ };
+private:
+ // Shadow Value::setValueSubclassData with a private forwarding method so that
+ // subclasses cannot accidentally use it.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
+ 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.
+template<>
+class PointerLikeTypeTraits<Instruction*> {
+ typedef Instruction* PT;
+public:
+ static inline void *getAsVoidPointer(PT P) { return P; }
+ static inline PT getFromVoidPointer(void *P) {
+ return static_cast<PT>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Instructions.h b/contrib/llvm/include/llvm/Instructions.h
new file mode 100644
index 000000000000..f6eaf04fd0d9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Instructions.h
@@ -0,0 +1,3598 @@
+//===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes the class definitions of all of the subclasses of the
+// Instruction class. This is meant to be an easy way to get access to all
+// instruction subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#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/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <iterator>
+
+namespace llvm {
+
+class ConstantInt;
+class ConstantRange;
+class APInt;
+class LLVMContext;
+
+enum AtomicOrdering {
+ NotAtomic = 0,
+ Unordered = 1,
+ Monotonic = 2,
+ // Consume = 3, // Not specified yet.
+ Acquire = 4,
+ Release = 5,
+ AcquireRelease = 6,
+ SequentiallyConsistent = 7
+};
+
+enum SynchronizationScope {
+ SingleThread = 0,
+ CrossThread = 1
+};
+
+//===----------------------------------------------------------------------===//
+// AllocaInst Class
+//===----------------------------------------------------------------------===//
+
+/// AllocaInst - an instruction to allocate memory on the stack
+///
+class AllocaInst : public UnaryInstruction {
+protected:
+ virtual AllocaInst *clone_impl() const;
+public:
+ explicit AllocaInst(Type *Ty, Value *ArraySize = 0,
+ const Twine &Name = "", Instruction *InsertBefore = 0);
+ AllocaInst(Type *Ty, Value *ArraySize,
+ const Twine &Name, BasicBlock *InsertAtEnd);
+
+ AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore = 0);
+ AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd);
+
+ AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
+ const Twine &Name = "", Instruction *InsertBefore = 0);
+ AllocaInst(Type *Ty, Value *ArraySize, unsigned Align,
+ const Twine &Name, BasicBlock *InsertAtEnd);
+
+ // Out of line virtual method, so the vtable, etc. has a home.
+ virtual ~AllocaInst();
+
+ /// isArrayAllocation - Return true if there is an allocation size parameter
+ /// to the allocation instruction that is not 1.
+ ///
+ bool isArrayAllocation() const;
+
+ /// getArraySize - Get the number of elements allocated. For a simple
+ /// allocation of a single element, this will return a constant 1 value.
+ ///
+ const Value *getArraySize() const { return getOperand(0); }
+ Value *getArraySize() { return getOperand(0); }
+
+ /// getType - Overload to return most specific pointer type
+ ///
+ PointerType *getType() const {
+ return reinterpret_cast<PointerType*>(Instruction::getType());
+ }
+
+ /// getAllocatedType - Return the type that is being allocated by the
+ /// instruction.
+ ///
+ Type *getAllocatedType() const;
+
+ /// getAlignment - Return the alignment of the memory that is being allocated
+ /// by the instruction.
+ ///
+ unsigned getAlignment() const {
+ return (1u << getSubclassDataFromInstruction()) >> 1;
+ }
+ void setAlignment(unsigned Align);
+
+ /// isStaticAlloca - Return true if this alloca is in the entry block of the
+ /// function and is a constant size. If so, the code generator will fold it
+ /// into the prolog/epilog code, so it is basically free.
+ 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);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// LoadInst Class
+//===----------------------------------------------------------------------===//
+
+/// LoadInst - an instruction for reading from memory. This uses the
+/// SubclassData field in Value to store whether or not the load is volatile.
+///
+class LoadInst : public UnaryInstruction {
+ void AssertOK();
+protected:
+ virtual LoadInst *clone_impl() const;
+public:
+ LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore);
+ LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ BasicBlock *InsertAtEnd);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ unsigned Align, Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ unsigned Align, BasicBlock *InsertAtEnd);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ unsigned Align, AtomicOrdering Order,
+ SynchronizationScope SynchScope = CrossThread,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
+ unsigned Align, AtomicOrdering Order,
+ SynchronizationScope SynchScope,
+ BasicBlock *InsertAtEnd);
+
+ LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore);
+ LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd);
+ explicit LoadInst(Value *Ptr, const char *NameStr = 0,
+ bool isVolatile = false, Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const char *NameStr, bool isVolatile,
+ BasicBlock *InsertAtEnd);
+
+ /// isVolatile - Return true if this is a load from a volatile memory
+ /// location.
+ ///
+ bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
+
+ /// setVolatile - Specify whether this is a volatile load or not.
+ ///
+ void setVolatile(bool V) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (V ? 1 : 0));
+ }
+
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
+ /// Returns the ordering effect of this fence.
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
+ }
+
+ /// Set the ordering constraint on this load. May not be Release or
+ /// AcquireRelease.
+ void setOrdering(AtomicOrdering Ordering) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) |
+ (Ordering << 7));
+ }
+
+ SynchronizationScope getSynchScope() const {
+ return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1);
+ }
+
+ /// Specify whether this load is ordered with respect to all
+ /// concurrently executing threads, or only with respect to signal handlers
+ /// executing in the same thread.
+ void setSynchScope(SynchronizationScope xthread) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) |
+ (xthread << 6));
+ }
+
+ bool isAtomic() const { return getOrdering() != NotAtomic; }
+ void setAtomic(AtomicOrdering Ordering,
+ SynchronizationScope SynchScope = CrossThread) {
+ setOrdering(Ordering);
+ setSynchScope(SynchScope);
+ }
+
+ bool isSimple() const { return !isAtomic() && !isVolatile(); }
+ bool isUnordered() const {
+ return getOrdering() <= Unordered && !isVolatile();
+ }
+
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+ static unsigned getPointerOperandIndex() { return 0U; }
+
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ }
+
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// StoreInst Class
+//===----------------------------------------------------------------------===//
+
+/// StoreInst - an instruction for storing to memory
+///
+class StoreInst : public Instruction {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void AssertOK();
+protected:
+ virtual StoreInst *clone_impl() const;
+public:
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+ StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
+ StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, BasicBlock *InsertAtEnd);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, AtomicOrdering Order,
+ SynchronizationScope SynchScope = CrossThread,
+ Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, AtomicOrdering Order,
+ SynchronizationScope SynchScope,
+ BasicBlock *InsertAtEnd);
+
+
+ /// isVolatile - Return true if this is a store to a volatile memory
+ /// location.
+ ///
+ bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
+
+ /// setVolatile - Specify whether this is a volatile store or not.
+ ///
+ void setVolatile(bool V) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (V ? 1 : 0));
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
+ /// Returns the ordering effect of this store.
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
+ }
+
+ /// Set the ordering constraint on this store. May not be Acquire or
+ /// AcquireRelease.
+ void setOrdering(AtomicOrdering Ordering) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) |
+ (Ordering << 7));
+ }
+
+ SynchronizationScope getSynchScope() const {
+ return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1);
+ }
+
+ /// Specify whether this store instruction is ordered with respect to all
+ /// concurrently executing threads, or only with respect to signal handlers
+ /// executing in the same thread.
+ void setSynchScope(SynchronizationScope xthread) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) |
+ (xthread << 6));
+ }
+
+ bool isAtomic() const { return getOrdering() != NotAtomic; }
+ void setAtomic(AtomicOrdering Ordering,
+ SynchronizationScope SynchScope = CrossThread) {
+ setOrdering(Ordering);
+ setSynchScope(SynchScope);
+ }
+
+ bool isSimple() const { return !isAtomic() && !isVolatile(); }
+ bool isUnordered() const {
+ return getOrdering() <= Unordered && !isVolatile();
+ }
+
+ Value *getValueOperand() { return getOperand(0); }
+ const Value *getValueOperand() const { return getOperand(0); }
+
+ Value *getPointerOperand() { return getOperand(1); }
+ const Value *getPointerOperand() const { return getOperand(1); }
+ static unsigned getPointerOperandIndex() { return 1U; }
+
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<StoreInst> : public FixedNumOperandTraits<StoreInst, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
+
+//===----------------------------------------------------------------------===//
+// FenceInst Class
+//===----------------------------------------------------------------------===//
+
+/// FenceInst - an instruction for ordering other memory operations
+///
+class FenceInst : public Instruction {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
+protected:
+ virtual FenceInst *clone_impl() const;
+public:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+
+ // Ordering may only be Acquire, Release, AcquireRelease, or
+ // SequentiallyConsistent.
+ FenceInst(LLVMContext &C, AtomicOrdering Ordering,
+ SynchronizationScope SynchScope = CrossThread,
+ Instruction *InsertBefore = 0);
+ FenceInst(LLVMContext &C, AtomicOrdering Ordering,
+ SynchronizationScope SynchScope,
+ BasicBlock *InsertAtEnd);
+
+ /// Returns the ordering effect of this fence.
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering(getSubclassDataFromInstruction() >> 1);
+ }
+
+ /// Set the ordering constraint on this fence. May only be Acquire, Release,
+ /// AcquireRelease, or SequentiallyConsistent.
+ void setOrdering(AtomicOrdering Ordering) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
+ (Ordering << 1));
+ }
+
+ SynchronizationScope getSynchScope() const {
+ return SynchronizationScope(getSubclassDataFromInstruction() & 1);
+ }
+
+ /// Specify whether this fence orders other operations with respect to all
+ /// concurrently executing threads, or only with respect to signal handlers
+ /// executing in the same thread.
+ void setSynchScope(SynchronizationScope xthread) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ xthread);
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// AtomicCmpXchgInst Class
+//===----------------------------------------------------------------------===//
+
+/// AtomicCmpXchgInst - an instruction that atomically checks whether a
+/// specified value is in a memory location, and, if it is, stores a new value
+/// there. Returns the value that was loaded.
+///
+class AtomicCmpXchgInst : public Instruction {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ void Init(Value *Ptr, Value *Cmp, Value *NewVal,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope);
+protected:
+ virtual AtomicCmpXchgInst *clone_impl() const;
+public:
+ // allocate space for exactly three operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 3);
+ }
+ AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ Instruction *InsertBefore = 0);
+ AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ BasicBlock *InsertAtEnd);
+
+ /// isVolatile - Return true if this is a cmpxchg from a volatile memory
+ /// location.
+ ///
+ bool isVolatile() const {
+ return getSubclassDataFromInstruction() & 1;
+ }
+
+ /// setVolatile - Specify whether this is a volatile cmpxchg.
+ ///
+ void setVolatile(bool V) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (unsigned)V);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// Set the ordering constraint on this cmpxchg.
+ void setOrdering(AtomicOrdering Ordering) {
+ assert(Ordering != NotAtomic &&
+ "CmpXchg instructions can only be atomic.");
+ setInstructionSubclassData((getSubclassDataFromInstruction() & 3) |
+ (Ordering << 2));
+ }
+
+ /// Specify whether this cmpxchg is atomic and orders other operations with
+ /// respect to all concurrently executing threads, or only with respect to
+ /// signal handlers executing in the same thread.
+ void setSynchScope(SynchronizationScope SynchScope) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) |
+ (SynchScope << 1));
+ }
+
+ /// Returns the ordering constraint on this cmpxchg.
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering(getSubclassDataFromInstruction() >> 2);
+ }
+
+ /// Returns whether this cmpxchg is atomic between threads or only within a
+ /// single thread.
+ SynchronizationScope getSynchScope() const {
+ return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1);
+ }
+
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+ static unsigned getPointerOperandIndex() { return 0U; }
+
+ Value *getCompareOperand() { return getOperand(1); }
+ const Value *getCompareOperand() const { return getOperand(1); }
+
+ Value *getNewValOperand() { return getOperand(2); }
+ const Value *getNewValOperand() const { return getOperand(2); }
+
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<AtomicCmpXchgInst> :
+ public FixedNumOperandTraits<AtomicCmpXchgInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value)
+
+//===----------------------------------------------------------------------===//
+// AtomicRMWInst Class
+//===----------------------------------------------------------------------===//
+
+/// AtomicRMWInst - an instruction that atomically reads a memory location,
+/// combines it with another value, and then stores the result back. Returns
+/// the old value.
+///
+class AtomicRMWInst : public Instruction {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+protected:
+ virtual AtomicRMWInst *clone_impl() const;
+public:
+ /// This enumeration lists the possible modifications atomicrmw can make. In
+ /// the descriptions, 'p' is the pointer to the instruction's memory location,
+ /// 'old' is the initial value of *p, and 'v' is the other value passed to the
+ /// instruction. These instructions always return 'old'.
+ enum BinOp {
+ /// *p = v
+ Xchg,
+ /// *p = old + v
+ Add,
+ /// *p = old - v
+ Sub,
+ /// *p = old & v
+ And,
+ /// *p = ~old & v
+ Nand,
+ /// *p = old | v
+ Or,
+ /// *p = old ^ v
+ Xor,
+ /// *p = old >signed v ? old : v
+ Max,
+ /// *p = old <signed v ? old : v
+ Min,
+ /// *p = old >unsigned v ? old : v
+ UMax,
+ /// *p = old <unsigned v ? old : v
+ UMin,
+
+ FIRST_BINOP = Xchg,
+ LAST_BINOP = UMin,
+ BAD_BINOP
+ };
+
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+ AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ Instruction *InsertBefore = 0);
+ AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ BasicBlock *InsertAtEnd);
+
+ BinOp getOperation() const {
+ return static_cast<BinOp>(getSubclassDataFromInstruction() >> 5);
+ }
+
+ void setOperation(BinOp Operation) {
+ unsigned short SubclassData = getSubclassDataFromInstruction();
+ setInstructionSubclassData((SubclassData & 31) |
+ (Operation << 5));
+ }
+
+ /// isVolatile - Return true if this is a RMW on a volatile memory location.
+ ///
+ bool isVolatile() const {
+ return getSubclassDataFromInstruction() & 1;
+ }
+
+ /// setVolatile - Specify whether this is a volatile RMW or not.
+ ///
+ void setVolatile(bool V) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (unsigned)V);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// Set the ordering constraint on this RMW.
+ void setOrdering(AtomicOrdering Ordering) {
+ assert(Ordering != NotAtomic &&
+ "atomicrmw instructions can only be atomic.");
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 2)) |
+ (Ordering << 2));
+ }
+
+ /// Specify whether this RMW orders other operations with respect to all
+ /// concurrently executing threads, or only with respect to signal handlers
+ /// executing in the same thread.
+ void setSynchScope(SynchronizationScope SynchScope) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) |
+ (SynchScope << 1));
+ }
+
+ /// Returns the ordering constraint on this RMW.
+ AtomicOrdering getOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+ }
+
+ /// Returns whether this RMW is atomic between threads or only within a
+ /// single thread.
+ SynchronizationScope getSynchScope() const {
+ return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1);
+ }
+
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+ static unsigned getPointerOperandIndex() { return 0U; }
+
+ Value *getValOperand() { return getOperand(1); }
+ const Value *getValOperand() const { return getOperand(1); }
+
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperand()->getType())->getAddressSpace();
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ void Init(BinOp Operation, Value *Ptr, Value *Val,
+ AtomicOrdering Ordering, SynchronizationScope SynchScope);
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<AtomicRMWInst>
+ : public FixedNumOperandTraits<AtomicRMWInst,2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicRMWInst, Value)
+
+//===----------------------------------------------------------------------===//
+// GetElementPtrInst Class
+//===----------------------------------------------------------------------===//
+
+// checkGEPType - Simple wrapper function to give a better assertion failure
+// message on bad indexes for a gep instruction.
+//
+static inline Type *checkGEPType(Type *Ty) {
+ assert(Ty && "Invalid GetElementPtrInst indices for type!");
+ return Ty;
+}
+
+/// GetElementPtrInst - an instruction for type-safe pointer arithmetic to
+/// access elements of arrays and structs
+///
+class GetElementPtrInst : public Instruction {
+ GetElementPtrInst(const GetElementPtrInst &GEPI);
+ void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
+
+ /// Constructors - Create a getelementptr instruction with a base pointer an
+ /// list of indices. The first ctor can optionally insert before an existing
+ /// instruction, the second appends the new instruction to the specified
+ /// BasicBlock.
+ inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
+ unsigned Values, const Twine &NameStr,
+ Instruction *InsertBefore);
+ inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
+ unsigned Values, const Twine &NameStr,
+ BasicBlock *InsertAtEnd);
+protected:
+ virtual GetElementPtrInst *clone_impl() const;
+public:
+ static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ unsigned Values = 1 + unsigned(IdxList.size());
+ return new(Values)
+ GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore);
+ }
+ static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = 1 + unsigned(IdxList.size());
+ return new(Values)
+ GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd);
+ }
+
+ /// Create an "inbounds" getelementptr. See the documentation for the
+ /// "inbounds" flag in LangRef.html for details.
+ static GetElementPtrInst *CreateInBounds(Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore);
+ GEP->setIsInBounds(true);
+ return GEP;
+ }
+ static GetElementPtrInst *CreateInBounds(Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd);
+ GEP->setIsInBounds(true);
+ return GEP;
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // getType - Overload to return most specific pointer type...
+ PointerType *getType() const {
+ return reinterpret_cast<PointerType*>(Instruction::getType());
+ }
+
+ /// getIndexedType - Returns the type of the element that would be loaded with
+ /// a load instruction with the specified parameters.
+ ///
+ /// Null is returned if the indices are invalid for the specified
+ /// pointer type.
+ ///
+ static Type *getIndexedType(Type *Ptr, ArrayRef<Value *> IdxList);
+ 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(); }
+ inline const_op_iterator idx_end() const { return op_end(); }
+
+ Value *getPointerOperand() {
+ return getOperand(0);
+ }
+ const Value *getPointerOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getPointerOperandIndex() {
+ 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();
+ }
+
+ /// 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));
+ // Vector GEP
+ if (Ptr->getType()->isVectorTy()) {
+ unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements();
+ return VectorType::get(PtrTy, NumElem);
+ }
+
+ // Scalar GEP
+ return PtrTy;
+ }
+
+ unsigned getNumIndices() const { // Note: always non-negative
+ return getNumOperands() - 1;
+ }
+
+ bool hasIndices() const {
+ return getNumOperands() > 1;
+ }
+
+ /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+ /// zeros. If so, the result pointer and the first operand have the same
+ /// value, just potentially different types.
+ bool hasAllZeroIndices() const;
+
+ /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+ /// constant integers. If so, the result pointer and the first operand have
+ /// a constant offset between them.
+ bool hasAllConstantIndices() const;
+
+ /// setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
+ /// See LangRef.html for the meaning of inbounds on a getelementptr.
+ void setIsInBounds(bool b = true);
+
+ /// isInBounds - Determine whether the GEP has the inbounds flag.
+ bool isInBounds() 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);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<GetElementPtrInst> :
+ public VariadicOperandTraits<GetElementPtrInst, 1> {
+};
+
+GetElementPtrInst::GetElementPtrInst(Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ unsigned Values,
+ const Twine &NameStr,
+ Instruction *InsertBefore)
+ : Instruction(getGEPReturnType(Ptr, IdxList),
+ GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertBefore) {
+ init(Ptr, IdxList, NameStr);
+}
+GetElementPtrInst::GetElementPtrInst(Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ unsigned Values,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd)
+ : Instruction(getGEPReturnType(Ptr, IdxList),
+ GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertAtEnd) {
+ init(Ptr, IdxList, NameStr);
+}
+
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
+
+
+//===----------------------------------------------------------------------===//
+// ICmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// 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.
+class ICmpInst: public CmpInst {
+protected:
+ /// @brief Clone an identical ICmpInst
+ virtual ICmpInst *clone_impl() const;
+public:
+ /// @brief Constructor with insert-before-instruction semantics.
+ ICmpInst(
+ Instruction *InsertBefore, ///< Where to insert
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const Twine &NameStr = "" ///< Name of the instruction
+ ) : CmpInst(makeCmpResultType(LHS->getType()),
+ Instruction::ICmp, pred, LHS, RHS, NameStr,
+ InsertBefore) {
+ assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
+ pred <= CmpInst::LAST_ICMP_PREDICATE &&
+ "Invalid ICmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to ICmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->getScalarType()->isPointerTy()) &&
+ "Invalid operand types for ICmp instruction");
+ }
+
+ /// @brief Constructor with insert-at-end semantics.
+ ICmpInst(
+ BasicBlock &InsertAtEnd, ///< Block to insert into.
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const Twine &NameStr = "" ///< Name of the instruction
+ ) : CmpInst(makeCmpResultType(LHS->getType()),
+ Instruction::ICmp, pred, LHS, RHS, NameStr,
+ &InsertAtEnd) {
+ assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
+ pred <= CmpInst::LAST_ICMP_PREDICATE &&
+ "Invalid ICmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to ICmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->isPointerTy()) &&
+ "Invalid operand types for ICmp instruction");
+ }
+
+ /// @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
+ Value *RHS, ///< The right-hand-side of the expression
+ const Twine &NameStr = "" ///< Name of the instruction
+ ) : CmpInst(makeCmpResultType(LHS->getType()),
+ Instruction::ICmp, pred, LHS, RHS, NameStr) {
+ assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
+ pred <= CmpInst::LAST_ICMP_PREDICATE &&
+ "Invalid ICmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to ICmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
+ getOperand(0)->getType()->getScalarType()->isPointerTy()) &&
+ "Invalid operand types for ICmp instruction");
+ }
+
+ /// 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
+ 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.
+ 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
+ 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.
+ static Predicate getUnsignedPredicate(Predicate pred);
+
+ /// isEquality - Return true if this predicate is either EQ or NE. This also
+ /// tests for commutativity.
+ static bool isEquality(Predicate P) {
+ return P == ICMP_EQ || P == ICMP_NE;
+ }
+
+ /// isEquality - Return true if this predicate is either EQ or NE. This also
+ /// tests for commutativity.
+ bool isEquality() const {
+ return isEquality(getPredicate());
+ }
+
+ /// @returns true if the predicate of this ICmpInst 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).
+ ///
+ bool isRelational() const {
+ return !isEquality();
+ }
+
+ /// isRelational - Return true if the predicate is relational (not EQ or NE).
+ ///
+ static bool isRelational(Predicate P) {
+ return !isEquality(P);
+ }
+
+ /// Initialize a set of values that all satisfy the predicate with C.
+ /// @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.
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+};
+
+//===----------------------------------------------------------------------===//
+// FCmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// 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.
+class FCmpInst: public CmpInst {
+protected:
+ /// @brief Clone an identical FCmpInst
+ virtual FCmpInst *clone_impl() const;
+public:
+ /// @brief Constructor with insert-before-instruction semantics.
+ FCmpInst(
+ Instruction *InsertBefore, ///< Where to insert
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const Twine &NameStr = "" ///< Name of the instruction
+ ) : CmpInst(makeCmpResultType(LHS->getType()),
+ Instruction::FCmp, pred, LHS, RHS, NameStr,
+ InsertBefore) {
+ assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
+ "Invalid FCmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to FCmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+ "Invalid operand types for FCmp instruction");
+ }
+
+ /// @brief Constructor with insert-at-end semantics.
+ FCmpInst(
+ BasicBlock &InsertAtEnd, ///< Block to insert into.
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const Twine &NameStr = "" ///< Name of the instruction
+ ) : CmpInst(makeCmpResultType(LHS->getType()),
+ Instruction::FCmp, pred, LHS, RHS, NameStr,
+ &InsertAtEnd) {
+ assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
+ "Invalid FCmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to FCmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+ "Invalid operand types for FCmp instruction");
+ }
+
+ /// @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
+ Value *RHS, ///< The right-hand-side of the expression
+ const Twine &NameStr = "" ///< Name of the instruction
+ ) : CmpInst(makeCmpResultType(LHS->getType()),
+ Instruction::FCmp, pred, LHS, RHS, NameStr) {
+ assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
+ "Invalid FCmp predicate value");
+ assert(getOperand(0)->getType() == getOperand(1)->getType() &&
+ "Both operands to FCmp instruction are not of the same type!");
+ // Check that the operands are the right type
+ assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
+ "Invalid operand types for FCmp instruction");
+ }
+
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// @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.
+ bool isCommutative() const {
+ return isEquality() ||
+ getPredicate() == FCMP_FALSE ||
+ getPredicate() == FCMP_TRUE ||
+ getPredicate() == FCMP_ORD ||
+ getPredicate() == FCMP_UNO;
+ }
+
+ /// @returns true if the predicate is relational (not EQ or NE).
+ /// @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.
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::FCmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// CallInst - This class represents a function call, abstracting a target
+/// machine's calling convention. This class uses low bit of the SubClassData
+/// field to indicate whether or not this is a tail call. The rest of the bits
+/// hold the calling convention of the call.
+///
+class CallInst : public Instruction {
+ AttrListPtr 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
+ 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
+ inline CallInst(Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+ CallInst(Value *F, Value *Actual, const Twine &NameStr,
+ Instruction *InsertBefore);
+ CallInst(Value *F, Value *Actual, const Twine &NameStr,
+ BasicBlock *InsertAtEnd);
+ explicit CallInst(Value *F, const Twine &NameStr,
+ Instruction *InsertBefore);
+ CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+ virtual CallInst *clone_impl() const;
+public:
+ static CallInst *Create(Value *Func,
+ ArrayRef<Value *> Args,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new(unsigned(Args.size() + 1))
+ CallInst(Func, Args, NameStr, InsertBefore);
+ }
+ static CallInst *Create(Value *Func,
+ ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd) {
+ return new(unsigned(Args.size() + 1))
+ CallInst(Func, Args, NameStr, InsertAtEnd);
+ }
+ static CallInst *Create(Value *F, const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new(1) CallInst(F, NameStr, InsertBefore);
+ }
+ static CallInst *Create(Value *F, const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new(1) CallInst(F, NameStr, InsertAtEnd);
+ }
+ /// CreateMalloc - Generate the IR for a call to malloc:
+ /// 1. Compute the malloc call's argument as the specified type's size,
+ /// possibly multiplied by the array size if the array size is not
+ /// constant 1.
+ /// 2. Call malloc with that argument.
+ /// 3. Bitcast the result of the malloc call to the specified type.
+ static Instruction *CreateMalloc(Instruction *InsertBefore,
+ Type *IntPtrTy, Type *AllocTy,
+ Value *AllocSize, Value *ArraySize = 0,
+ Function* MallocF = 0,
+ const Twine &Name = "");
+ static Instruction *CreateMalloc(BasicBlock *InsertAtEnd,
+ Type *IntPtrTy, Type *AllocTy,
+ Value *AllocSize, Value *ArraySize = 0,
+ Function* MallocF = 0,
+ const Twine &Name = "");
+ /// CreateFree - Generate the IR for a call to the builtin free function.
+ static Instruction* CreateFree(Value* Source, Instruction *InsertBefore);
+ static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd);
+
+ ~CallInst();
+
+ bool isTailCall() const { return getSubclassDataFromInstruction() & 1; }
+ void setTailCall(bool isTC = true) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ unsigned(isTC));
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getNumArgOperands - Return the number of call arguments.
+ ///
+ unsigned getNumArgOperands() const { return getNumOperands() - 1; }
+
+ /// getArgOperand/setArgOperand - Return/set the i-th call argument.
+ ///
+ Value *getArgOperand(unsigned i) const { return getOperand(i); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+ /// getCallingConv/setCallingConv - Get or set the calling convention of this
+ /// function call.
+ CallingConv::ID getCallingConv() const {
+ return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 1);
+ }
+ void setCallingConv(CallingConv::ID CC) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
+ (static_cast<unsigned>(CC) << 1));
+ }
+
+ /// getAttributes - Return the parameter attributes for this call.
+ ///
+ const AttrListPtr &getAttributes() const { return AttributeList; }
+
+ /// setAttributes - Set the parameter attributes for this call.
+ ///
+ void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; }
+
+ /// addAttribute - adds the attribute to the list of attributes.
+ void addAttribute(unsigned i, Attributes attr);
+
+ /// removeAttribute - removes the attribute from the list of attributes.
+ void removeAttribute(unsigned i, Attributes attr);
+
+ /// @brief Determine whether the call or the callee has the given attribute.
+ bool paramHasAttr(unsigned i, Attributes attr) const;
+
+ /// @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.
+ bool isNoInline() const { return paramHasAttr(~0, Attribute::NoInline); }
+ void setIsNoInline(bool Value = true) {
+ if (Value) addAttribute(~0, Attribute::NoInline);
+ else removeAttribute(~0, Attribute::NoInline);
+ }
+
+ /// @brief Return true if the call can return twice
+ bool canReturnTwice() const {
+ return paramHasAttr(~0, Attribute::ReturnsTwice);
+ }
+ void setCanReturnTwice(bool Value = true) {
+ if (Value) addAttribute(~0, Attribute::ReturnsTwice);
+ else removeAttribute(~0, Attribute::ReturnsTwice);
+ }
+
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const {
+ return paramHasAttr(~0, Attribute::ReadNone);
+ }
+ void setDoesNotAccessMemory(bool NotAccessMemory = true) {
+ if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
+ else removeAttribute(~0, Attribute::ReadNone);
+ }
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
+ }
+ void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
+ if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
+ else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
+ }
+
+ /// @brief Determine if the call cannot return.
+ bool doesNotReturn() const { return paramHasAttr(~0, Attribute::NoReturn); }
+ void setDoesNotReturn(bool DoesNotReturn = true) {
+ if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
+ else removeAttribute(~0, Attribute::NoReturn);
+ }
+
+ /// @brief Determine if the call cannot unwind.
+ bool doesNotThrow() const { return paramHasAttr(~0, Attribute::NoUnwind); }
+ void setDoesNotThrow(bool DoesNotThrow = true) {
+ if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
+ else removeAttribute(~0, Attribute::NoUnwind);
+ }
+
+ /// @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.
+ bool hasByValArgument() const {
+ return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+ }
+
+ /// getCalledFunction - Return the function called, or null if this is an
+ /// indirect function invocation.
+ ///
+ Function *getCalledFunction() const {
+ return dyn_cast<Function>(Op<-1>());
+ }
+
+ /// getCalledValue - Get a pointer to the function that is invoked by this
+ /// instruction.
+ const Value *getCalledValue() const { return Op<-1>(); }
+ Value *getCalledValue() { return Op<-1>(); }
+
+ /// setCalledFunction - Set the function called.
+ void setCalledFunction(Value* Fn) {
+ Op<-1>() = Fn;
+ }
+
+ /// isInlineAsm - Check if this call is an inline asm statement.
+ bool isInlineAsm() const {
+ return isa<InlineAsm>(Op<-1>());
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<CallInst> : public VariadicOperandTraits<CallInst, 1> {
+};
+
+CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
+ unsigned(Args.size() + 1), InsertAtEnd) {
+ init(Func, Args, NameStr);
+}
+
+CallInst::CallInst(Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr, Instruction *InsertBefore)
+ : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Call,
+ OperandTraits<CallInst>::op_end(this) - (Args.size() + 1),
+ unsigned(Args.size() + 1), InsertBefore) {
+ init(Func, Args, NameStr);
+}
+
+
+// Note: if you get compile errors about private methods then
+// please update your code to use the high-level operand
+// interfaces. See line 943 above.
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value)
+
+//===----------------------------------------------------------------------===//
+// SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// SelectInst - This class represents the LLVM 'select' instruction.
+///
+class SelectInst : public Instruction {
+ void init(Value *C, Value *S1, Value *S2) {
+ assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select");
+ Op<0>() = C;
+ Op<1>() = S1;
+ Op<2>() = S2;
+ }
+
+ SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
+ Instruction *InsertBefore)
+ : Instruction(S1->getType(), Instruction::Select,
+ &Op<0>(), 3, InsertBefore) {
+ init(C, S1, S2);
+ setName(NameStr);
+ }
+ SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
+ BasicBlock *InsertAtEnd)
+ : Instruction(S1->getType(), Instruction::Select,
+ &Op<0>(), 3, InsertAtEnd) {
+ init(C, S1, S2);
+ setName(NameStr);
+ }
+protected:
+ virtual SelectInst *clone_impl() const;
+public:
+ static SelectInst *Create(Value *C, Value *S1, Value *S2,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new(3) SelectInst(C, S1, S2, NameStr, InsertBefore);
+ }
+ static SelectInst *Create(Value *C, Value *S1, Value *S2,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new(3) SelectInst(C, S1, S2, NameStr, InsertAtEnd);
+ }
+
+ const Value *getCondition() const { return Op<0>(); }
+ const Value *getTrueValue() const { return Op<1>(); }
+ const Value *getFalseValue() const { return Op<2>(); }
+ Value *getCondition() { return Op<0>(); }
+ Value *getTrueValue() { return Op<1>(); }
+ Value *getFalseValue() { return Op<2>(); }
+
+ /// areInvalidOperands - Return a string if the specified operands are invalid
+ /// for a select operation, otherwise return null.
+ static const char *areInvalidOperands(Value *Cond, Value *True, Value *False);
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ OtherOps getOpcode() const {
+ return static_cast<OtherOps>(Instruction::getOpcode());
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<SelectInst> : public FixedNumOperandTraits<SelectInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value)
+
+//===----------------------------------------------------------------------===//
+// VAArgInst Class
+//===----------------------------------------------------------------------===//
+
+/// VAArgInst - This class represents the va_arg llvm instruction, which returns
+/// an argument of the specified type given a va_list and increments that list
+///
+class VAArgInst : public UnaryInstruction {
+protected:
+ virtual VAArgInst *clone_impl() const;
+
+public:
+ VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "",
+ Instruction *InsertBefore = 0)
+ : UnaryInstruction(Ty, VAArg, List, InsertBefore) {
+ setName(NameStr);
+ }
+ VAArgInst(Value *List, Type *Ty, const Twine &NameStr,
+ BasicBlock *InsertAtEnd)
+ : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) {
+ setName(NameStr);
+ }
+
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ExtractElementInst Class
+//===----------------------------------------------------------------------===//
+
+/// ExtractElementInst - This instruction extracts a single (scalar)
+/// element from a VectorType value
+///
+class ExtractElementInst : public Instruction {
+ ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr = "",
+ Instruction *InsertBefore = 0);
+ ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr,
+ BasicBlock *InsertAtEnd);
+protected:
+ virtual ExtractElementInst *clone_impl() const;
+
+public:
+ static ExtractElementInst *Create(Value *Vec, Value *Idx,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertBefore);
+ }
+ static ExtractElementInst *Create(Value *Vec, Value *Idx,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new(2) ExtractElementInst(Vec, Idx, NameStr, InsertAtEnd);
+ }
+
+ /// isValidOperands - Return true if an extractelement instruction can be
+ /// formed with the specified operands.
+ static bool isValidOperands(const Value *Vec, const Value *Idx);
+
+ Value *getVectorOperand() { return Op<0>(); }
+ Value *getIndexOperand() { return Op<1>(); }
+ const Value *getVectorOperand() const { return Op<0>(); }
+ const Value *getIndexOperand() const { return Op<1>(); }
+
+ VectorType *getVectorOperandType() const {
+ return reinterpret_cast<VectorType*>(getVectorOperand()->getType());
+ }
+
+
+ /// Transparently provide more efficient getOperand methods.
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<ExtractElementInst> :
+ public FixedNumOperandTraits<ExtractElementInst, 2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value)
+
+//===----------------------------------------------------------------------===//
+// InsertElementInst Class
+//===----------------------------------------------------------------------===//
+
+/// InsertElementInst - This instruction inserts a single (scalar)
+/// element into a VectorType value
+///
+class InsertElementInst : public Instruction {
+ InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0);
+ InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+ virtual InsertElementInst *clone_impl() const;
+
+public:
+ static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore);
+ }
+ static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new(3) InsertElementInst(Vec, NewElt, Idx, NameStr, InsertAtEnd);
+ }
+
+ /// isValidOperands - Return true if an insertelement instruction can be
+ /// formed with the specified operands.
+ static bool isValidOperands(const Value *Vec, const Value *NewElt,
+ const Value *Idx);
+
+ /// getType - Overload to return most specific vector type.
+ ///
+ VectorType *getType() const {
+ return reinterpret_cast<VectorType*>(Instruction::getType());
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<InsertElementInst> :
+ public FixedNumOperandTraits<InsertElementInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
+
+//===----------------------------------------------------------------------===//
+// ShuffleVectorInst Class
+//===----------------------------------------------------------------------===//
+
+/// ShuffleVectorInst - This instruction constructs a fixed permutation of two
+/// input vectors.
+///
+class ShuffleVectorInst : public Instruction {
+protected:
+ virtual ShuffleVectorInst *clone_impl() const;
+
+public:
+ // allocate space for exactly three operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 3);
+ }
+ ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+ const Twine &NameStr = "",
+ Instruction *InsertBefor = 0);
+ ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+ /// isValidOperands - Return true if a shufflevector instruction can be
+ /// formed with the specified operands.
+ static bool isValidOperands(const Value *V1, const Value *V2,
+ const Value *Mask);
+
+ /// getType - Overload to return most specific vector type.
+ ///
+ VectorType *getType() const {
+ return reinterpret_cast<VectorType*>(Instruction::getType());
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ Constant *getMask() const {
+ return reinterpret_cast<Constant*>(getOperand(2));
+ }
+
+ /// getMaskValue - Return the index from the shuffle mask for the specified
+ /// output result. This is either -1 if the element is undef or a number less
+ /// than 2*numelements.
+ static int getMaskValue(Constant *Mask, unsigned i);
+
+ int getMaskValue(unsigned i) const {
+ return getMaskValue(getMask(), i);
+ }
+
+ /// getShuffleMask - Return the full mask for this instruction, where each
+ /// element is the element number and undef's are returned as -1.
+ static void getShuffleMask(Constant *Mask, SmallVectorImpl<int> &Result);
+
+ void getShuffleMask(SmallVectorImpl<int> &Result) const {
+ return getShuffleMask(getMask(), Result);
+ }
+
+ SmallVector<int, 16> getShuffleMask() const {
+ SmallVector<int, 16> Mask;
+ getShuffleMask(Mask);
+ return Mask;
+ }
+
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<ShuffleVectorInst> :
+ public FixedNumOperandTraits<ShuffleVectorInst, 3> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value)
+
+//===----------------------------------------------------------------------===//
+// ExtractValueInst Class
+//===----------------------------------------------------------------------===//
+
+/// ExtractValueInst - This instruction extracts a struct member or array
+/// element value from an aggregate value.
+///
+class ExtractValueInst : public UnaryInstruction {
+ SmallVector<unsigned, 4> Indices;
+
+ ExtractValueInst(const ExtractValueInst &EVI);
+ void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
+
+ /// Constructors - Create a extractvalue instruction with a base aggregate
+ /// value and a list of indices. The first ctor can optionally insert before
+ /// an existing instruction, the second appends the new instruction to the
+ /// specified BasicBlock.
+ inline ExtractValueInst(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ Instruction *InsertBefore);
+ inline ExtractValueInst(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+ // allocate space for exactly one operand
+ void *operator new(size_t s) {
+ return User::operator new(s, 1);
+ }
+protected:
+ virtual ExtractValueInst *clone_impl() const;
+
+public:
+ static ExtractValueInst *Create(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new
+ ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
+ }
+ static ExtractValueInst *Create(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd);
+ }
+
+ /// getIndexedType - Returns the type of the element that would be extracted
+ /// with an extractvalue instruction with the specified parameters.
+ ///
+ /// Null is returned if the indices are invalid for the specified type.
+ static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
+
+ typedef const unsigned* idx_iterator;
+ inline idx_iterator idx_begin() const { return Indices.begin(); }
+ inline idx_iterator idx_end() const { return Indices.end(); }
+
+ Value *getAggregateOperand() {
+ return getOperand(0);
+ }
+ const Value *getAggregateOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getAggregateOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ ArrayRef<unsigned> getIndices() const {
+ return Indices;
+ }
+
+ unsigned getNumIndices() const {
+ return (unsigned)Indices.size();
+ }
+
+ bool hasIndices() const {
+ return true;
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+ExtractValueInst::ExtractValueInst(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ Instruction *InsertBefore)
+ : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
+ ExtractValue, Agg, InsertBefore) {
+ init(Idxs, NameStr);
+}
+ExtractValueInst::ExtractValueInst(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd)
+ : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
+ ExtractValue, Agg, InsertAtEnd) {
+ init(Idxs, NameStr);
+}
+
+
+//===----------------------------------------------------------------------===//
+// InsertValueInst Class
+//===----------------------------------------------------------------------===//
+
+/// InsertValueInst - This instruction inserts a struct field of array element
+/// value into an aggregate value.
+///
+class InsertValueInst : public Instruction {
+ SmallVector<unsigned, 4> Indices;
+
+ void *operator new(size_t, unsigned); // Do not implement
+ InsertValueInst(const InsertValueInst &IVI);
+ void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
+ const Twine &NameStr);
+
+ /// Constructors - Create a insertvalue instruction with a base aggregate
+ /// value, a value to insert, and a list of indices. The first ctor can
+ /// optionally insert before an existing instruction, the second appends
+ /// the new instruction to the specified BasicBlock.
+ inline InsertValueInst(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ Instruction *InsertBefore);
+ inline InsertValueInst(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+ /// Constructors - These two constructors are convenience methods because one
+ /// and two index insertvalue instructions are so common.
+ InsertValueInst(Value *Agg, Value *Val,
+ unsigned Idx, const Twine &NameStr = "",
+ Instruction *InsertBefore = 0);
+ InsertValueInst(Value *Agg, Value *Val, unsigned Idx,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+ virtual InsertValueInst *clone_impl() const;
+public:
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
+
+ static InsertValueInst *Create(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
+ }
+ static InsertValueInst *Create(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ typedef const unsigned* idx_iterator;
+ inline idx_iterator idx_begin() const { return Indices.begin(); }
+ inline idx_iterator idx_end() const { return Indices.end(); }
+
+ Value *getAggregateOperand() {
+ return getOperand(0);
+ }
+ const Value *getAggregateOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getAggregateOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ Value *getInsertedValueOperand() {
+ return getOperand(1);
+ }
+ const Value *getInsertedValueOperand() const {
+ return getOperand(1);
+ }
+ static unsigned getInsertedValueOperandIndex() {
+ return 1U; // get index for modifying correct operand
+ }
+
+ ArrayRef<unsigned> getIndices() const {
+ return Indices;
+ }
+
+ unsigned getNumIndices() const {
+ return (unsigned)Indices.size();
+ }
+
+ bool hasIndices() const {
+ return true;
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<InsertValueInst> :
+ public FixedNumOperandTraits<InsertValueInst, 2> {
+};
+
+InsertValueInst::InsertValueInst(Value *Agg,
+ Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ Instruction *InsertBefore)
+ : Instruction(Agg->getType(), InsertValue,
+ OperandTraits<InsertValueInst>::op_begin(this),
+ 2, InsertBefore) {
+ init(Agg, Val, Idxs, NameStr);
+}
+InsertValueInst::InsertValueInst(Value *Agg,
+ Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd)
+ : Instruction(Agg->getType(), InsertValue,
+ OperandTraits<InsertValueInst>::op_begin(this),
+ 2, InsertAtEnd) {
+ init(Agg, Val, Idxs, NameStr);
+}
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
+
+//===----------------------------------------------------------------------===//
+// PHINode Class
+//===----------------------------------------------------------------------===//
+
+// PHINode - The PHINode class is used to represent the magical mystical PHI
+// node, that can not exist in nature, but can be synthesized in a computer
+// scientist's overactive imagination.
+//
+class PHINode : public Instruction {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ /// ReservedSpace - The number of operands actually allocated. NumOperands is
+ /// the number actually in use.
+ unsigned ReservedSpace;
+ PHINode(const PHINode &PN);
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ explicit PHINode(Type *Ty, unsigned NumReservedValues,
+ const Twine &NameStr = "", Instruction *InsertBefore = 0)
+ : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
+ ReservedSpace(NumReservedValues) {
+ setName(NameStr);
+ OperandList = allocHungoffUses(ReservedSpace);
+ }
+
+ PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr,
+ BasicBlock *InsertAtEnd)
+ : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
+ ReservedSpace(NumReservedValues) {
+ setName(NameStr);
+ OperandList = allocHungoffUses(ReservedSpace);
+ }
+protected:
+ // allocHungoffUses - this is more complicated than the generic
+ // User::allocHungoffUses, because we have to allocate Uses for the incoming
+ // values and pointers to the incoming blocks, all in one allocation.
+ Use *allocHungoffUses(unsigned) const;
+
+ virtual PHINode *clone_impl() const;
+public:
+ /// Constructors - NumReservedValues is a hint for the number of incoming
+ /// edges that this phi node will have (use 0 if you really have no idea).
+ static PHINode *Create(Type *Ty, unsigned NumReservedValues,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
+ }
+ static PHINode *Create(Type *Ty, unsigned NumReservedValues,
+ const Twine &NameStr, BasicBlock *InsertAtEnd) {
+ return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd);
+ }
+ ~PHINode();
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // Block iterator interface. This provides access to the list of incoming
+ // basic blocks, which parallels the list of incoming values.
+
+ typedef BasicBlock **block_iterator;
+ typedef BasicBlock * const *const_block_iterator;
+
+ block_iterator block_begin() {
+ Use::UserRef *ref =
+ reinterpret_cast<Use::UserRef*>(op_begin() + ReservedSpace);
+ return reinterpret_cast<block_iterator>(ref + 1);
+ }
+
+ const_block_iterator block_begin() const {
+ const Use::UserRef *ref =
+ reinterpret_cast<const Use::UserRef*>(op_begin() + ReservedSpace);
+ return reinterpret_cast<const_block_iterator>(ref + 1);
+ }
+
+ block_iterator block_end() {
+ return block_begin() + getNumOperands();
+ }
+
+ const_block_iterator block_end() const {
+ return block_begin() + getNumOperands();
+ }
+
+ /// getNumIncomingValues - Return the number of incoming edges
+ ///
+ unsigned getNumIncomingValues() const { return getNumOperands(); }
+
+ /// getIncomingValue - Return incoming value number x
+ ///
+ Value *getIncomingValue(unsigned i) const {
+ return getOperand(i);
+ }
+ void setIncomingValue(unsigned i, Value *V) {
+ setOperand(i, V);
+ }
+ static unsigned getOperandNumForIncomingValue(unsigned i) {
+ return i;
+ }
+ static unsigned getIncomingValueNumForOperand(unsigned i) {
+ return i;
+ }
+
+ /// getIncomingBlock - Return incoming basic block number @p i.
+ ///
+ BasicBlock *getIncomingBlock(unsigned i) const {
+ return block_begin()[i];
+ }
+
+ /// getIncomingBlock - Return incoming basic block corresponding
+ /// to an operand of the PHI.
+ ///
+ BasicBlock *getIncomingBlock(const Use &U) const {
+ assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?");
+ return getIncomingBlock(unsigned(&U - op_begin()));
+ }
+
+ /// getIncomingBlock - Return incoming basic block corresponding
+ /// to value use iterator.
+ ///
+ template <typename U>
+ BasicBlock *getIncomingBlock(value_use_iterator<U> I) const {
+ return getIncomingBlock(I.getUse());
+ }
+
+ void setIncomingBlock(unsigned i, BasicBlock *BB) {
+ block_begin()[i] = BB;
+ }
+
+ /// addIncoming - Add an incoming value to the end of the PHI list
+ ///
+ void addIncoming(Value *V, BasicBlock *BB) {
+ assert(V && "PHI node got a null value!");
+ assert(BB && "PHI node got a null basic block!");
+ assert(getType() == V->getType() &&
+ "All operands to PHI node must be the same type as the PHI node!");
+ if (NumOperands == ReservedSpace)
+ growOperands(); // Get more space!
+ // Initialize some new operands.
+ ++NumOperands;
+ setIncomingValue(NumOperands - 1, V);
+ setIncomingBlock(NumOperands - 1, BB);
+ }
+
+ /// removeIncomingValue - Remove an incoming value. This is useful if a
+ /// predecessor basic block is deleted. The value removed is returned.
+ ///
+ /// If the last incoming value for a PHI node is removed (and DeletePHIIfEmpty
+ /// is true), the PHI node is destroyed and any uses of it are replaced with
+ /// dummy values. The only time there should be zero incoming values to a PHI
+ /// node is when the block is dead, so this strategy is sound.
+ ///
+ Value *removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty = true);
+
+ Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty=true) {
+ int Idx = getBasicBlockIndex(BB);
+ assert(Idx >= 0 && "Invalid basic block argument to remove!");
+ return removeIncomingValue(Idx, DeletePHIIfEmpty);
+ }
+
+ /// getBasicBlockIndex - Return the first index of the specified basic
+ /// block in the value list for this PHI. Returns -1 if no instance.
+ ///
+ int getBasicBlockIndex(const BasicBlock *BB) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (block_begin()[i] == BB)
+ return i;
+ return -1;
+ }
+
+ Value *getIncomingValueForBlock(const BasicBlock *BB) const {
+ int Idx = getBasicBlockIndex(BB);
+ assert(Idx >= 0 && "Invalid basic block argument!");
+ return getIncomingValue(Idx);
+ }
+
+ /// hasConstantValue - If the specified PHI node always merges together the
+ /// same value, return the value, otherwise return null.
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+ private:
+ void growOperands();
+};
+
+template <>
+struct OperandTraits<PHINode> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value)
+
+//===----------------------------------------------------------------------===//
+// LandingPadInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// LandingPadInst - The landingpad instruction holds all of the information
+/// necessary to generate correct exception handling. The landingpad instruction
+/// cannot be moved from the top of a landing pad block, which itself is
+/// accessible only from the 'unwind' edge of an invoke. This uses the
+/// SubclassData field in Value to store whether or not the landingpad is a
+/// cleanup.
+///
+class LandingPadInst : public Instruction {
+ /// ReservedSpace - The number of operands actually allocated. NumOperands is
+ /// the number actually in use.
+ unsigned ReservedSpace;
+ LandingPadInst(const LandingPadInst &LP);
+public:
+ enum ClauseType { Catch, Filter };
+private:
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ // Allocate space for exactly zero operands.
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ void growOperands(unsigned Size);
+ void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr);
+
+ explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
+ unsigned NumReservedValues, const Twine &NameStr,
+ Instruction *InsertBefore);
+ explicit LandingPadInst(Type *RetTy, Value *PersonalityFn,
+ unsigned NumReservedValues, const Twine &NameStr,
+ BasicBlock *InsertAtEnd);
+protected:
+ virtual LandingPadInst *clone_impl() const;
+public:
+ /// Constructors - NumReservedClauses is a hint for the number of incoming
+ /// clauses that this landingpad will have (use 0 if you really have no idea).
+ static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
+ unsigned NumReservedClauses,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = 0);
+ static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn,
+ unsigned NumReservedClauses,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+ ~LandingPadInst();
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getPersonalityFn - Get the personality function associated with this
+ /// landing pad.
+ Value *getPersonalityFn() const { return getOperand(0); }
+
+ /// isCleanup - Return 'true' if this landingpad instruction is a
+ /// cleanup. I.e., it should be run when unwinding even if its landing pad
+ /// doesn't catch the exception.
+ bool isCleanup() const { return getSubclassDataFromInstruction() & 1; }
+
+ /// setCleanup - Indicate that this landingpad instruction is a cleanup.
+ void setCleanup(bool V) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
+ (V ? 1 : 0));
+ }
+
+ /// addClause - Add a catch or filter clause to the landing pad.
+ void addClause(Value *ClauseVal);
+
+ /// getClause - Get the value of the clause at index Idx. Use isCatch/isFilter
+ /// to determine what type of clause this is.
+ Value *getClause(unsigned Idx) const { return OperandList[Idx + 1]; }
+
+ /// isCatch - Return 'true' if the clause and index Idx is a catch clause.
+ bool isCatch(unsigned Idx) const {
+ return !isa<ArrayType>(OperandList[Idx + 1]->getType());
+ }
+
+ /// isFilter - Return 'true' if the clause and index Idx is a filter clause.
+ bool isFilter(unsigned Idx) const {
+ return isa<ArrayType>(OperandList[Idx + 1]->getType());
+ }
+
+ /// getNumClauses - Get the number of clauses for this landing pad.
+ unsigned getNumClauses() const { return getNumOperands() - 1; }
+
+ /// reserveClauses - Grow the size of the operand list to accomodate the new
+ /// number of clauses.
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<LandingPadInst> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+// ReturnInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// ReturnInst - Return a value (possibly void), from a function. Execution
+/// does not continue in this function any longer.
+///
+class ReturnInst : public TerminatorInst {
+ ReturnInst(const ReturnInst &RI);
+
+private:
+ // ReturnInst constructors:
+ // ReturnInst() - 'ret void' instruction
+ // ReturnInst( null) - 'ret void' instruction
+ // ReturnInst(Value* X) - 'ret X' instruction
+ // ReturnInst( null, Inst *I) - 'ret void' instruction, insert before I
+ // ReturnInst(Value* X, Inst *I) - 'ret X' instruction, insert before I
+ // ReturnInst( null, BB *B) - 'ret void' instruction, insert @ end of B
+ // ReturnInst(Value* X, BB *B) - 'ret X' instruction, insert @ end of B
+ //
+ // NOTE: If the Value* passed is of type void then the constructor behaves as
+ // if it was passed NULL.
+ explicit ReturnInst(LLVMContext &C, Value *retVal = 0,
+ Instruction *InsertBefore = 0);
+ ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd);
+ explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd);
+protected:
+ virtual ReturnInst *clone_impl() const;
+public:
+ static ReturnInst* Create(LLVMContext &C, Value *retVal = 0,
+ Instruction *InsertBefore = 0) {
+ return new(!!retVal) ReturnInst(C, retVal, InsertBefore);
+ }
+ static ReturnInst* Create(LLVMContext &C, Value *retVal,
+ BasicBlock *InsertAtEnd) {
+ return new(!!retVal) ReturnInst(C, retVal, InsertAtEnd);
+ }
+ static ReturnInst* Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
+ return new(0) ReturnInst(C, InsertAtEnd);
+ }
+ virtual ~ReturnInst();
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// Convenience accessor. Returns null if there is no return value.
+ Value *getReturnValue() const {
+ return getNumOperands() != 0 ? getOperand(0) : 0;
+ }
+
+ 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);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+ private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+template <>
+struct OperandTraits<ReturnInst> : public VariadicOperandTraits<ReturnInst> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value)
+
+//===----------------------------------------------------------------------===//
+// BranchInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// BranchInst - Conditional or Unconditional Branch instruction.
+///
+class BranchInst : public TerminatorInst {
+ /// Ops list - Branches are strange. The operands are ordered:
+ /// [Cond, FalseDest,] TrueDest. This makes some accessors faster because
+ /// they don't have to check for cond/uncond branchness. These are mostly
+ /// accessed relative from op_end().
+ BranchInst(const BranchInst &BI);
+ void AssertOK();
+ // BranchInst constructors (where {B, T, F} are blocks, and C is a condition):
+ // BranchInst(BB *B) - 'br B'
+ // BranchInst(BB* T, BB *F, Value *C) - 'br C, T, F'
+ // BranchInst(BB* B, Inst *I) - 'br B' insert before I
+ // BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I
+ // BranchInst(BB* B, BB *I) - 'br B' insert at end
+ // BranchInst(BB* T, BB *F, Value *C, BB *I) - 'br C, T, F', insert at end
+ explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0);
+ BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
+ Instruction *InsertBefore = 0);
+ BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd);
+ BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
+ BasicBlock *InsertAtEnd);
+protected:
+ virtual BranchInst *clone_impl() const;
+public:
+ static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) {
+ return new(1) BranchInst(IfTrue, InsertBefore);
+ }
+ static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
+ Value *Cond, Instruction *InsertBefore = 0) {
+ return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertBefore);
+ }
+ static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) {
+ return new(1) BranchInst(IfTrue, InsertAtEnd);
+ }
+ static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
+ Value *Cond, BasicBlock *InsertAtEnd) {
+ return new(3) BranchInst(IfTrue, IfFalse, Cond, InsertAtEnd);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ bool isUnconditional() const { return getNumOperands() == 1; }
+ bool isConditional() const { return getNumOperands() == 3; }
+
+ Value *getCondition() const {
+ assert(isConditional() && "Cannot get condition of an uncond branch!");
+ return Op<-3>();
+ }
+
+ void setCondition(Value *V) {
+ assert(isConditional() && "Cannot set condition of unconditional branch!");
+ Op<-3>() = V;
+ }
+
+ unsigned getNumSuccessors() const { return 1+isConditional(); }
+
+ BasicBlock *getSuccessor(unsigned i) const {
+ assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
+ return cast_or_null<BasicBlock>((&Op<-1>() - i)->get());
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
+ *(&Op<-1>() - idx) = (Value*)NewSucc;
+ }
+
+ /// \brief Swap the successors of this branch instruction.
+ ///
+ /// Swaps the successors of the branch instruction. This also swaps any
+ /// branch weight metadata associated with the instruction so that it
+ /// continues to map correctly to each operand.
+ 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);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+template <>
+struct OperandTraits<BranchInst> : public VariadicOperandTraits<BranchInst, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
+
+//===----------------------------------------------------------------------===//
+// SwitchInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// SwitchInst - Multiway switch
+///
+class SwitchInst : public TerminatorInst {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ unsigned ReservedSpace;
+ // Operand[0] = Value to switch on
+ // Operand[1] = Default basic block destination
+ // Operand[2n ] = Value to match
+ // Operand[2n+1] = BasicBlock to go to on match
+ SwitchInst(const SwitchInst &SI);
+ void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
+ void growOperands();
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ /// SwitchInst ctor - Create a new switch instruction, specifying a value to
+ /// switch on and a default destination. The number of additional cases can
+ /// be specified here to make memory allocation more efficient. This
+ /// constructor can also autoinsert before another instruction.
+ SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
+ Instruction *InsertBefore);
+
+ /// SwitchInst ctor - Create a new switch instruction, specifying a value to
+ /// switch on and a default destination. The number of additional cases can
+ /// be specified here to make memory allocation more efficient. This
+ /// constructor also autoinserts at the end of the specified BasicBlock.
+ SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
+ BasicBlock *InsertAtEnd);
+protected:
+ virtual SwitchInst *clone_impl() const;
+public:
+
+ // -2
+ static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
+
+ template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
+ class CaseIteratorT {
+ protected:
+
+ SwitchInstTy *SI;
+ unsigned Index;
+
+ public:
+
+ typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// case number.
+ CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
+ this->SI = SI;
+ Index = CaseNum;
+ }
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// TerminatorInst's successor index.
+ static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) {
+ assert(SuccessorIndex < SI->getNumSuccessors() &&
+ "Successor index # out of range!");
+ return SuccessorIndex != 0 ?
+ Self(SI, SuccessorIndex - 1) :
+ Self(SI, DefaultPseudoIndex);
+ }
+
+ /// Resolves case value for current case.
+ ConstantIntTy *getCaseValue() {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
+ }
+
+ /// Resolves successor for current case.
+ BasicBlockTy *getCaseSuccessor() {
+ assert((Index < SI->getNumCases() ||
+ Index == DefaultPseudoIndex) &&
+ "Index out the number of cases.");
+ return SI->getSuccessor(getSuccessorIndex());
+ }
+
+ /// Returns number of current case.
+ unsigned getCaseIndex() const { return Index; }
+
+ /// Returns TerminatorInst's successor index for current case successor.
+ unsigned getSuccessorIndex() const {
+ assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) &&
+ "Index out the number of cases.");
+ return Index != DefaultPseudoIndex ? Index + 1 : 0;
+ }
+
+ Self operator++() {
+ // Check index correctness after increment.
+ // Note: Index == getNumCases() means end().
+ assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
+ ++Index;
+ return *this;
+ }
+ Self operator++(int) {
+ Self tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+ Self operator--() {
+ // Check index correctness after decrement.
+ // Note: Index == getNumCases() means end().
+ // Also allow "-1" iterator here. That will became valid after ++.
+ assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
+ "Index out the number of cases.");
+ --Index;
+ return *this;
+ }
+ Self operator--(int) {
+ Self tmp = *this;
+ --(*this);
+ return tmp;
+ }
+ bool operator==(const Self& RHS) const {
+ assert(RHS.SI == SI && "Incompatible operators.");
+ return RHS.Index == Index;
+ }
+ bool operator!=(const Self& RHS) const {
+ assert(RHS.SI == SI && "Incompatible operators.");
+ return RHS.Index != Index;
+ }
+ };
+
+ typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
+ ConstCaseIt;
+
+ class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
+
+ typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
+
+ public:
+
+ CaseIt(const ParentTy& Src) : ParentTy(Src) {}
+ CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+
+ /// Sets the new value for current case.
+ void setValue(ConstantInt *V) {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
+ }
+
+ /// Sets the new successor for current case.
+ void setSuccessor(BasicBlock *S) {
+ SI->setSuccessor(getSuccessorIndex(), S);
+ }
+ };
+
+ static SwitchInst *Create(Value *Value, BasicBlock *Default,
+ unsigned NumCases, Instruction *InsertBefore = 0) {
+ return new SwitchInst(Value, Default, NumCases, InsertBefore);
+ }
+ static SwitchInst *Create(Value *Value, BasicBlock *Default,
+ unsigned NumCases, BasicBlock *InsertAtEnd) {
+ return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
+ }
+
+ ~SwitchInst();
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // Accessor Methods for Switch stmt
+ Value *getCondition() const { return getOperand(0); }
+ void setCondition(Value *V) { setOperand(0, V); }
+
+ BasicBlock *getDefaultDest() const {
+ return cast<BasicBlock>(getOperand(1));
+ }
+
+ void setDefaultDest(BasicBlock *DefaultCase) {
+ setOperand(1, reinterpret_cast<Value*>(DefaultCase));
+ }
+
+ /// getNumCases - return the number of 'cases' in this switch instruction,
+ /// except the default case
+ unsigned getNumCases() const {
+ return getNumOperands()/2 - 1;
+ }
+
+ /// Returns a read/write iterator that points to the first
+ /// case in SwitchInst.
+ CaseIt case_begin() {
+ return CaseIt(this, 0);
+ }
+ /// Returns a read-only iterator that points to the first
+ /// case in the SwitchInst.
+ ConstCaseIt case_begin() const {
+ return ConstCaseIt(this, 0);
+ }
+
+ /// Returns a read/write iterator that points one past the last
+ /// in the SwitchInst.
+ CaseIt case_end() {
+ return CaseIt(this, getNumCases());
+ }
+ /// Returns a read-only iterator that points one past the last
+ /// in the SwitchInst.
+ ConstCaseIt case_end() const {
+ return ConstCaseIt(this, getNumCases());
+ }
+ /// Returns an iterator that points to the default case.
+ /// Note: this iterator allows to resolve successor only. Attempt
+ /// to resolve case value causes an assertion.
+ /// Also note, that increment and decrement also causes an assertion and
+ /// makes iterator invalid.
+ CaseIt case_default() {
+ return CaseIt(this, DefaultPseudoIndex);
+ }
+ ConstCaseIt case_default() const {
+ return ConstCaseIt(this, DefaultPseudoIndex);
+ }
+
+ /// findCaseValue - Search all of the case values for the specified constant.
+ /// If it is explicitly handled, return the case iterator of it, otherwise
+ /// return default case iterator to indicate
+ /// that it is handled by the default handler.
+ CaseIt findCaseValue(const ConstantInt *C) {
+ for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
+ if (i.getCaseValue() == C)
+ return i;
+ return case_default();
+ }
+ ConstCaseIt findCaseValue(const ConstantInt *C) const {
+ for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
+ if (i.getCaseValue() == C)
+ return i;
+ return case_default();
+ }
+
+ /// findCaseDest - Finds the unique case value for a given successor. Returns
+ /// null if the successor is not found, not unique, or is the default case.
+ ConstantInt *findCaseDest(BasicBlock *BB) {
+ if (BB == getDefaultDest()) return NULL;
+
+ ConstantInt *CI = NULL;
+ for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
+ if (i.getCaseSuccessor() == BB) {
+ if (CI) return NULL; // Multiple cases lead to BB.
+ else CI = i.getCaseValue();
+ }
+ }
+ return CI;
+ }
+
+ /// addCase - Add an entry to the switch instruction...
+ /// Note:
+ /// This action invalidates case_end(). Old case_end() iterator will
+ /// point to the added case.
+ void addCase(ConstantInt *OnVal, BasicBlock *Dest);
+
+ /// removeCase - This method removes the specified case and its successor
+ /// from the switch instruction. Note that this operation may reorder the
+ /// remaining cases at index idx and above.
+ /// Note:
+ /// This action invalidates iterators for all cases following the one removed,
+ /// including the case_end() iterator.
+ void removeCase(CaseIt i);
+
+ unsigned getNumSuccessors() const { return getNumOperands()/2; }
+ BasicBlock *getSuccessor(unsigned idx) const {
+ assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
+ return cast<BasicBlock>(getOperand(idx*2+1));
+ }
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
+ setOperand(idx*2+1, (Value*)NewSucc);
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+template <>
+struct OperandTraits<SwitchInst> : public HungoffOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
+
+
+//===----------------------------------------------------------------------===//
+// IndirectBrInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// IndirectBrInst - Indirect Branch Instruction.
+///
+class IndirectBrInst : public TerminatorInst {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+ unsigned ReservedSpace;
+ // Operand[0] = Value to switch on
+ // Operand[1] = Default basic block destination
+ // Operand[2n ] = Value to match
+ // Operand[2n+1] = BasicBlock to go to on match
+ IndirectBrInst(const IndirectBrInst &IBI);
+ void init(Value *Address, unsigned NumDests);
+ void growOperands();
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an
+ /// Address to jump to. The number of expected destinations can be specified
+ /// here to make memory allocation more efficient. This constructor can also
+ /// autoinsert before another instruction.
+ IndirectBrInst(Value *Address, unsigned NumDests, Instruction *InsertBefore);
+
+ /// IndirectBrInst ctor - Create a new indirectbr instruction, specifying an
+ /// Address to jump to. The number of expected destinations can be specified
+ /// here to make memory allocation more efficient. This constructor also
+ /// autoinserts at the end of the specified BasicBlock.
+ IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd);
+protected:
+ virtual IndirectBrInst *clone_impl() const;
+public:
+ static IndirectBrInst *Create(Value *Address, unsigned NumDests,
+ Instruction *InsertBefore = 0) {
+ return new IndirectBrInst(Address, NumDests, InsertBefore);
+ }
+ static IndirectBrInst *Create(Value *Address, unsigned NumDests,
+ BasicBlock *InsertAtEnd) {
+ return new IndirectBrInst(Address, NumDests, InsertAtEnd);
+ }
+ ~IndirectBrInst();
+
+ /// Provide fast operand accessors.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // Accessor Methods for IndirectBrInst instruction.
+ Value *getAddress() { return getOperand(0); }
+ const Value *getAddress() const { return getOperand(0); }
+ void setAddress(Value *V) { setOperand(0, V); }
+
+
+ /// getNumDestinations - return the number of possible destinations in this
+ /// indirectbr instruction.
+ unsigned getNumDestinations() const { return getNumOperands()-1; }
+
+ /// getDestination - Return the specified destination.
+ BasicBlock *getDestination(unsigned i) { return getSuccessor(i); }
+ const BasicBlock *getDestination(unsigned i) const { return getSuccessor(i); }
+
+ /// addDestination - Add a destination.
+ ///
+ void addDestination(BasicBlock *Dest);
+
+ /// removeDestination - This method removes the specified successor from the
+ /// indirectbr instruction.
+ void removeDestination(unsigned i);
+
+ unsigned getNumSuccessors() const { return getNumOperands()-1; }
+ BasicBlock *getSuccessor(unsigned i) const {
+ return cast<BasicBlock>(getOperand(i+1));
+ }
+ void setSuccessor(unsigned i, BasicBlock *NewSucc) {
+ setOperand(i+1, (Value*)NewSucc);
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+template <>
+struct OperandTraits<IndirectBrInst> : public HungoffOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
+
+
+//===----------------------------------------------------------------------===//
+// InvokeInst Class
+//===----------------------------------------------------------------------===//
+
+/// InvokeInst - Invoke instruction. The SubclassData field is used to hold the
+/// calling convention of the call.
+///
+class InvokeInst : public TerminatorInst {
+ AttrListPtr 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
+ 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
+ inline InvokeInst(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+protected:
+ virtual InvokeInst *clone_impl() const;
+public:
+ static InvokeInst *Create(Value *Func,
+ BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr = "",
+ Instruction *InsertBefore = 0) {
+ unsigned Values = unsigned(Args.size()) + 3;
+ return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
+ Values, NameStr, InsertBefore);
+ }
+ static InvokeInst *Create(Value *Func,
+ BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ unsigned Values = unsigned(Args.size()) + 3;
+ return new(Values) InvokeInst(Func, IfNormal, IfException, Args,
+ Values, NameStr, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getNumArgOperands - Return the number of invoke arguments.
+ ///
+ unsigned getNumArgOperands() const { return getNumOperands() - 3; }
+
+ /// getArgOperand/setArgOperand - Return/set the i-th invoke argument.
+ ///
+ Value *getArgOperand(unsigned i) const { return getOperand(i); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+ /// getCallingConv/setCallingConv - Get or set the calling convention of this
+ /// function call.
+ CallingConv::ID getCallingConv() const {
+ return static_cast<CallingConv::ID>(getSubclassDataFromInstruction());
+ }
+ void setCallingConv(CallingConv::ID CC) {
+ setInstructionSubclassData(static_cast<unsigned>(CC));
+ }
+
+ /// getAttributes - Return the parameter attributes for this invoke.
+ ///
+ const AttrListPtr &getAttributes() const { return AttributeList; }
+
+ /// setAttributes - Set the parameter attributes for this invoke.
+ ///
+ void setAttributes(const AttrListPtr &Attrs) { AttributeList = Attrs; }
+
+ /// addAttribute - adds the attribute to the list of attributes.
+ void addAttribute(unsigned i, Attributes attr);
+
+ /// removeAttribute - removes the attribute from the list of attributes.
+ void removeAttribute(unsigned i, Attributes attr);
+
+ /// @brief Determine whether the call or the callee has the given attribute.
+ bool paramHasAttr(unsigned i, Attributes attr) const;
+
+ /// @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.
+ bool isNoInline() const { return paramHasAttr(~0, Attribute::NoInline); }
+ void setIsNoInline(bool Value = true) {
+ if (Value) addAttribute(~0, Attribute::NoInline);
+ else removeAttribute(~0, Attribute::NoInline);
+ }
+
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const {
+ return paramHasAttr(~0, Attribute::ReadNone);
+ }
+ void setDoesNotAccessMemory(bool NotAccessMemory = true) {
+ if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
+ else removeAttribute(~0, Attribute::ReadNone);
+ }
+
+ /// @brief Determine if the call does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
+ }
+ void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
+ if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
+ else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
+ }
+
+ /// @brief Determine if the call cannot return.
+ bool doesNotReturn() const { return paramHasAttr(~0, Attribute::NoReturn); }
+ void setDoesNotReturn(bool DoesNotReturn = true) {
+ if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
+ else removeAttribute(~0, Attribute::NoReturn);
+ }
+
+ /// @brief Determine if the call cannot unwind.
+ bool doesNotThrow() const { return paramHasAttr(~0, Attribute::NoUnwind); }
+ void setDoesNotThrow(bool DoesNotThrow = true) {
+ if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
+ else removeAttribute(~0, Attribute::NoUnwind);
+ }
+
+ /// @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.
+ bool hasByValArgument() const {
+ return AttributeList.hasAttrSomewhere(Attribute::ByVal);
+ }
+
+ /// getCalledFunction - Return the function called, or null if this is an
+ /// indirect function invocation.
+ ///
+ Function *getCalledFunction() const {
+ return dyn_cast<Function>(Op<-3>());
+ }
+
+ /// getCalledValue - Get a pointer to the function that is invoked by this
+ /// instruction
+ const Value *getCalledValue() const { return Op<-3>(); }
+ Value *getCalledValue() { return Op<-3>(); }
+
+ /// setCalledFunction - Set the function called.
+ void setCalledFunction(Value* Fn) {
+ Op<-3>() = Fn;
+ }
+
+ // get*Dest - Return the destination basic blocks...
+ BasicBlock *getNormalDest() const {
+ return cast<BasicBlock>(Op<-2>());
+ }
+ BasicBlock *getUnwindDest() const {
+ return cast<BasicBlock>(Op<-1>());
+ }
+ void setNormalDest(BasicBlock *B) {
+ Op<-2>() = reinterpret_cast<Value*>(B);
+ }
+ void setUnwindDest(BasicBlock *B) {
+ Op<-1>() = reinterpret_cast<Value*>(B);
+ }
+
+ /// getLandingPadInst - Get the landingpad instruction from the landing pad
+ /// block (the unwind destination).
+ LandingPadInst *getLandingPadInst() const;
+
+ BasicBlock *getSuccessor(unsigned i) const {
+ assert(i < 2 && "Successor # out of range for invoke!");
+ return i == 0 ? getNormalDest() : getUnwindDest();
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < 2 && "Successor # out of range for invoke!");
+ *(&Op<-2>() + idx) = reinterpret_cast<Value*>(NewSucc);
+ }
+
+ 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);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+
+ // Shadow Instruction::setInstructionSubclassData with a private forwarding
+ // method so that subclasses cannot accidentally use it.
+ void setInstructionSubclassData(unsigned short D) {
+ Instruction::setInstructionSubclassData(D);
+ }
+};
+
+template <>
+struct OperandTraits<InvokeInst> : public VariadicOperandTraits<InvokeInst, 3> {
+};
+
+InvokeInst::InvokeInst(Value *Func,
+ BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore)
+ : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Invoke,
+ OperandTraits<InvokeInst>::op_end(this) - Values,
+ Values, InsertBefore) {
+ init(Func, IfNormal, IfException, Args, NameStr);
+}
+InvokeInst::InvokeInst(Value *Func,
+ BasicBlock *IfNormal, BasicBlock *IfException,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd)
+ : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
+ ->getElementType())->getReturnType(),
+ Instruction::Invoke,
+ OperandTraits<InvokeInst>::op_end(this) - Values,
+ Values, InsertAtEnd) {
+ init(Func, IfNormal, IfException, Args, NameStr);
+}
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value)
+
+//===----------------------------------------------------------------------===//
+// ResumeInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// ResumeInst - Resume the propagation of an exception.
+///
+class ResumeInst : public TerminatorInst {
+ ResumeInst(const ResumeInst &RI);
+
+ explicit ResumeInst(Value *Exn, Instruction *InsertBefore=0);
+ ResumeInst(Value *Exn, BasicBlock *InsertAtEnd);
+protected:
+ virtual ResumeInst *clone_impl() const;
+public:
+ static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = 0) {
+ return new(1) ResumeInst(Exn, InsertBefore);
+ }
+ static ResumeInst *Create(Value *Exn, BasicBlock *InsertAtEnd) {
+ return new(1) ResumeInst(Exn, InsertAtEnd);
+ }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// Convenience accessor.
+ Value *getValue() const { return Op<0>(); }
+
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+template <>
+struct OperandTraits<ResumeInst> :
+ public FixedNumOperandTraits<ResumeInst, 1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
+
+//===----------------------------------------------------------------------===//
+// UnreachableInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// UnreachableInst - This function has undefined behavior. In particular, the
+/// presence of this instruction indicates some higher level knowledge that the
+/// end of the block cannot be reached.
+///
+class UnreachableInst : public TerminatorInst {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
+protected:
+ virtual UnreachableInst *clone_impl() const;
+
+public:
+ // allocate space for exactly zero operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 0);
+ }
+ explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = 0);
+ explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd);
+
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+//===----------------------------------------------------------------------===//
+// TruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a truncation of integer types.
+class TruncInst : public CastInst {
+protected:
+ /// @brief Clone an identical TruncInst
+ virtual TruncInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ TruncInst(
+ Value *S, ///< The value to be truncated
+ Type *Ty, ///< The (smaller) type to truncate to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @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
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Trunc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ZExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents zero extension of integer types.
+class ZExtInst : public CastInst {
+protected:
+ /// @brief Clone an identical ZExtInst
+ virtual ZExtInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ ZExtInst(
+ Value *S, ///< The value to be zero extended
+ Type *Ty, ///< The type to zero extend to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end semantics.
+ ZExtInst(
+ Value *S, ///< The value to be zero extended
+ Type *Ty, ///< The type to zero extend to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == ZExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a sign extension of integer types.
+class SExtInst : public CastInst {
+protected:
+ /// @brief Clone an identical SExtInst
+ virtual SExtInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ SExtInst(
+ Value *S, ///< The value to be sign extended
+ Type *Ty, ///< The type to sign extend to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @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
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == SExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPTruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a truncation of floating point types.
+class FPTruncInst : public CastInst {
+protected:
+ /// @brief Clone an identical FPTruncInst
+ virtual FPTruncInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPTruncInst(
+ Value *S, ///< The value to be truncated
+ Type *Ty, ///< The type to truncate to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-before-instruction semantics
+ FPTruncInst(
+ Value *S, ///< The value to be truncated
+ Type *Ty, ///< The type to truncate to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPTrunc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents an extension of floating point types.
+class FPExtInst : public CastInst {
+protected:
+ /// @brief Clone an identical FPExtInst
+ virtual FPExtInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPExtInst(
+ Value *S, ///< The value to be extended
+ Type *Ty, ///< The type to extend to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPExtInst(
+ Value *S, ///< The value to be extended
+ Type *Ty, ///< The type to extend to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// UIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast unsigned integer to floating point.
+class UIToFPInst : public CastInst {
+protected:
+ /// @brief Clone an identical UIToFPInst
+ virtual UIToFPInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ UIToFPInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ UIToFPInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == UIToFP;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from signed integer to floating point.
+class SIToFPInst : public CastInst {
+protected:
+ /// @brief Clone an identical SIToFPInst
+ virtual SIToFPInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ SIToFPInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ SIToFPInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == SIToFP;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPToUIInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from floating point to unsigned integer
+class FPToUIInst : public CastInst {
+protected:
+ /// @brief Clone an identical FPToUIInst
+ virtual FPToUIInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPToUIInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPToUIInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPToUI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPToSIInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from floating point to signed integer.
+class FPToSIInst : public CastInst {
+protected:
+ /// @brief Clone an identical FPToSIInst
+ virtual FPToSIInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPToSIInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPToSIInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr, ///< A name for the new instruction
+ 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; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPToSI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// IntToPtrInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from an integer to a pointer.
+class IntToPtrInst : public CastInst {
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ IntToPtrInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ IntToPtrInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical IntToPtrInst
+ virtual IntToPtrInst *clone_impl() const;
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// PtrToIntInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from a pointer to an integer
+class PtrToIntInst : public CastInst {
+protected:
+ /// @brief Clone an identical PtrToIntInst
+ virtual PtrToIntInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ PtrToIntInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ PtrToIntInst(
+ Value *S, ///< The value to be converted
+ Type *Ty, ///< The type to convert to
+ const Twine &NameStr, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// BitCastInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a no-op cast from one type to another.
+class BitCastInst : public CastInst {
+protected:
+ /// @brief Clone an identical BitCastInst
+ virtual BitCastInst *clone_impl() const;
+
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ BitCastInst(
+ Value *S, ///< The value to be casted
+ Type *Ty, ///< The type to casted to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ BitCastInst(
+ Value *S, ///< The value to be casted
+ Type *Ty, ///< The type to casted to
+ const Twine &NameStr, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/IntrinsicInst.h b/contrib/llvm/include/llvm/IntrinsicInst.h
new file mode 100644
index 000000000000..1cebdd2ee642
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicInst.h
@@ -0,0 +1,282 @@
+//===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- 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 classes that make it really easy to deal with intrinsic
+// functions with the isa/dyncast family of functions. In particular, this
+// allows you to do things like:
+//
+// if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
+// ... MCI->getDest() ... MCI->getSource() ...
+//
+// All intrinsic function calls are instances of the call instruction, so these
+// are all subclasses of the CallInst class. Note that none of these classes
+// has state or virtual methods, which is an important part of this gross/neat
+// hack working.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTRINSICINST_H
+#define LLVM_INTRINSICINST_H
+
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/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
+ public:
+ /// getIntrinsicID - Return the intrinsic ID of this intrinsic.
+ ///
+ Intrinsic::ID getIntrinsicID() const {
+ return (Intrinsic::ID)getCalledFunction()->getIntrinsicID();
+ }
+
+ // 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 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:
+ case Intrinsic::dbg_value:
+ return true;
+ default: return false;
+ }
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ static Value *StripCast(Value *C);
+ };
+
+ /// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
+ ///
+ class DbgDeclareInst : public DbgInfoIntrinsic {
+ public:
+ Value *getAddress() const;
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// DbgValueInst - This represents the llvm.dbg.value instruction.
+ ///
+ class DbgValueInst : public DbgInfoIntrinsic {
+ public:
+ const Value *getValue() const;
+ Value *getValue();
+ uint64_t getOffset() const {
+ return cast<ConstantInt>(
+ const_cast<Value*>(getArgOperand(1)))->getZExtValue();
+ }
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
+ ///
+ class MemIntrinsic : public IntrinsicInst {
+ public:
+ Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); }
+
+ Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); }
+ ConstantInt *getAlignmentCst() const {
+ return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));
+ }
+
+ unsigned getAlignment() const {
+ return getAlignmentCst()->getZExtValue();
+ }
+
+ ConstantInt *getVolatileCst() const {
+ return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4)));
+ }
+ bool isVolatile() const {
+ return !getVolatileCst()->isZero();
+ }
+
+ unsigned getDestAddressSpace() const {
+ return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
+
+ /// getDest - This is just like getRawDest, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getDest() const { return getRawDest()->stripPointerCasts(); }
+
+ /// set* - Set the specified arguments of the instruction.
+ ///
+ void setDest(Value *Ptr) {
+ assert(getRawDest()->getType() == Ptr->getType() &&
+ "setDest called with pointer of wrong type!");
+ setArgOperand(0, Ptr);
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setArgOperand(2, L);
+ }
+
+ void setAlignment(Constant* A) {
+ setArgOperand(3, A);
+ }
+
+ void setVolatile(Constant* V) {
+ setArgOperand(4, V);
+ }
+
+ Type *getAlignmentType() const {
+ return getArgOperand(3)->getType();
+ }
+
+ // 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:
+ case Intrinsic::memmove:
+ case Intrinsic::memset:
+ return true;
+ default: return false;
+ }
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemSetInst - This class wraps the llvm.memset intrinsic.
+ ///
+ class MemSetInst : public MemIntrinsic {
+ public:
+ /// get* - Return the arguments to the instruction.
+ ///
+ Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); }
+
+ void setValue(Value *Val) {
+ assert(getValue()->getType() == Val->getType() &&
+ "setValue called with value of wrong type!");
+ setArgOperand(1, Val);
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics.
+ ///
+ class MemTransferInst : public MemIntrinsic {
+ public:
+ /// get* - Return the arguments to the instruction.
+ ///
+ Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); }
+
+ /// getSource - This is just like getRawSource, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getSource() const { return getRawSource()->stripPointerCasts(); }
+
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+ }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setArgOperand(1, Ptr);
+ }
+
+ // 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+
+ /// MemCpyInst - This class wraps the llvm.memcpy intrinsic.
+ ///
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemMoveInst - This class wraps the llvm.memmove intrinsic.
+ ///
+ 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;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Intrinsics.h b/contrib/llvm/include/llvm/Intrinsics.h
new file mode 100644
index 000000000000..370382560337
--- /dev/null
+++ b/contrib/llvm/include/llvm/Intrinsics.h
@@ -0,0 +1,81 @@
+//===-- llvm/Instrinsics.h - LLVM Intrinsic Function Handling ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a set of enums which allow processing of intrinsic
+// functions. Values of these enum types are returned by
+// Function::getIntrinsicID.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTRINSICS_H
+#define LLVM_INTRINSICS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include <string>
+
+namespace llvm {
+
+class Type;
+class FunctionType;
+class Function;
+class LLVMContext;
+class Module;
+class AttrListPtr;
+
+/// Intrinsic Namespace - This namespace contains an enum with a value for
+/// every intrinsic/builtin function known by LLVM. These enum values are
+/// returned by Function::getIntrinsicID().
+///
+namespace Intrinsic {
+ enum ID {
+ not_intrinsic = 0, // Must be zero
+
+ // Get the intrinsic enums generated from Intrinsics.td
+#define GET_INTRINSIC_ENUM_VALUES
+#include "llvm/Intrinsics.gen"
+#undef GET_INTRINSIC_ENUM_VALUES
+ , num_intrinsics
+ };
+
+ /// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as
+ /// "llvm.ppc.altivec.lvx".
+ std::string getName(ID id, ArrayRef<Type*> Tys = ArrayRef<Type*>());
+
+ /// Intrinsic::getType(ID) - Return the function type for an intrinsic.
+ ///
+ FunctionType *getType(LLVMContext &Context, ID id,
+ ArrayRef<Type*> Tys = ArrayRef<Type*>());
+
+ /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be
+ /// overloaded.
+ bool isOverloaded(ID id);
+
+ /// Intrinsic::getAttributes(ID) - Return the attributes for an intrinsic.
+ ///
+ AttrListPtr getAttributes(ID id);
+
+ /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
+ /// declaration for an intrinsic, and return it.
+ ///
+ /// The Tys and numTys parameters are for intrinsics with overloaded types
+ /// (e.g., those using iAny, fAny, vAny, or iPTRAny). For a declaration for an
+ /// overloaded intrinsic, Tys should point to an array of numTys pointers to
+ /// Type, and must provide exactly one type for each overloaded type in the
+ /// intrinsic.
+ Function *getDeclaration(Module *M, ID id,
+ ArrayRef<Type*> Tys = ArrayRef<Type*>());
+
+ /// Map a GCC builtin name to an intrinsic ID.
+ ID getIntrinsicForGCCBuiltin(const char *Prefix, const char *BuiltinName);
+
+} // End Intrinsic namespace
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Intrinsics.td b/contrib/llvm/include/llvm/Intrinsics.td
new file mode 100644
index 000000000000..069f907d4ff2
--- /dev/null
+++ b/contrib/llvm/include/llvm/Intrinsics.td
@@ -0,0 +1,443 @@
+//===- Intrinsics.td - Defines all LLVM 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 properties of all LLVM intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CodeGen/ValueTypes.td"
+
+//===----------------------------------------------------------------------===//
+// Properties we keep track of for intrinsics.
+//===----------------------------------------------------------------------===//
+
+class IntrinsicProperty;
+
+// Intr*Mem - Memory properties. An intrinsic is allowed to have at most one of
+// these properties set. They are listed from the most aggressive (best to use
+// if correct) to the least aggressive. If no property is set, the worst case
+// is assumed (it may read and write any memory it can get access to and it may
+// have other side effects).
+
+// IntrNoMem - The intrinsic does not access memory or have any other side
+// effects. It may be CSE'd deleted if dead, etc.
+def IntrNoMem : IntrinsicProperty;
+
+// IntrReadArgMem - This intrinsic reads only from memory that one of its
+// pointer-typed arguments points to, but may read an unspecified amount.
+def IntrReadArgMem : IntrinsicProperty;
+
+// IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be
+// moved across stores. However, it can be reordered otherwise and can be
+// deleted if dead.
+def IntrReadMem : IntrinsicProperty;
+
+// IntrReadWriteArgMem - This intrinsic reads and writes only from memory that
+// one of its arguments points to, but may access an unspecified amount. The
+// reads and writes may be volatile, but except for this it has no other side
+// effects.
+def IntrReadWriteArgMem : IntrinsicProperty;
+
+// Commutative - This intrinsic is commutative: X op Y == Y op X.
+def Commutative : IntrinsicProperty;
+
+// Throws - This intrinsic can throw.
+def Throws : IntrinsicProperty;
+
+// NoCapture - The specified argument pointer is not captured by the intrinsic.
+class NoCapture<int argNo> : IntrinsicProperty {
+ int ArgNo = argNo;
+}
+
+//===----------------------------------------------------------------------===//
+// Types used by intrinsics.
+//===----------------------------------------------------------------------===//
+
+class LLVMType<ValueType vt> {
+ ValueType VT = vt;
+}
+
+class LLVMPointerType<LLVMType elty>
+ : LLVMType<iPTR>{
+ LLVMType ElTy = elty;
+}
+
+class LLVMAnyPointerType<LLVMType elty>
+ : LLVMType<iPTRAny>{
+ LLVMType ElTy = elty;
+}
+
+// Match the type of another intrinsic parameter. Number is an index into the
+// list of overloaded types for the intrinsic, excluding all the fixed types.
+// The Number value must refer to a previously listed type. For example:
+// Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyfloat_ty, LLVMMatchType<0>]>
+// has two overloaded types, the 2nd and 3rd arguments. LLVMMatchType<0>
+// refers to the first overloaded type, which is the 2nd argument.
+class LLVMMatchType<int num>
+ : LLVMType<OtherVT>{
+ int Number = num;
+}
+
+// Match the type of another intrinsic parameter that is expected to be
+// an integral vector type, but change the element size to be twice as wide
+// or half as wide as the other type. This is only useful when the intrinsic
+// is overloaded, so the matched type should be declared as iAny.
+class LLVMExtendedElementVectorType<int num> : LLVMMatchType<num>;
+class LLVMTruncatedElementVectorType<int num> : LLVMMatchType<num>;
+
+def llvm_void_ty : LLVMType<isVoid>;
+def llvm_anyint_ty : LLVMType<iAny>;
+def llvm_anyfloat_ty : LLVMType<fAny>;
+def llvm_anyvector_ty : LLVMType<vAny>;
+def llvm_i1_ty : LLVMType<i1>;
+def llvm_i8_ty : LLVMType<i8>;
+def llvm_i16_ty : LLVMType<i16>;
+def llvm_i32_ty : LLVMType<i32>;
+def llvm_i64_ty : LLVMType<i64>;
+def llvm_float_ty : LLVMType<f32>;
+def llvm_double_ty : LLVMType<f64>;
+def llvm_f80_ty : LLVMType<f80>;
+def llvm_f128_ty : LLVMType<f128>;
+def llvm_ppcf128_ty : LLVMType<ppcf128>;
+def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8*
+def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8**
+def llvm_anyptr_ty : LLVMAnyPointerType<llvm_i8_ty>; // (space)i8*
+def llvm_empty_ty : LLVMType<OtherVT>; // { }
+def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }*
+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_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_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_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
+def llvm_v1i64_ty : LLVMType<v1i64>; // 1 x i64
+def llvm_v2i64_ty : LLVMType<v2i64>; // 2 x i64
+def llvm_v4i64_ty : LLVMType<v4i64>; // 4 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_v2f64_ty : LLVMType<v2f64>; // 2 x double
+def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double
+
+def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
+
+
+//===----------------------------------------------------------------------===//
+// Intrinsic Definitions.
+//===----------------------------------------------------------------------===//
+
+// Intrinsic class - This is used to define one LLVM intrinsic. The name of the
+// intrinsic definition should start with "int_", then match the LLVM intrinsic
+// name with the "llvm." prefix removed, and all "."s turned into "_"s. For
+// example, llvm.bswap.i16 -> int_bswap_i16.
+//
+// * RetTypes is a list containing the return types expected for the
+// intrinsic.
+// * ParamTypes is a list containing the parameter types expected for the
+// intrinsic.
+// * Properties can be set to describe the behavior of the intrinsic.
+//
+class Intrinsic<list<LLVMType> ret_types,
+ list<LLVMType> param_types = [],
+ list<IntrinsicProperty> properties = [],
+ string name = ""> {
+ string LLVMName = name;
+ string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
+ list<LLVMType> RetTypes = ret_types;
+ list<LLVMType> ParamTypes = param_types;
+ list<IntrinsicProperty> Properties = properties;
+
+ bit isTarget = 0;
+}
+
+/// GCCBuiltin - If this intrinsic exactly corresponds to a GCC builtin, this
+/// specifies the name of the builtin. This provides automatic CBE and CFE
+/// support.
+class GCCBuiltin<string name> {
+ string GCCBuiltinName = name;
+}
+
+
+//===--------------- Variable Argument Handling Intrinsics ----------------===//
+//
+
+def int_vastart : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_start">;
+def int_vacopy : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], [],
+ "llvm.va_copy">;
+def int_vaend : Intrinsic<[], [llvm_ptr_ty], [], "llvm.va_end">;
+
+//===------------------- Garbage Collection Intrinsics --------------------===//
+//
+def int_gcroot : Intrinsic<[],
+ [llvm_ptrptr_ty, llvm_ptr_ty]>;
+def int_gcread : Intrinsic<[llvm_ptr_ty],
+ [llvm_ptr_ty, llvm_ptrptr_ty],
+ [IntrReadArgMem]>;
+def int_gcwrite : Intrinsic<[],
+ [llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
+ [IntrReadWriteArgMem, NoCapture<1>, NoCapture<2>]>;
+
+//===--------------------- Code Generator Intrinsics ----------------------===//
+//
+def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
+def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+// Note: we treat stacksave/stackrestore as writemem because we don't otherwise
+// model their dependencies on allocas.
+def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
+ GCCBuiltin<"__builtin_stack_save">;
+def int_stackrestore : Intrinsic<[], [llvm_ptr_ty]>,
+ GCCBuiltin<"__builtin_stack_restore">;
+
+// IntrReadWriteArgMem is more pessimistic than strictly necessary for prefetch,
+// however it does conveniently prevent the prefetch from being reordered
+// with respect to nearby accesses to the same memory.
+def int_prefetch : Intrinsic<[],
+ [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>;
+
+def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
+
+// Stack Protector Intrinsic - The stackprotector intrinsic writes the stack
+// guard to the correct place on the stack frame.
+def int_stackprotector : Intrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>;
+
+//===------------------- Standard C Library Intrinsics --------------------===//
+//
+
+def int_memcpy : Intrinsic<[],
+ [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
+ llvm_i32_ty, llvm_i1_ty],
+ [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>]>;
+def int_memmove : Intrinsic<[],
+ [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
+ llvm_i32_ty, llvm_i1_ty],
+ [IntrReadWriteArgMem, NoCapture<0>, NoCapture<1>]>;
+def int_memset : Intrinsic<[],
+ [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
+ llvm_i32_ty, llvm_i1_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>;
+
+// These functions do not actually read memory, but they are sensitive to the
+// rounding mode. This needs to be modelled separately; in the meantime
+// declaring them as reading memory is conservatively correct.
+let Properties = [IntrReadMem] in {
+ def int_sqrt : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_powi : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty]>;
+ def int_sin : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_cos : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_pow : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>]>;
+ def int_log : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_log10: Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_log2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_exp : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_exp2 : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+}
+
+let Properties = [IntrNoMem] in {
+ def int_fma : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>]>;
+}
+
+// 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_sigsetjmp : Intrinsic<[llvm_i32_ty] , [llvm_ptr_ty, llvm_i32_ty]>;
+def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty]>;
+
+// Internal interface for object size checking
+def int_objectsize : Intrinsic<[llvm_anyint_ty], [llvm_ptr_ty, llvm_i1_ty],
+ [IntrNoMem]>,
+ GCCBuiltin<"__builtin_object_size">;
+
+//===------------------------- Expect Intrinsics --------------------------===//
+//
+def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+ LLVMMatchType<0>], [IntrNoMem]>;
+
+//===-------------------- Bit Manipulation Intrinsics ---------------------===//
+//
+
+// None of these intrinsics accesses memory at all.
+let Properties = [IntrNoMem] in {
+ def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+ def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
+ def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
+ def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
+}
+
+//===------------------------ Debugger Intrinsics -------------------------===//
+//
+
+// None of these intrinsics accesses memory at all...but that doesn't mean the
+// optimizers can change them aggressively. Special handling needed in a few
+// places.
+let Properties = [IntrNoMem] in {
+ def int_dbg_declare : Intrinsic<[],
+ [llvm_metadata_ty, llvm_metadata_ty]>;
+ def int_dbg_value : Intrinsic<[],
+ [llvm_metadata_ty, llvm_i64_ty,
+ llvm_metadata_ty]>;
+}
+
+//===------------------ Exception Handling Intrinsics----------------------===//
+//
+
+// The result of eh.typeid.for depends on the enclosing function, but inside a
+// given function it is 'const' and may be CSE'd etc.
+def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>;
+
+def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
+def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
+
+def int_eh_unwind_init: Intrinsic<[]>,
+ GCCBuiltin<"__builtin_unwind_init">;
+
+def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
+
+let Properties = [IntrNoMem] in {
+ def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
+ def int_eh_sjlj_callsite : Intrinsic<[], [llvm_i32_ty]>;
+}
+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]>;
+
+//===---------------- Generic Variable Attribute Intrinsics----------------===//
+//
+def int_var_annotation : Intrinsic<[],
+ [llvm_ptr_ty, llvm_ptr_ty,
+ llvm_ptr_ty, llvm_i32_ty],
+ [], "llvm.var.annotation">;
+def int_ptr_annotation : Intrinsic<[LLVMAnyPointerType<llvm_anyint_ty>],
+ [LLVMMatchType<0>, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i32_ty],
+ [], "llvm.ptr.annotation">;
+def int_annotation : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, llvm_ptr_ty,
+ llvm_ptr_ty, llvm_i32_ty],
+ [], "llvm.annotation">;
+
+//===------------------------ Trampoline Intrinsics -----------------------===//
+//
+def int_init_trampoline : Intrinsic<[],
+ [llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<0>]>,
+ GCCBuiltin<"__builtin_init_trampoline">;
+
+def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
+ [IntrReadArgMem]>,
+ GCCBuiltin<"__builtin_adjust_trampoline">;
+
+//===------------------------ Overflow Intrinsics -------------------------===//
+//
+
+// Expose the carry flag from add operations on two integrals.
+def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+//===------------------------- Memory Use Markers -------------------------===//
+//
+def int_lifetime_start : Intrinsic<[],
+ [llvm_i64_ty, llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<1>]>;
+def int_lifetime_end : Intrinsic<[],
+ [llvm_i64_ty, llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<1>]>;
+def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
+ [llvm_i64_ty, llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<1>]>;
+def int_invariant_end : Intrinsic<[],
+ [llvm_descriptor_ty, llvm_i64_ty,
+ llvm_ptr_ty],
+ [IntrReadWriteArgMem, NoCapture<2>]>;
+
+//===-------------------------- Other Intrinsics --------------------------===//
+//
+def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
+ GCCBuiltin<"__builtin_flt_rounds">;
+def int_trap : Intrinsic<[]>,
+ GCCBuiltin<"__builtin_trap">;
+
+// Intrisics to support half precision floating point format
+let Properties = [IntrNoMem] in {
+def int_convert_to_fp16 : Intrinsic<[llvm_i16_ty], [llvm_float_ty]>,
+ GCCBuiltin<"__gnu_f2h_ieee">;
+def int_convert_from_fp16 : Intrinsic<[llvm_float_ty], [llvm_i16_ty]>,
+ GCCBuiltin<"__gnu_h2f_ieee">;
+}
+
+// These convert intrinsics are to support various conversions between
+// various types with rounding and saturation. NOTE: avoid using these
+// intrinsics as they might be removed sometime in the future and
+// most targets don't support them.
+def int_convertff : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertfsi : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertfui : Intrinsic<[llvm_anyfloat_ty],
+ [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertsif : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertuif : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyfloat_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertss : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertsu : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertus : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+def int_convertuu : Intrinsic<[llvm_anyint_ty],
+ [llvm_anyint_ty, llvm_i32_ty, llvm_i32_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/IntrinsicsPTX.td"
+include "llvm/IntrinsicsHexagon.td"
diff --git a/contrib/llvm/include/llvm/IntrinsicsARM.td b/contrib/llvm/include/llvm/IntrinsicsARM.td
new file mode 100644
index 000000000000..fa8034e0c2ce
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsARM.td
@@ -0,0 +1,442 @@
+//===- 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/contrib/llvm/include/llvm/IntrinsicsCellSPU.td b/contrib/llvm/include/llvm/IntrinsicsCellSPU.td
new file mode 100644
index 000000000000..1e311bbecbc6
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsCellSPU.td
@@ -0,0 +1,242 @@
+//==- 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/contrib/llvm/include/llvm/IntrinsicsHexagon.td b/contrib/llvm/include/llvm/IntrinsicsHexagon.td
new file mode 100644
index 000000000000..eb5dc8fb1e7f
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsHexagon.td
@@ -0,0 +1,3671 @@
+//===- IntrinsicsHexagon.td - Defines Hexagon 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 Hexagon-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Definitions for all Hexagon intrinsics.
+//
+// All Hexagon intrinsics start with "llvm.hexagon.".
+let TargetPrefix = "hexagon" in {
+ /// Hexagon_Intrinsic - Base class for all altivec intrinsics.
+ class Hexagon_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
+ list<LLVMType> param_types,
+ list<IntrinsicProperty> properties>
+ : GCCBuiltin<!strconcat("__builtin_", GCCIntSuffix)>,
+ Intrinsic<ret_types, param_types, properties>;
+}
+
+//===----------------------------------------------------------------------===//
+//
+// DEF_FUNCTION_TYPE_1(QI_ftype_MEM,BT_BOOL,BT_PTR) ->
+// Hexagon_qi_mem_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_mem_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_ptr_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(void_ftype_SI,BT_VOID,BT_INT) ->
+// Hexagon_void_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_void_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_void_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(HI_ftype_SI,BT_I16,BT_INT) ->
+// Hexagon_hi_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_hi_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i16_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(SI_ftype_SI,BT_INT,BT_INT) ->
+// Hexagon_si_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(DI_ftype_SI,BT_LONGLONG,BT_INT) ->
+// Hexagon_di_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(SI_ftype_DI,BT_INT,BT_LONGLONG) ->
+// Hexagon_si_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_di_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(DI_ftype_DI,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_di_di_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_di_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(QI_ftype_QI,BT_BOOL,BT_BOOL) ->
+// Hexagon_qi_qi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_qi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(QI_ftype_SI,BT_BOOL,BT_INT) ->
+// Hexagon_qi_si_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_si_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(DI_ftype_QI,BT_LONGLONG,BT_BOOL) ->
+// Hexagon_di_qi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_qi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_1(SI_ftype_QI,BT_INT,BT_BOOL) ->
+// Hexagon_si_qi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_SISI,BT_BOOL,BT_INT,BT_INT) ->
+// Hexagon_qi_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_sisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(void_ftype_SISI,BT_VOID,BT_INT,BT_INT) ->
+// Hexagon_void_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_void_sisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_void_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_SISI,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_si_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(USI_ftype_SISI,BT_UINT,BT_INT,BT_INT) ->
+// Hexagon_usi_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_usi_sisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_SISI,BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_di_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(UDI_ftype_SISI,BT_ULONGLONG,BT_INT,BT_INT) ->
+// Hexagon_udi_sisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_udi_sisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_SIDI,BT_LONGLONG,BT_INT,BT_LONGLONG) ->
+// Hexagon_di_sidi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sidi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_DISI,BT_LONGLONG,BT_LONGLONG,BT_INT) ->
+// Hexagon_di_disi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_disi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_SIDI,BT_INT,BT_INT,BT_LONGLONG) ->
+// Hexagon_si_sidi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sidi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_DIDI,BT_INT,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_si_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_didi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(DI_ftype_DIDI,BT_LONGLONG,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_di_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(UDI_ftype_DIDI,BT_ULONGLONG,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_udi_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_udi_didi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_DISI,BT_INT,BT_LONGLONG,BT_INT) ->
+// Hexagon_si_disi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_disi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_DIDI,BT_BOOL,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_didi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_QIQI,BT_BOOL,BT_BOOL,BT_BOOL) ->
+// Hexagon_qi_qiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_qiqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(QI_ftype_QIQIQI,BT_BOOL,BT_BOOL,BT_BOOL) ->
+// Hexagon_qi_qiqiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_qi_qiqiqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i1_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_QIQI,BT_INT,BT_BOOL,BT_BOOL) ->
+// Hexagon_si_qiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qiqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_2(SI_ftype_QISI,BT_INT,BT_BOOL,BT_INT) ->
+// Hexagon_si_qisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i1_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(void_ftype_SISISI,BT_VOID,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_void_sisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_void_sisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_void_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SISISI,BT_INT,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_si_sisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_SISISI,BT_LONGLONG,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_di_sisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_sisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_DISISI,BT_INT,BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_si_disisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_disisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DISISI,BT_LONGLONG,BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_di_disisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_disisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SIDISI,BT_INT,BT_INT,BT_LONGLONG,BT_INT) ->
+// Hexagon_si_sidisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sidisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DIDISI,BT_LONGLONG,BT_LONGLONG,
+// BT_LONGLONG,BT_INT) ->
+// Hexagon_di_didisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SIDIDI,BT_INT,BT_INT,BT_LONGLONG,BT_LONGLONG) ->
+// Hexagon_si_sididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sididi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty,
+ llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DIDIDI,BT_LONGLONG,BT_LONGLONG,BT_LONGLONG,
+// BT_LONGLONG) ->
+// Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_dididi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+ llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_SISIDI,BT_INT,BT_INT,BT_INT,BT_LONGLONG) ->
+// Hexagon_si_sisidi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisidi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(SI_ftype_QISISI,BT_INT,BT_BOOL,BT_INT,BT_INT) ->
+// Hexagon_si_qisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_qisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_QISISI,BT_LONGLONG,BT_BOOL,BT_INT,BT_INT) ->
+// Hexagon_di_qisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_qisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i1_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_QIDIDI,BT_LONGLONG,BT_BOOL,BT_LONGLONG,
+// BT_LONGLONG) ->
+// Hexagon_di_qididi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_qididi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty,
+ llvm_i64_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_3(DI_ftype_DIDIQI,BT_LONGLONG,BT_LONGLONG,BT_LONGLONG,
+// BT_BOOL) ->
+// Hexagon_di_didiqi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didiqi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+ llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_4(SI_ftype_SISISISI,BT_INT,BT_INT,BT_INT,BT_INT,BT_INT) ->
+// Hexagon_si_sisisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_si_sisisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+//
+// DEF_FUNCTION_TYPE_4(DI_ftype_DIDISISI,BT_LONGLONG,BT_LONGLONG,
+// BT_LONGLONG,BT_INT,BT_INT) ->
+// Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
+//
+class Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpeq : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgt,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgt : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgt">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtu,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgtu : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgtu">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpeqp,QI_ftype_DIDI,2)
+//
+def int_hexagon_C2_cmpeqp : Hexagon_qi_didi_Intrinsic<"HEXAGON.C2.cmpeqp">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtp,QI_ftype_DIDI,2)
+//
+def int_hexagon_C2_cmpgtp : Hexagon_qi_didi_Intrinsic<"HEXAGON.C2.cmpgtp">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtup,QI_ftype_DIDI,2)
+//
+def int_hexagon_C2_cmpgtup : Hexagon_qi_didi_Intrinsic<"HEXAGON.C2.cmpgtup">;
+//
+// BUILTIN_INFO(HEXAGON.C2_bitsset,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_bitsset : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.bitsset">;
+//
+// BUILTIN_INFO(HEXAGON.C2_bitsclr,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_bitsclr : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.bitsclr">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpeqi,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpeqi : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpeqi">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgti,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgti : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgti">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgtui,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgtui : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgtui">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgei,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgei : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgei">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpgeui,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpgeui : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpgeui">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmplt,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmplt : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmplt">;
+//
+// BUILTIN_INFO(HEXAGON.C2_cmpltu,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_cmpltu : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.cmpltu">;
+//
+// BUILTIN_INFO(HEXAGON.C2_bitsclri,QI_ftype_SISI,2)
+//
+def int_hexagon_C2_bitsclri : Hexagon_qi_sisi_Intrinsic<"HEXAGON.C2.bitsclri">;
+//
+// BUILTIN_INFO(HEXAGON.C2_and,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_and : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.and">;
+//
+// BUILTIN_INFO(HEXAGON.C2_or,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_or : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.or">;
+//
+// BUILTIN_INFO(HEXAGON.C2_xor,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_xor : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.xor">;
+//
+// BUILTIN_INFO(HEXAGON.C2_andn,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_andn : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.andn">;
+//
+// BUILTIN_INFO(HEXAGON.C2_not,QI_ftype_QI,1)
+//
+def int_hexagon_C2_not : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.not">;
+//
+// BUILTIN_INFO(HEXAGON.C2_orn,QI_ftype_QIQI,2)
+//
+def int_hexagon_C2_orn : Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C2.orn">;
+//
+// BUILTIN_INFO(HEXAGON.C2_pxfer_map,QI_ftype_QI,1)
+//
+def int_hexagon_C2_pxfer_map : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.pxfer.map">;
+//
+// BUILTIN_INFO(HEXAGON.C2_any8,QI_ftype_QI,1)
+//
+def int_hexagon_C2_any8 : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.any8">;
+//
+// BUILTIN_INFO(HEXAGON.C2_all8,QI_ftype_QI,1)
+//
+def int_hexagon_C2_all8 : Hexagon_qi_qi_Intrinsic<"HEXAGON.C2.all8">;
+//
+// BUILTIN_INFO(HEXAGON.C2_vitpack,SI_ftype_QIQI,2)
+//
+def int_hexagon_C2_vitpack : Hexagon_si_qiqi_Intrinsic<"HEXAGON.C2.vitpack">;
+//
+// BUILTIN_INFO(HEXAGON.C2_mux,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_mux : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.mux">;
+//
+// BUILTIN_INFO(HEXAGON.C2_muxii,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_muxii : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.muxii">;
+//
+// BUILTIN_INFO(HEXAGON.C2_muxir,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_muxir : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.muxir">;
+//
+// BUILTIN_INFO(HEXAGON.C2_muxri,SI_ftype_QISISI,3)
+//
+def int_hexagon_C2_muxri : Hexagon_si_qisisi_Intrinsic<"HEXAGON.C2.muxri">;
+//
+// BUILTIN_INFO(HEXAGON.C2_vmux,DI_ftype_QIDIDI,3)
+//
+def int_hexagon_C2_vmux : Hexagon_di_qididi_Intrinsic<"HEXAGON.C2.vmux">;
+//
+// BUILTIN_INFO(HEXAGON.C2_mask,DI_ftype_QI,1)
+//
+def int_hexagon_C2_mask : Hexagon_di_qi_Intrinsic<"HEXAGON.C2.mask">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpbeq,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpbeq : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpbeq">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpbgtu,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpbgtu : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpbgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpheq,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpheq : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpheq">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmphgt,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmphgt : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmphgt">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmphgtu,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmphgtu : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmphgtu">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpweq,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpweq : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpweq">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpwgt,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpwgt : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpwgt">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vcmpwgtu,QI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vcmpwgtu : Hexagon_qi_didi_Intrinsic<"HEXAGON.A2.vcmpwgtu">;
+//
+// BUILTIN_INFO(HEXAGON.C2_tfrpr,SI_ftype_QI,1)
+//
+def int_hexagon_C2_tfrpr : Hexagon_si_qi_Intrinsic<"HEXAGON.C2.tfrpr">;
+//
+// BUILTIN_INFO(HEXAGON.C2_tfrrp,QI_ftype_SI,1)
+//
+def int_hexagon_C2_tfrrp : Hexagon_qi_si_Intrinsic<"HEXAGON.C2.tfrrp">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_acc_sat_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_acc_sat_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.acc.sat.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_nac_sat_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpy_nac_sat_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpy.nac.sat.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_rnd_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_rnd_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.rnd.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hl_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hl_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_hl_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_hl_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_lh_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_lh_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_lh_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_lh_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_ll_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_ll_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_sat_rnd_ll_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_sat_rnd_ll_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.sat.rnd.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_acc_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_acc_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.acc.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_nac_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyd_nac_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyd.nac.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hl_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hl_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_hl_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_hl_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_lh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_lh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_lh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_lh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_ll_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_ll_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_ll_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_ll_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hl_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hl_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_hl_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_hl_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_lh_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_lh_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_lh_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_lh_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_ll_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_ll_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyd_rnd_ll_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyd_rnd_ll_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.mpyd.rnd.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_acc_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_acc_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.acc.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hl_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hl_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_hl_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_hl_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_lh_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_lh_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_lh_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_lh_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_ll_s0,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_ll_s0 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_nac_ll_s1,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_mpyu_nac_ll_s1 :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.mpyu.nac.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hh_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hh_s0 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hh_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hh_s1 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hl_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hl_s0 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_hl_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_hl_s1 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_lh_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_lh_s0 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_lh_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_lh_s1 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_ll_s0,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_ll_s0 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_ll_s1,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_ll_s1 :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_acc_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_acc_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.acc.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hl_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hl_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_hl_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_hl_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_lh_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_lh_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_lh_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_lh_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_ll_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_ll_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_nac_ll_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_mpyud_nac_ll_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.mpyud.nac.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hh_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hh_s0 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hh_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hh_s1 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hl_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hl_s0 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_hl_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_hl_s1 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.hl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_lh_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_lh_s0 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.lh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_lh_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_lh_s1 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.lh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_ll_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_ll_s0 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.ll.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyud_ll_s1,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyud_ll_s1 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.mpyud.ll.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpysmi,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpysmi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpysmi">;
+//
+// BUILTIN_INFO(HEXAGON.M2_macsip,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_macsip :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.macsip">;
+//
+// BUILTIN_INFO(HEXAGON.M2_macsin,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_macsin :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.macsin">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_dpmpyss_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.dpmpyss.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_acc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyss_acc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyss.acc.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_nac_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyss_nac_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyss.nac.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_s0,UDI_ftype_SISI,2)
+//
+def int_hexagon_M2_dpmpyuu_s0 :
+Hexagon_udi_sisi_Intrinsic<"HEXAGON.M2.dpmpyuu.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_acc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyuu_acc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyuu.acc.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyuu_nac_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_dpmpyuu_nac_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.dpmpyuu.nac.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpy_up,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpy_up :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpy.up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyu_up,USI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyu_up :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.M2.mpyu.up">;
+//
+// BUILTIN_INFO(HEXAGON.M2_dpmpyss_rnd_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_dpmpyss_rnd_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.dpmpyss.rnd.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyi,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpyi">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mpyui,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_mpyui :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.mpyui">;
+//
+// BUILTIN_INFO(HEXAGON.M2_maci,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_maci :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.maci">;
+//
+// BUILTIN_INFO(HEXAGON.M2_acci,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_acci :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.acci">;
+//
+// BUILTIN_INFO(HEXAGON.M2_accii,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_accii :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.accii">;
+//
+// BUILTIN_INFO(HEXAGON.M2_nacci,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_nacci :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.nacci">;
+//
+// BUILTIN_INFO(HEXAGON.M2_naccii,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_naccii :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.naccii">;
+//
+// BUILTIN_INFO(HEXAGON.M2_subacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_subacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.subacc">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2s_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2s_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.vmac2s.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2s_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2s_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.vmac2s.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s0pack,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s0pack :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s0pack">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2s_s1pack,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_vmpy2s_s1pack :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.vmpy2s.s1pack">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_vmac2 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.vmac2">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2es_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vmpy2es_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vmpy2es.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmpy2es_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vmpy2es_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vmpy2es.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2es_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vmac2es_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vmac2es.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2es_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vmac2es_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vmac2es.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vmac2es,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vmac2es :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vmac2es">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrmac_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrmac_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrmac.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrmpy_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrmpy_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrmpy.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpyrs_s0,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpyrs_s0 :
+Hexagon_si_didi_Intrinsic<"HEXAGON.M2.vdmpyrs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpyrs_s1,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpyrs_s1 :
+Hexagon_si_didi_Intrinsic<"HEXAGON.M2.vdmpyrs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmacs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vdmacs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vdmacs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmacs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vdmacs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vdmacs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpys_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpys_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vdmpys.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vdmpys_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vdmpys_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vdmpys.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrs_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrs_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrs_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrs_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrsc_s0,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrsc_s0 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrsc.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyrsc_s1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyrsc_s1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.cmpyrsc.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacs_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacs_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacs_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacs_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacsc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacsc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacsc.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacsc_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacsc_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacsc.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpys_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpys_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpys.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpys_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpys_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpys.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpysc_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpysc_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpysc.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpysc_s1,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpysc_s1 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpysc.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacs_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacs_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacs_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacs_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacsc_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacsc_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacsc.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cnacsc_s1,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cnacsc_s1 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cnacsc.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpys_s1,DI_ftype_DISI,2)
+//
+def int_hexagon_M2_vrcmpys_s1 :
+Hexagon_di_disi_Intrinsic<"HEXAGON.M2.vrcmpys.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpys_acc_s1,DI_ftype_DIDISI,3)
+//
+def int_hexagon_M2_vrcmpys_acc_s1 :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.M2.vrcmpys.acc.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpys_s1rp,SI_ftype_DISI,2)
+//
+def int_hexagon_M2_vrcmpys_s1rp :
+Hexagon_si_disi_Intrinsic<"HEXAGON.M2.vrcmpys.s1rp">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacls_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacls_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacls.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmachs_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmachs_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmachs.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyl_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyl_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyl.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyh_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyh_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyh.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyl_rs1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyl_rs1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.hmmpyl.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_hmmpyh_rs1,SI_ftype_SISI,2)
+//
+def int_hexagon_M2_hmmpyh_rs1 :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.M2.hmmpyh.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_s1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_s1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_s1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_s1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.s1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmaculs_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmaculs_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmaculs.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_rs0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_rs0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmacuhs_rs1,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_mmacuhs_rs1 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.mmacuhs.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyul_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyul_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyul.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_rs0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_rs0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.rs0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_mmpyuh_rs1,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_mmpyuh_rs1 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.mmpyuh.rs1">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmaci_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmaci_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmaci.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmacr_s0,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmacr_s0 :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmacr.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmaci_s0c,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmaci_s0c :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmaci.s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmacr_s0c,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vrcmacr_s0c :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vrcmacr.s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmaci_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmaci_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmaci.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmacr_s0,DI_ftype_DISISI,3)
+//
+def int_hexagon_M2_cmacr_s0 :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.M2.cmacr.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyi_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyi_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyi.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyr_s0,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyr_s0 :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyr.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyi_s0c,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyi_s0c :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyi.s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vrcmpyr_s0c,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vrcmpyr_s0c :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vrcmpyr.s0c">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyi_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyi_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpyi.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_cmpyr_s0,DI_ftype_SISI,2)
+//
+def int_hexagon_M2_cmpyr_s0 :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.M2.cmpyr.s0">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s0_sat_i,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s0_sat_i :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s0.sat.i">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s0_sat_r,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s0_sat_r :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s0.sat.r">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s1_sat_i,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s1_sat_i :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s1.sat.i">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmpy_s1_sat_r,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vcmpy_s1_sat_r :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vcmpy.s1.sat.r">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmac_s0_sat_i,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vcmac_s0_sat_i :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vcmac.s0.sat.i">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vcmac_s0_sat_r,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M2_vcmac_s0_sat_r :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M2.vcmac.s0.sat.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vcrotate,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_vcrotate :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.vcrotate">;
+//
+// BUILTIN_INFO(HEXAGON.A2_add,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_add :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.add">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sub,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_sub :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.sub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addsat,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addsat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subsat,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subsat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addi,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addi">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.hl">;
+def int_hexagon_A2_addh_l16_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.lh">;
+def int_hexagon_A2_addh_l16_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_l16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_l16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.hl">;
+def int_hexagon_A2_addh_l16_sat_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.lh">;
+def int_hexagon_A2_addh_l16_sat_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.l16.sat.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.sat.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_l16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_l16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.l16.sat.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addh_h16_sat_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_addh_h16_sat_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.addh.h16.sat.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subh_h16_sat_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subh_h16_sat_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subh.h16.sat.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_aslh,SI_ftype_SI,1)
+//
+def int_hexagon_A2_aslh :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.aslh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_asrh,SI_ftype_SI,1)
+//
+def int_hexagon_A2_asrh :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.asrh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_addp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.addp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addpsat,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_addpsat :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.addpsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_addsp,DI_ftype_SIDI,2)
+//
+def int_hexagon_A2_addsp :
+Hexagon_di_sidi_Intrinsic<"HEXAGON.A2.addsp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_subp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.subp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_neg,SI_ftype_SI,1)
+//
+def int_hexagon_A2_neg :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.neg">;
+//
+// BUILTIN_INFO(HEXAGON.A2_negsat,SI_ftype_SI,1)
+//
+def int_hexagon_A2_negsat :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.negsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_abs,SI_ftype_SI,1)
+//
+def int_hexagon_A2_abs :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.abs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_abssat,SI_ftype_SI,1)
+//
+def int_hexagon_A2_abssat :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.abssat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vconj,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vconj :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.vconj">;
+//
+// BUILTIN_INFO(HEXAGON.A2_negp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_negp :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.negp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_absp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_absp :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.absp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_max,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_max :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.max">;
+//
+// BUILTIN_INFO(HEXAGON.A2_maxu,USI_ftype_SISI,2)
+//
+def int_hexagon_A2_maxu :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.A2.maxu">;
+//
+// BUILTIN_INFO(HEXAGON.A2_min,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_min :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.min">;
+//
+// BUILTIN_INFO(HEXAGON.A2_minu,USI_ftype_SISI,2)
+//
+def int_hexagon_A2_minu :
+Hexagon_usi_sisi_Intrinsic<"HEXAGON.A2.minu">;
+//
+// BUILTIN_INFO(HEXAGON.A2_maxp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_maxp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.maxp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_maxup,UDI_ftype_DIDI,2)
+//
+def int_hexagon_A2_maxup :
+Hexagon_udi_didi_Intrinsic<"HEXAGON.A2.maxup">;
+//
+// BUILTIN_INFO(HEXAGON.A2_minp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_minp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.minp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_minup,UDI_ftype_DIDI,2)
+//
+def int_hexagon_A2_minup :
+Hexagon_udi_didi_Intrinsic<"HEXAGON.A2.minup">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfr,SI_ftype_SI,1)
+//
+def int_hexagon_A2_tfr :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.tfr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrsi,SI_ftype_SI,1)
+//
+def int_hexagon_A2_tfrsi :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.tfrsi">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_tfrp :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.tfrp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrpi,DI_ftype_SI,1)
+//
+def int_hexagon_A2_tfrpi :
+Hexagon_di_si_Intrinsic<"HEXAGON.A2.tfrpi">;
+//
+// BUILTIN_INFO(HEXAGON.A2_zxtb,SI_ftype_SI,1)
+//
+def int_hexagon_A2_zxtb :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.zxtb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sxtb,SI_ftype_SI,1)
+//
+def int_hexagon_A2_sxtb :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.sxtb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_zxth,SI_ftype_SI,1)
+//
+def int_hexagon_A2_zxth :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.zxth">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sxth,SI_ftype_SI,1)
+//
+def int_hexagon_A2_sxth :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.sxth">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combinew,DI_ftype_SISI,2)
+//
+def int_hexagon_A2_combinew :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.A2.combinew">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combineii,DI_ftype_SISI,2)
+//
+def int_hexagon_A2_combineii :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.A2.combineii">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_hh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_hh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.hh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_hl,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_hl :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.hl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_lh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_lh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.lh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_combine_ll,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_combine_ll :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.combine.ll">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfril,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_tfril :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.tfril">;
+//
+// BUILTIN_INFO(HEXAGON.A2_tfrih,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_tfrih :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.tfrih">;
+//
+// BUILTIN_INFO(HEXAGON.A2_and,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_and :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.and">;
+//
+// BUILTIN_INFO(HEXAGON.A2_or,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_or :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.or">;
+//
+// BUILTIN_INFO(HEXAGON.A2_xor,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_xor :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.xor">;
+//
+// BUILTIN_INFO(HEXAGON.A2_not,SI_ftype_SI,1)
+//
+def int_hexagon_A2_not :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.not">;
+//
+// BUILTIN_INFO(HEXAGON.M2_xor_xacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_M2_xor_xacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M2.xor.xacc">;
+//
+// BUILTIN_INFO(HEXAGON.A2_subri,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_subri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.subri">;
+//
+// BUILTIN_INFO(HEXAGON.A2_andir,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_andir :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.andir">;
+//
+// BUILTIN_INFO(HEXAGON.A2_orir,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_orir :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.orir">;
+//
+// BUILTIN_INFO(HEXAGON.A2_andp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_andp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.andp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_orp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_orp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.orp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_xorp,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_xorp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.xorp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_notp,DI_ftype_DI,1)
+//
+def int_hexagon_A2_notp :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.notp">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sxtw,DI_ftype_SI,1)
+//
+def int_hexagon_A2_sxtw :
+Hexagon_di_si_Intrinsic<"HEXAGON.A2.sxtw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sat,SI_ftype_DI,1)
+//
+def int_hexagon_A2_sat :
+Hexagon_si_di_Intrinsic<"HEXAGON.A2.sat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_sath,SI_ftype_SI,1)
+//
+def int_hexagon_A2_sath :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.sath">;
+//
+// BUILTIN_INFO(HEXAGON.A2_satuh,SI_ftype_SI,1)
+//
+def int_hexagon_A2_satuh :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.satuh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_satub,SI_ftype_SI,1)
+//
+def int_hexagon_A2_satub :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.satub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_satb,SI_ftype_SI,1)
+//
+def int_hexagon_A2_satb :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.satb">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddubs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddubs :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddubs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vadduhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vadduhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vadduhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vaddws,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vaddws :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vaddws">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svavgh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svavgh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svavghs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svavghs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svavghs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svnavgh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svnavgh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svnavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svaddh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svaddh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svaddh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svaddhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svaddhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svaddhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svadduhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svadduhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svadduhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svsubh,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svsubh :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svsubh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svsubhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svsubhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svsubhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_svsubuhs,SI_ftype_SISI,2)
+//
+def int_hexagon_A2_svsubuhs :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A2.svsubuhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vraddub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vraddub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vraddub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vraddub_acc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_A2_vraddub_acc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.A2.vraddub.acc">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vradduh,SI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vradduh :
+Hexagon_si_didi_Intrinsic<"HEXAGON.M2.vradduh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsububs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsububs :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsububs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubuhs,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubuhs :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubuhs">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vsubws,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vsubws :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vsubws">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabsh,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabsh :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabsh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabshsat,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabshsat :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabshsat">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabsw,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabsw :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabsw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vabswsat,DI_ftype_DI,1)
+//
+def int_hexagon_A2_vabswsat :
+Hexagon_di_di_Intrinsic<"HEXAGON.A2.vabswsat">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vabsdiffw,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vabsdiffw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vabsdiffw">;
+//
+// BUILTIN_INFO(HEXAGON.M2_vabsdiffh,DI_ftype_DIDI,2)
+//
+def int_hexagon_M2_vabsdiffh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.M2.vabsdiffh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vrsadub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vrsadub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vrsadub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vrsadub_acc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_A2_vrsadub_acc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.A2.vrsadub.acc">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgwr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgwr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgwr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgwr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgwr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgwr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgwcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgwcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgwcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavgwcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavgwcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavgwcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavghcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavghcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavghcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavghcr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavghcr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavghcr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguwr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguwr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguwr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavgubr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavgubr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavgubr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavguhr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavguhr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavguhr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vavghr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vavghr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vavghr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vnavghr,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vnavghr :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vnavghr">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxub,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxub :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxub">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminuh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminuh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminuh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxuh,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxuh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxuh">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vminuw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vminuw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vminuw">;
+//
+// BUILTIN_INFO(HEXAGON.A2_vmaxuw,DI_ftype_DIDI,2)
+//
+def int_hexagon_A2_vmaxuw :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A2.vmaxuw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.r.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.r.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_lsr_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.lsr.r.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_lsl_r_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.lsl.r.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.r.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.r.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.r.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsl_r_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsl.r.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.r.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.r.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.r.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsl_r_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsl.r.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.r.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.r.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.r.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsl_r_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsl.r.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_r_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_r_r_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.r.r.sat">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_r_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_r_r_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.r.r.sat">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_i_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.i.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_lsr_i_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.lsr.i.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_i_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.i.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.i.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_i_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.i.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_i_p :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.i.p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_acc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_acc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_acc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_acc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.acc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_nac,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_nac :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_nac,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_nac :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.nac">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_xacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_xacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_xacc,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_xacc :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_xacc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_xacc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_xacc,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_xacc :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.xacc">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asr_i_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asr.i.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_lsr_i_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.lsr.i.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_asl_i_r_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.asl.i.r.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_and,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_and :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.and">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asr_i_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asr.i.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_lsr_i_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.lsr.i.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_p_or,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_asl_i_p_or :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.asl.i.p.or">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_r_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asl_i_r_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asl.i.r.sat">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_rnd,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_i_r_rnd :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.i.r.rnd">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_r_rnd_goodsyntax,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_asr_i_r_rnd_goodsyntax :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.asr.i.r.rnd.goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_addasl_rrri,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_addasl_rrri :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.addasl.rrri">;
+//
+// BUILTIN_INFO(HEXAGON.S2_valignib,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_valignib :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.valignib">;
+//
+// BUILTIN_INFO(HEXAGON.S2_valignrb,DI_ftype_DIDIQI,3)
+//
+def int_hexagon_S2_valignrb :
+Hexagon_di_didiqi_Intrinsic<"HEXAGON.S2.valignrb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vspliceib,DI_ftype_DIDISI,3)
+//
+def int_hexagon_S2_vspliceib :
+Hexagon_di_didisi_Intrinsic<"HEXAGON.S2.vspliceib">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsplicerb,DI_ftype_DIDIQI,3)
+//
+def int_hexagon_S2_vsplicerb :
+Hexagon_di_didiqi_Intrinsic<"HEXAGON.S2.vsplicerb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsplatrh,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vsplatrh :
+Hexagon_di_si_Intrinsic<"HEXAGON.S2.vsplatrh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsplatrb,SI_ftype_SI,1)
+//
+def int_hexagon_S2_vsplatrb :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.vsplatrb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insert,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_insert :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.insert">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxb_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxb_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxb.goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxh_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxh_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxh.goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxw_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxw_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxw.goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tableidxd_goodsyntax,SI_ftype_SISISISI,4)
+//
+def int_hexagon_S2_tableidxd_goodsyntax :
+Hexagon_si_sisisisi_Intrinsic<"HEXAGON.S2.tableidxd.goodsyntax">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractu,SI_ftype_SISISI,3)
+//
+def int_hexagon_S2_extractu :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S2.extractu">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insertp,DI_ftype_DIDISISI,4)
+//
+def int_hexagon_S2_insertp :
+Hexagon_di_didisisi_Intrinsic<"HEXAGON.S2.insertp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractup,DI_ftype_DISISI,3)
+//
+def int_hexagon_S2_extractup :
+Hexagon_di_disisi_Intrinsic<"HEXAGON.S2.extractup">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insert_rp,SI_ftype_SISIDI,3)
+//
+def int_hexagon_S2_insert_rp :
+Hexagon_si_sisidi_Intrinsic<"HEXAGON.S2.insert.rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractu_rp,SI_ftype_SIDI,2)
+//
+def int_hexagon_S2_extractu_rp :
+Hexagon_si_sidi_Intrinsic<"HEXAGON.S2.extractu.rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_insertp_rp,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_S2_insertp_rp :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.S2.insertp.rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_extractup_rp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_extractup_rp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.extractup.rp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tstbit_i,QI_ftype_SISI,2)
+//
+def int_hexagon_S2_tstbit_i :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.S2.tstbit.i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_setbit_i,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_setbit_i :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.setbit.i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_togglebit_i,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_togglebit_i :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.togglebit.i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clrbit_i,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_clrbit_i :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.clrbit.i">;
+//
+// BUILTIN_INFO(HEXAGON.S2_tstbit_r,QI_ftype_SISI,2)
+//
+def int_hexagon_S2_tstbit_r :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.S2.tstbit.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_setbit_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_setbit_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.setbit.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_togglebit_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_togglebit_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.togglebit.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clrbit_r,SI_ftype_SISI,2)
+//
+def int_hexagon_S2_clrbit_r :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.S2.clrbit.r">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.i.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_i_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.i.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_i_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.i.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.r.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.r.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.r.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_vh,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsl_r_vh :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsl.r.vh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.i.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_i_svw_trun,SI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_i_svw_trun :
+Hexagon_si_disi_Intrinsic<"HEXAGON.S2.asr.i.svw.trun">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_svw_trun,SI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_svw_trun :
+Hexagon_si_disi_Intrinsic<"HEXAGON.S2.asr.r.svw.trun">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_i_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_i_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.i.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_i_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_i_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.i.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asr_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asr_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asr.r.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_asl_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_asl_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.asl.r.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsr_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsr_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsr.r.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lsl_r_vw,DI_ftype_DISI,2)
+//
+def int_hexagon_S2_lsl_r_vw :
+Hexagon_di_disi_Intrinsic<"HEXAGON.S2.lsl.r.vw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vrndpackwh,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vrndpackwh :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vrndpackwh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vrndpackwhs,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vrndpackwhs :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vrndpackwhs">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsxtbh,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vsxtbh :
+Hexagon_di_si_Intrinsic<"HEXAGON.S2.vsxtbh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vzxtbh,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vzxtbh :
+Hexagon_di_si_Intrinsic<"HEXAGON.S2.vzxtbh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathub,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathub :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsathub">;
+//
+// BUILTIN_INFO(HEXAGON.S2_svsathub,SI_ftype_SI,1)
+//
+def int_hexagon_S2_svsathub :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.svsathub">;
+//
+// BUILTIN_INFO(HEXAGON.S2_svsathb,SI_ftype_SI,1)
+//
+def int_hexagon_S2_svsathb :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.svsathb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathb,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathb :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsathb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunohb,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vtrunohb :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vtrunohb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunewh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_vtrunewh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.vtrunewh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunowh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_vtrunowh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.vtrunowh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vtrunehb,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vtrunehb :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vtrunehb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsxthw,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vsxthw :
+Hexagon_di_si_Intrinsic<"HEXAGON.S2.vsxthw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vzxthw,DI_ftype_SI,1)
+//
+def int_hexagon_S2_vzxthw :
+Hexagon_di_si_Intrinsic<"HEXAGON.S2.vzxthw">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwh,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwh :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsatwh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwuh,SI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwuh :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.vsatwuh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_packhl,DI_ftype_SISI,2)
+//
+def int_hexagon_S2_packhl :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.S2.packhl">;
+//
+// BUILTIN_INFO(HEXAGON.A2_swiz,SI_ftype_SI,1)
+//
+def int_hexagon_A2_swiz :
+Hexagon_si_si_Intrinsic<"HEXAGON.A2.swiz">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathub_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathub_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsathub.nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsathb_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsathb_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsathb.nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwh_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwh_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsatwh.nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_vsatwuh_nopack,DI_ftype_DI,1)
+//
+def int_hexagon_S2_vsatwuh_nopack :
+Hexagon_di_di_Intrinsic<"HEXAGON.S2.vsatwuh.nopack">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffob,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffob :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffob">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffeb,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffeb :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffeb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffoh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffoh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffoh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_shuffeh,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_shuffeh :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.shuffeh">;
+//
+// BUILTIN_INFO(HEXAGON.S2_parityp,SI_ftype_DIDI,2)
+//
+def int_hexagon_S2_parityp :
+Hexagon_si_didi_Intrinsic<"HEXAGON.S2.parityp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_lfsp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S2_lfsp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S2.lfsp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clbnorm,SI_ftype_SI,1)
+//
+def int_hexagon_S2_clbnorm :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.clbnorm">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clb,SI_ftype_SI,1)
+//
+def int_hexagon_S2_clb :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.clb">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl0,SI_ftype_SI,1)
+//
+def int_hexagon_S2_cl0 :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.cl0">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl1,SI_ftype_SI,1)
+//
+def int_hexagon_S2_cl1 :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.cl1">;
+//
+// BUILTIN_INFO(HEXAGON.S2_clbp,SI_ftype_DI,1)
+//
+def int_hexagon_S2_clbp :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.clbp">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl0p,SI_ftype_DI,1)
+//
+def int_hexagon_S2_cl0p :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.cl0p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_cl1p,SI_ftype_DI,1)
+//
+def int_hexagon_S2_cl1p :
+Hexagon_si_di_Intrinsic<"HEXAGON.S2.cl1p">;
+//
+// BUILTIN_INFO(HEXAGON.S2_brev,SI_ftype_SI,1)
+//
+def int_hexagon_S2_brev :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.brev">;
+//
+// BUILTIN_INFO(HEXAGON.S2_ct0,SI_ftype_SI,1)
+//
+def int_hexagon_S2_ct0 :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.ct0">;
+//
+// BUILTIN_INFO(HEXAGON.S2_ct1,SI_ftype_SI,1)
+//
+def int_hexagon_S2_ct1 :
+Hexagon_si_si_Intrinsic<"HEXAGON.S2.ct1">;
+//
+// BUILTIN_INFO(HEXAGON.S2_interleave,DI_ftype_DI,1)
+//
+def int_hexagon_S2_interleave :
+Hexagon_di_di_Intrinsic<"HEXAGON.S2.interleave">;
+//
+// BUILTIN_INFO(HEXAGON.S2_deinterleave,DI_ftype_DI,1)
+//
+def int_hexagon_S2_deinterleave :
+Hexagon_di_di_Intrinsic<"HEXAGON.S2.deinterleave">;
+
+//
+// BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1)
+//
+def int_hexagon_SI_to_SXTHI_asrh :
+Hexagon_si_si_Intrinsic<"SI.to.SXTHI.asrh">;
+
+//
+// BUILTIN_INFO(HEXAGON.A4_orn,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_orn :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.orn">;
+//
+// BUILTIN_INFO(HEXAGON.A4_andn,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_andn :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.andn">;
+//
+// BUILTIN_INFO(HEXAGON.A4_orn,DI_ftype_DIDI,2)
+//
+def int_hexagon_A4_ornp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A4.ornp">;
+//
+// BUILTIN_INFO(HEXAGON.A4_andn,DI_ftype_DIDI,2)
+//
+def int_hexagon_A4_andnp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.A4.andnp">;
+//
+// BUILTIN_INFO(HEXAGON.A4_combineir,DI_ftype_sisi,2)
+//
+def int_hexagon_A4_combineir :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.A4.combineir">;
+//
+// BUILTIN_INFO(HEXAGON.A4_combineir,DI_ftype_sisi,2)
+//
+def int_hexagon_A4_combineri :
+Hexagon_di_sisi_Intrinsic<"HEXAGON.A4.combineri">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpneq,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpneq :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmpneq">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpneqi,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpneqi :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmpneqi">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplte,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplte :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmplte">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmpltei,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmpltei :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmpltei">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplteu,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplteu :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmplteu">;
+//
+// BUILTIN_INFO(HEXAGON.C4_cmplteui,QI_ftype_SISI,2)
+//
+def int_hexagon_C4_cmplteui :
+Hexagon_qi_sisi_Intrinsic<"HEXAGON.C4.cmplteui">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpneq,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpneq :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpneq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpneqi,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpneqi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpneqi">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpeq,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpeq :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpeq">;
+//
+// BUILTIN_INFO(HEXAGON.A4_rcmpeqi,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_rcmpeqi :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.rcmpeqi">;
+//
+// BUILTIN_INFO(HEXAGON.C4_fastcorner9,QI_ftype_QIQI,2)
+//
+def int_hexagon_C4_fastcorner9 :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C4.fastcorner9">;
+//
+// BUILTIN_INFO(HEXAGON.C4_fastcorner9_not,QI_ftype_QIQI,2)
+//
+def int_hexagon_C4_fastcorner9_not :
+Hexagon_qi_qiqi_Intrinsic<"HEXAGON.C4.fastcorner9_not">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_andn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_andn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_and,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_and :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_and">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_orn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_orn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_and_or,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_and_or :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.and_or">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_andn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_andn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_andn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_and,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_and :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_and">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_orn,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_orn :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_orn">;
+//
+// BUILTIN_INFO(HEXAGON.C4_or_or,QI_ftype_QIQIQI,3)
+//
+def int_hexagon_C4_or_or :
+Hexagon_qi_qiqiqi_Intrinsic<"HEXAGON.C4.or_or">;
+//
+// BUILTIN_INFO(HEXAGON.S4_addaddi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_addaddi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.addaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_subaddi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_subaddi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.subaddi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_andnp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_andnp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S4.andnp">;
+//
+// BUILTIN_INFO(HEXAGON.S4_ornp,DI_ftype_DIDI,2)
+//
+def int_hexagon_S4_ornp :
+Hexagon_di_didi_Intrinsic<"HEXAGON.S4.ornp">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_xacc,DI_ftype_DIDIDI,3)
+//
+def int_hexagon_M4_xor_xacc :
+Hexagon_di_dididi_Intrinsic<"HEXAGON.M4.xor_xacc">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_andn">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_and_xor,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_and_xor :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.and_xor">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.xor_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.xor_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_xor_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_xor_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.xor_andn">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_and,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_and :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_and">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_or,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_or :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_or">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_xor,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_xor :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_xor">;
+//
+// BUILTIN_INFO(HEXAGON.M4_or_andn,SI_ftype_SISISI,3)
+//
+def int_hexagon_M4_or_andn :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.M4.or_andn">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_andix,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_andix :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.or_andix">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_andi,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_andi :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.or_andi">;
+//
+// BUILTIN_INFO(HEXAGON.S4_or_ori,SI_ftype_SISISI,3)
+//
+def int_hexagon_S4_or_ori :
+Hexagon_si_sisisi_Intrinsic<"HEXAGON.S4.or_ori">;
+//
+// BUILTIN_INFO(HEXAGON.A4_modwrapu,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_modwrapu :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.modwrapu">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cround_ri,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_cround_ri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.cround_ri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_cround_rr,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_cround_rr :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.cround_rr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_ri,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_ri :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_ri">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_rr,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_rr :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_rr">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_ri_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_ri_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_ri_sat">;
+//
+// BUILTIN_INFO(HEXAGON.A4_round_rr_sat,SI_ftype_SISI,2)
+//
+def int_hexagon_A4_round_rr_sat :
+Hexagon_si_sisi_Intrinsic<"HEXAGON.A4.round_rr_sat">;
diff --git a/contrib/llvm/include/llvm/IntrinsicsPTX.td b/contrib/llvm/include/llvm/IntrinsicsPTX.td
new file mode 100644
index 000000000000..28379c918dea
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsPTX.td
@@ -0,0 +1,92 @@
+//===- IntrinsicsPTX.td - Defines PTX 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 PTX-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "ptx" in {
+ multiclass PTXReadSpecialRegisterIntrinsic_v4i32<string prefix> {
+// FIXME: Do we need the 128-bit integer type version?
+// def _r64 : Intrinsic<[llvm_i128_ty], [], [IntrNoMem]>;
+
+// FIXME: Enable this once v4i32 support is enabled in back-end.
+// def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>;
+
+ def _x : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_x")>;
+ def _y : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_y")>;
+ def _z : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_z")>;
+ def _w : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<!strconcat(prefix, "_w")>;
+ }
+
+ class PTXReadSpecialRegisterIntrinsic_r32<string name>
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>,
+ GCCBuiltin<name>;
+
+ class PTXReadSpecialRegisterIntrinsic_r64<string name>
+ : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>,
+ GCCBuiltin<name>;
+}
+
+defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_tid">;
+defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_ntid">;
+
+def int_ptx_read_laneid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_laneid">;
+def int_ptx_read_warpid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_warpid">;
+def int_ptx_read_nwarpid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_nwarpid">;
+
+defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_ctaid">;
+defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i32
+ <"__builtin_ptx_read_nctaid">;
+
+def int_ptx_read_smid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_smid">;
+def int_ptx_read_nsmid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_nsmid">;
+def int_ptx_read_gridid : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_gridid">;
+
+def int_ptx_read_lanemask_eq : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_eq">;
+def int_ptx_read_lanemask_le : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_le">;
+def int_ptx_read_lanemask_lt : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_lt">;
+def int_ptx_read_lanemask_ge : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_ge">;
+def int_ptx_read_lanemask_gt : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_lanemask_gt">;
+
+def int_ptx_read_clock : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_clock">;
+def int_ptx_read_clock64 : PTXReadSpecialRegisterIntrinsic_r64
+ <"__builtin_ptx_read_clock64">;
+
+def int_ptx_read_pm0 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm0">;
+def int_ptx_read_pm1 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm1">;
+def int_ptx_read_pm2 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm2">;
+def int_ptx_read_pm3 : PTXReadSpecialRegisterIntrinsic_r32
+ <"__builtin_ptx_read_pm3">;
+
+let TargetPrefix = "ptx" in
+ def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>,
+ GCCBuiltin<"__builtin_ptx_bar_sync">;
diff --git a/contrib/llvm/include/llvm/IntrinsicsPowerPC.td b/contrib/llvm/include/llvm/IntrinsicsPowerPC.td
new file mode 100644
index 000000000000..da85bfba8631
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsPowerPC.td
@@ -0,0 +1,465 @@
+//===- IntrinsicsPowerPC.td - Defines PowerPC 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 PowerPC-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Definitions for all PowerPC intrinsics.
+//
+
+// Non-altivec intrinsics.
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+ // dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions.
+ def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>;
+ 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_dcbtst: Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
+
+ // sync instruction
+ def int_ppc_sync : Intrinsic<[], [], []>;
+}
+
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ /// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics.
+ class PowerPC_Vec_Intrinsic<string GCCIntSuffix, list<LLVMType> ret_types,
+ list<LLVMType> param_types,
+ list<IntrinsicProperty> properties>
+ : GCCBuiltin<!strconcat("__builtin_altivec_", GCCIntSuffix)>,
+ Intrinsic<ret_types, param_types, properties>;
+}
+
+//===----------------------------------------------------------------------===//
+// PowerPC Altivec Intrinsic Class Definitions.
+//
+
+/// PowerPC_Vec_FF_Intrinsic - A PowerPC intrinsic that takes one v4f32
+/// vector and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_FF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+
+/// PowerPC_Vec_FFF_Intrinsic - A PowerPC intrinsic that takes two v4f32
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_HHH_Intrinsic - A PowerPC intrinsic that takes two v8i16
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_HHH_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_WWW_Intrinsic - A PowerPC intrinsic that takes two v4i32
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+
+//===----------------------------------------------------------------------===//
+// PowerPC Altivec Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+ // Data Stream Control.
+ def int_ppc_altivec_dss : GCCBuiltin<"__builtin_altivec_dss">,
+ Intrinsic<[], [llvm_i32_ty], []>;
+ def int_ppc_altivec_dssall : GCCBuiltin<"__builtin_altivec_dssall">,
+ Intrinsic<[], [], []>;
+ def int_ppc_altivec_dst : GCCBuiltin<"__builtin_altivec_dst">,
+ Intrinsic<[],
+ [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ []>;
+ def int_ppc_altivec_dstt : GCCBuiltin<"__builtin_altivec_dstt">,
+ Intrinsic<[],
+ [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ []>;
+ def int_ppc_altivec_dstst : GCCBuiltin<"__builtin_altivec_dstst">,
+ Intrinsic<[],
+ [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ []>;
+ def int_ppc_altivec_dststt : GCCBuiltin<"__builtin_altivec_dststt">,
+ Intrinsic<[],
+ [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ []>;
+
+ // VSCR access.
+ def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">,
+ Intrinsic<[llvm_v8i16_ty], [], [IntrReadMem]>;
+ def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">,
+ Intrinsic<[], [llvm_v4i32_ty], []>;
+
+
+ // Loads. These don't map directly to GCC builtins because they represent the
+ // source address with a single pointer.
+ def int_ppc_altivec_lvx :
+ Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvxl :
+ Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvebx :
+ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvehx :
+ Intrinsic<[llvm_v8i16_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvewx :
+ Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty], [IntrReadMem]>;
+
+ // Stores. These don't map directly to GCC builtins because they represent the
+ // source address with a single pointer.
+ def int_ppc_altivec_stvx :
+ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>;
+ def int_ppc_altivec_stvxl :
+ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>;
+ def int_ppc_altivec_stvebx :
+ Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty], []>;
+ def int_ppc_altivec_stvehx :
+ Intrinsic<[], [llvm_v8i16_ty, llvm_ptr_ty], []>;
+ def int_ppc_altivec_stvewx :
+ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty], []>;
+
+ // Comparisons setting a vector.
+ def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpeqfp : GCCBuiltin<"__builtin_altivec_vcmpeqfp">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgefp : GCCBuiltin<"__builtin_altivec_vcmpgefp">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsw : GCCBuiltin<"__builtin_altivec_vcmpgtsw">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuw : GCCBuiltin<"__builtin_altivec_vcmpgtuw">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequh : GCCBuiltin<"__builtin_altivec_vcmpequh">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsh : GCCBuiltin<"__builtin_altivec_vcmpgtsh">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuh : GCCBuiltin<"__builtin_altivec_vcmpgtuh">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequb : GCCBuiltin<"__builtin_altivec_vcmpequb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsb : GCCBuiltin<"__builtin_altivec_vcmpgtsb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtub : GCCBuiltin<"__builtin_altivec_vcmpgtub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+ // Predicate Comparisons. The first operand specifies interpretation of CR6.
+ def int_ppc_altivec_vcmpbfp_p : GCCBuiltin<"__builtin_altivec_vcmpbfp_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpeqfp_p : GCCBuiltin<"__builtin_altivec_vcmpeqfp_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgefp_p : GCCBuiltin<"__builtin_altivec_vcmpgefp_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtfp_p : GCCBuiltin<"__builtin_altivec_vcmpgtfp_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsw_p : GCCBuiltin<"__builtin_altivec_vcmpgtsw_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuw_p : GCCBuiltin<"__builtin_altivec_vcmpgtuw_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequh_p : GCCBuiltin<"__builtin_altivec_vcmpequh_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsh_p : GCCBuiltin<"__builtin_altivec_vcmpgtsh_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuh_p : GCCBuiltin<"__builtin_altivec_vcmpgtuh_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequb_p : GCCBuiltin<"__builtin_altivec_vcmpequb_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsb_p : GCCBuiltin<"__builtin_altivec_vcmpgtsb_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtub_p : GCCBuiltin<"__builtin_altivec_vcmpgtub_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+}
+
+// Vector average.
+def int_ppc_altivec_vavgsb : PowerPC_Vec_BBB_Intrinsic<"vavgsb">;
+def int_ppc_altivec_vavgsh : PowerPC_Vec_HHH_Intrinsic<"vavgsh">;
+def int_ppc_altivec_vavgsw : PowerPC_Vec_WWW_Intrinsic<"vavgsw">;
+def int_ppc_altivec_vavgub : PowerPC_Vec_BBB_Intrinsic<"vavgub">;
+def int_ppc_altivec_vavguh : PowerPC_Vec_HHH_Intrinsic<"vavguh">;
+def int_ppc_altivec_vavguw : PowerPC_Vec_WWW_Intrinsic<"vavguw">;
+
+// Vector maximum.
+def int_ppc_altivec_vmaxfp : PowerPC_Vec_FFF_Intrinsic<"vmaxfp">;
+def int_ppc_altivec_vmaxsb : PowerPC_Vec_BBB_Intrinsic<"vmaxsb">;
+def int_ppc_altivec_vmaxsh : PowerPC_Vec_HHH_Intrinsic<"vmaxsh">;
+def int_ppc_altivec_vmaxsw : PowerPC_Vec_WWW_Intrinsic<"vmaxsw">;
+def int_ppc_altivec_vmaxub : PowerPC_Vec_BBB_Intrinsic<"vmaxub">;
+def int_ppc_altivec_vmaxuh : PowerPC_Vec_HHH_Intrinsic<"vmaxuh">;
+def int_ppc_altivec_vmaxuw : PowerPC_Vec_WWW_Intrinsic<"vmaxuw">;
+
+// Vector minimum.
+def int_ppc_altivec_vminfp : PowerPC_Vec_FFF_Intrinsic<"vminfp">;
+def int_ppc_altivec_vminsb : PowerPC_Vec_BBB_Intrinsic<"vminsb">;
+def int_ppc_altivec_vminsh : PowerPC_Vec_HHH_Intrinsic<"vminsh">;
+def int_ppc_altivec_vminsw : PowerPC_Vec_WWW_Intrinsic<"vminsw">;
+def int_ppc_altivec_vminub : PowerPC_Vec_BBB_Intrinsic<"vminub">;
+def int_ppc_altivec_vminuh : PowerPC_Vec_HHH_Intrinsic<"vminuh">;
+def int_ppc_altivec_vminuw : PowerPC_Vec_WWW_Intrinsic<"vminuw">;
+
+// Saturating adds.
+def int_ppc_altivec_vaddubs : PowerPC_Vec_BBB_Intrinsic<"vaddubs">;
+def int_ppc_altivec_vaddsbs : PowerPC_Vec_BBB_Intrinsic<"vaddsbs">;
+def int_ppc_altivec_vadduhs : PowerPC_Vec_HHH_Intrinsic<"vadduhs">;
+def int_ppc_altivec_vaddshs : PowerPC_Vec_HHH_Intrinsic<"vaddshs">;
+def int_ppc_altivec_vadduws : PowerPC_Vec_WWW_Intrinsic<"vadduws">;
+def int_ppc_altivec_vaddsws : PowerPC_Vec_WWW_Intrinsic<"vaddsws">;
+def int_ppc_altivec_vaddcuw : PowerPC_Vec_WWW_Intrinsic<"vaddcuw">;
+
+// Saturating subs.
+def int_ppc_altivec_vsububs : PowerPC_Vec_BBB_Intrinsic<"vsububs">;
+def int_ppc_altivec_vsubsbs : PowerPC_Vec_BBB_Intrinsic<"vsubsbs">;
+def int_ppc_altivec_vsubuhs : PowerPC_Vec_HHH_Intrinsic<"vsubuhs">;
+def int_ppc_altivec_vsubshs : PowerPC_Vec_HHH_Intrinsic<"vsubshs">;
+def int_ppc_altivec_vsubuws : PowerPC_Vec_WWW_Intrinsic<"vsubuws">;
+def int_ppc_altivec_vsubsws : PowerPC_Vec_WWW_Intrinsic<"vsubsws">;
+def int_ppc_altivec_vsubcuw : PowerPC_Vec_WWW_Intrinsic<"vsubcuw">;
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ // Saturating multiply-adds.
+ def int_ppc_altivec_vmhaddshs : GCCBuiltin<"__builtin_altivec_vmhaddshs">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmhraddshs : GCCBuiltin<"__builtin_altivec_vmhraddshs">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_ppc_altivec_vmaddfp : GCCBuiltin<"__builtin_altivec_vmaddfp">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vnmsubfp : GCCBuiltin<"__builtin_altivec_vnmsubfp">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+
+ // Vector Multiply Sum Intructions.
+ def int_ppc_altivec_vmsummbm : GCCBuiltin<"__builtin_altivec_vmsummbm">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumshm : GCCBuiltin<"__builtin_altivec_vmsumshm">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumshs : GCCBuiltin<"__builtin_altivec_vmsumshs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumubm : GCCBuiltin<"__builtin_altivec_vmsumubm">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumuhm : GCCBuiltin<"__builtin_altivec_vmsumuhm">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumuhs : GCCBuiltin<"__builtin_altivec_vmsumuhs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ // Vector Multiply Intructions.
+ def int_ppc_altivec_vmulesb : GCCBuiltin<"__builtin_altivec_vmulesb">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmuleuh : GCCBuiltin<"__builtin_altivec_vmuleuh">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmulouh : GCCBuiltin<"__builtin_altivec_vmulouh">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+ // Vector Sum Intructions.
+ def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum2sws : GCCBuiltin<"__builtin_altivec_vsum2sws">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum4sbs : GCCBuiltin<"__builtin_altivec_vsum4sbs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum4shs : GCCBuiltin<"__builtin_altivec_vsum4shs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum4ubs : GCCBuiltin<"__builtin_altivec_vsum4ubs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ // Other multiplies.
+ def int_ppc_altivec_vmladduhm : GCCBuiltin<"__builtin_altivec_vmladduhm">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ // Packs.
+ def int_ppc_altivec_vpkpx : GCCBuiltin<"__builtin_altivec_vpkpx">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkshss : GCCBuiltin<"__builtin_altivec_vpkshss">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkshus : GCCBuiltin<"__builtin_altivec_vpkshus">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkswss : GCCBuiltin<"__builtin_altivec_vpkswss">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ // vpkuhum is lowered to a shuffle.
+ def int_ppc_altivec_vpkuhus : GCCBuiltin<"__builtin_altivec_vpkuhus">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ // vpkuwum is lowered to a shuffle.
+ def int_ppc_altivec_vpkuwus : GCCBuiltin<"__builtin_altivec_vpkuwus">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ // Unpacks.
+ def int_ppc_altivec_vupkhpx : GCCBuiltin<"__builtin_altivec_vupkhpx">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupkhsb : GCCBuiltin<"__builtin_altivec_vupkhsb">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupkhsh : GCCBuiltin<"__builtin_altivec_vupkhsh">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklpx : GCCBuiltin<"__builtin_altivec_vupklpx">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklsb : GCCBuiltin<"__builtin_altivec_vupklsb">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklsh : GCCBuiltin<"__builtin_altivec_vupklsh">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+
+
+ // FP <-> integer conversion.
+ def int_ppc_altivec_vcfsx : GCCBuiltin<"__builtin_altivec_vcfsx">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcfux : GCCBuiltin<"__builtin_altivec_vcfux">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vctsxs : GCCBuiltin<"__builtin_altivec_vctsxs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vctuxs : GCCBuiltin<"__builtin_altivec_vctuxs">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vrfim : GCCBuiltin<"__builtin_altivec_vrfim">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vrfin : GCCBuiltin<"__builtin_altivec_vrfin">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vrfip : GCCBuiltin<"__builtin_altivec_vrfip">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vrfiz : GCCBuiltin<"__builtin_altivec_vrfiz">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+def int_ppc_altivec_vsl : PowerPC_Vec_WWW_Intrinsic<"vsl">;
+def int_ppc_altivec_vslo : PowerPC_Vec_WWW_Intrinsic<"vslo">;
+
+def int_ppc_altivec_vslb : PowerPC_Vec_BBB_Intrinsic<"vslb">;
+def int_ppc_altivec_vslh : PowerPC_Vec_HHH_Intrinsic<"vslh">;
+def int_ppc_altivec_vslw : PowerPC_Vec_WWW_Intrinsic<"vslw">;
+
+// Right Shifts.
+def int_ppc_altivec_vsr : PowerPC_Vec_WWW_Intrinsic<"vsr">;
+def int_ppc_altivec_vsro : PowerPC_Vec_WWW_Intrinsic<"vsro">;
+
+def int_ppc_altivec_vsrb : PowerPC_Vec_BBB_Intrinsic<"vsrb">;
+def int_ppc_altivec_vsrh : PowerPC_Vec_HHH_Intrinsic<"vsrh">;
+def int_ppc_altivec_vsrw : PowerPC_Vec_WWW_Intrinsic<"vsrw">;
+def int_ppc_altivec_vsrab : PowerPC_Vec_BBB_Intrinsic<"vsrab">;
+def int_ppc_altivec_vsrah : PowerPC_Vec_HHH_Intrinsic<"vsrah">;
+def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">;
+
+// Rotates.
+def int_ppc_altivec_vrlb : PowerPC_Vec_BBB_Intrinsic<"vrlb">;
+def int_ppc_altivec_vrlh : PowerPC_Vec_HHH_Intrinsic<"vrlh">;
+def int_ppc_altivec_vrlw : PowerPC_Vec_WWW_Intrinsic<"vrlw">;
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ // Miscellaneous.
+ def int_ppc_altivec_lvsl :
+ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrNoMem]>;
+ def int_ppc_altivec_lvsr :
+ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrNoMem]>;
+
+ def int_ppc_altivec_vperm : GCCBuiltin<"__builtin_altivec_vperm_4si">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vsel : GCCBuiltin<"__builtin_altivec_vsel_4si">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+def int_ppc_altivec_vexptefp : PowerPC_Vec_FF_Intrinsic<"vexptefp">;
+def int_ppc_altivec_vlogefp : PowerPC_Vec_FF_Intrinsic<"vlogefp">;
+def int_ppc_altivec_vrefp : PowerPC_Vec_FF_Intrinsic<"vrefp">;
+def int_ppc_altivec_vrsqrtefp : PowerPC_Vec_FF_Intrinsic<"vrsqrtefp">;
diff --git a/contrib/llvm/include/llvm/IntrinsicsX86.td b/contrib/llvm/include/llvm/IntrinsicsX86.td
new file mode 100644
index 000000000000..cb7b3eadc870
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsX86.td
@@ -0,0 +1,2677 @@
+//===- IntrinsicsX86.td - Defines X86 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 X86-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Interrupt traps
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_int : Intrinsic<[], [llvm_i8_ty]>;
+}
+
+//===----------------------------------------------------------------------===//
+// 3DNow!
+
+let TargetPrefix = "x86" in {
+ def int_x86_3dnow_pavgusb : GCCBuiltin<"__builtin_ia32_pavgusb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pf2id : GCCBuiltin<"__builtin_ia32_pf2id">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_3dnow_pfacc : GCCBuiltin<"__builtin_ia32_pfacc">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfadd : GCCBuiltin<"__builtin_ia32_pfadd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfcmpeq : GCCBuiltin<"__builtin_ia32_pfcmpeq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfcmpge : GCCBuiltin<"__builtin_ia32_pfcmpge">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfcmpgt : GCCBuiltin<"__builtin_ia32_pfcmpgt">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfmax : GCCBuiltin<"__builtin_ia32_pfmax">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfmin : GCCBuiltin<"__builtin_ia32_pfmin">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfmul : GCCBuiltin<"__builtin_ia32_pfmul">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfrcp : GCCBuiltin<"__builtin_ia32_pfrcp">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_3dnow_pfrcpit1 : GCCBuiltin<"__builtin_ia32_pfrcpit1">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfrcpit2 : GCCBuiltin<"__builtin_ia32_pfrcpit2">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfrsqrt : GCCBuiltin<"__builtin_ia32_pfrsqrt">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_3dnow_pfrsqit1 : GCCBuiltin<"__builtin_ia32_pfrsqit1">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfsub : GCCBuiltin<"__builtin_ia32_pfsub">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pfsubr : GCCBuiltin<"__builtin_ia32_pfsubr">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnow_pi2fd : GCCBuiltin<"__builtin_ia32_pi2fd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_3dnow_pmulhrw : GCCBuiltin<"__builtin_ia32_pmulhrw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// 3DNow! extensions
+
+let TargetPrefix = "x86" in {
+ def int_x86_3dnowa_pf2iw : GCCBuiltin<"__builtin_ia32_pf2iw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_3dnowa_pfnacc : GCCBuiltin<"__builtin_ia32_pfnacc">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnowa_pfpnacc : GCCBuiltin<"__builtin_ia32_pfpnacc">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_3dnowa_pi2fw : GCCBuiltin<"__builtin_ia32_pi2fw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_3dnowa_pswapd :
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE1
+
+// Arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_add_ss : GCCBuiltin<"__builtin_ia32_addss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_sub_ss : GCCBuiltin<"__builtin_ia32_subss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_mul_ss : GCCBuiltin<"__builtin_ia32_mulss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_div_ss : GCCBuiltin<"__builtin_ia32_divss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_sqrt_ps : GCCBuiltin<"__builtin_ia32_sqrtps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rcp_ss : GCCBuiltin<"__builtin_ia32_rcpss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rcp_ps : GCCBuiltin<"__builtin_ia32_rcpps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rsqrt_ss : GCCBuiltin<"__builtin_ia32_rsqrtss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rsqrt_ps : GCCBuiltin<"__builtin_ia32_rsqrtps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_min_ss : GCCBuiltin<"__builtin_ia32_minss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_min_ps : GCCBuiltin<"__builtin_ia32_minps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_max_ss : GCCBuiltin<"__builtin_ia32_maxss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_max_ps : GCCBuiltin<"__builtin_ia32_maxps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+// Comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_cmp_ss : GCCBuiltin<"__builtin_ia32_cmpss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse_cmp_ps : GCCBuiltin<"__builtin_ia32_cmpps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse_comieq_ss : GCCBuiltin<"__builtin_ia32_comieq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comilt_ss : GCCBuiltin<"__builtin_ia32_comilt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comile_ss : GCCBuiltin<"__builtin_ia32_comile">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comigt_ss : GCCBuiltin<"__builtin_ia32_comigt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comige_ss : GCCBuiltin<"__builtin_ia32_comige">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comineq_ss : GCCBuiltin<"__builtin_ia32_comineq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomieq_ss : GCCBuiltin<"__builtin_ia32_ucomieq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomilt_ss : GCCBuiltin<"__builtin_ia32_ucomilt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomile_ss : GCCBuiltin<"__builtin_ia32_ucomile">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomigt_ss : GCCBuiltin<"__builtin_ia32_ucomigt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomige_ss : GCCBuiltin<"__builtin_ia32_ucomige">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomineq_ss : GCCBuiltin<"__builtin_ia32_ucomineq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+
+// Conversion ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_cvtss2si : GCCBuiltin<"__builtin_ia32_cvtss2si">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtss2si64 : GCCBuiltin<"__builtin_ia32_cvtss2si64">,
+ Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvttss2si : GCCBuiltin<"__builtin_ia32_cvttss2si">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvttss2si64 : GCCBuiltin<"__builtin_ia32_cvttss2si64">,
+ Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtsi2ss : GCCBuiltin<"__builtin_ia32_cvtsi2ss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtsi642ss : GCCBuiltin<"__builtin_ia32_cvtsi642ss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtps2pi : GCCBuiltin<"__builtin_ia32_cvtps2pi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvttps2pi: GCCBuiltin<"__builtin_ia32_cvttps2pi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtpi2ps : GCCBuiltin<"__builtin_ia32_cvtpi2ps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v4f32_ty], []>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_sfence : GCCBuiltin<"__builtin_ia32_sfence">,
+ Intrinsic<[], [], []>;
+}
+
+// Control register.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_stmxcsr :
+ Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_x86_sse_ldmxcsr :
+ Intrinsic<[], [llvm_ptr_ty], []>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_movmsk_ps : GCCBuiltin<"__builtin_ia32_movmskps">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE2
+
+// FP arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_add_sd : GCCBuiltin<"__builtin_ia32_addsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_sub_sd : GCCBuiltin<"__builtin_ia32_subsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_mul_sd : GCCBuiltin<"__builtin_ia32_mulsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_div_sd : GCCBuiltin<"__builtin_ia32_divsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_sqrt_sd : GCCBuiltin<"__builtin_ia32_sqrtsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_sqrt_pd : GCCBuiltin<"__builtin_ia32_sqrtpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_min_sd : GCCBuiltin<"__builtin_ia32_minsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_min_pd : GCCBuiltin<"__builtin_ia32_minpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_max_sd : GCCBuiltin<"__builtin_ia32_maxsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_max_pd : GCCBuiltin<"__builtin_ia32_maxpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// FP comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_cmp_sd : GCCBuiltin<"__builtin_ia32_cmpsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_cmp_pd : GCCBuiltin<"__builtin_ia32_cmppd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_comieq_sd : GCCBuiltin<"__builtin_ia32_comisdeq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comilt_sd : GCCBuiltin<"__builtin_ia32_comisdlt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comile_sd : GCCBuiltin<"__builtin_ia32_comisdle">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comigt_sd : GCCBuiltin<"__builtin_ia32_comisdgt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comige_sd : GCCBuiltin<"__builtin_ia32_comisdge">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comineq_sd : GCCBuiltin<"__builtin_ia32_comisdneq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomieq_sd : GCCBuiltin<"__builtin_ia32_ucomisdeq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomilt_sd : GCCBuiltin<"__builtin_ia32_ucomisdlt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomile_sd : GCCBuiltin<"__builtin_ia32_ucomisdle">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomigt_sd : GCCBuiltin<"__builtin_ia32_ucomisdgt">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomige_sd : GCCBuiltin<"__builtin_ia32_ucomisdge">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomineq_sd : GCCBuiltin<"__builtin_ia32_ucomisdneq">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_padds_b : GCCBuiltin<"__builtin_ia32_paddsb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_padds_w : GCCBuiltin<"__builtin_ia32_paddsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pminu_b : GCCBuiltin<"__builtin_ia32_pminub128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_sse2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem, Commutative]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_psll_w : GCCBuiltin<"__builtin_ia32_psllw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psll_d : GCCBuiltin<"__builtin_ia32_pslld128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psll_q : GCCBuiltin<"__builtin_ia32_psllq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_d : GCCBuiltin<"__builtin_ia32_psrld128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_sse2_psra_w : GCCBuiltin<"__builtin_ia32_psraw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psra_d : GCCBuiltin<"__builtin_ia32_psrad128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ def int_x86_sse2_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_pslli_q : GCCBuiltin<"__builtin_ia32_psllqi128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrli_w : GCCBuiltin<"__builtin_ia32_psrlwi128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrli_d : GCCBuiltin<"__builtin_ia32_psrldi128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrli_q : GCCBuiltin<"__builtin_ia32_psrlqi128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrai_w : GCCBuiltin<"__builtin_ia32_psrawi128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrai_d : GCCBuiltin<"__builtin_ia32_psradi128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+
+ def int_x86_sse2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi128_byteshift">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi128_byteshift">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Conversion ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_cvtdq2pd : GCCBuiltin<"__builtin_ia32_cvtdq2pd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtdq2ps : GCCBuiltin<"__builtin_ia32_cvtdq2ps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtpd2dq : GCCBuiltin<"__builtin_ia32_cvtpd2dq">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttpd2dq : GCCBuiltin<"__builtin_ia32_cvttpd2dq">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtpd2ps : GCCBuiltin<"__builtin_ia32_cvtpd2ps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtps2dq : GCCBuiltin<"__builtin_ia32_cvtps2dq">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttps2dq : GCCBuiltin<"__builtin_ia32_cvttps2dq">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtps2pd : GCCBuiltin<"__builtin_ia32_cvtps2pd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsd2si : GCCBuiltin<"__builtin_ia32_cvtsd2si">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsd2si64 : GCCBuiltin<"__builtin_ia32_cvtsd2si64">,
+ Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttsd2si : GCCBuiltin<"__builtin_ia32_cvttsd2si">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttsd2si64 : GCCBuiltin<"__builtin_ia32_cvttsd2si64">,
+ Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsi2sd : GCCBuiltin<"__builtin_ia32_cvtsi2sd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsi642sd : GCCBuiltin<"__builtin_ia32_cvtsi642sd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsd2ss : GCCBuiltin<"__builtin_ia32_cvtsd2ss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtss2sd : GCCBuiltin<"__builtin_ia32_cvtss2sd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtpd2pi : GCCBuiltin<"__builtin_ia32_cvtpd2pi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse_cvttpd2pi: GCCBuiltin<"__builtin_ia32_cvttpd2pi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtpi2pd : GCCBuiltin<"__builtin_ia32_cvtpi2pd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v2f64_ty], []>;
+ def int_x86_sse2_storeu_dq : GCCBuiltin<"__builtin_ia32_storedqu">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v16i8_ty], []>;
+ def int_x86_sse2_storel_dq : GCCBuiltin<"__builtin_ia32_storelv4si">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v4i32_ty], []>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_packsswb_128 : GCCBuiltin<"__builtin_ia32_packsswb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_packssdw_128 : GCCBuiltin<"__builtin_ia32_packssdw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_packuswb_128 : GCCBuiltin<"__builtin_ia32_packuswb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_movmsk_pd : GCCBuiltin<"__builtin_ia32_movmskpd">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmovmskb_128 : GCCBuiltin<"__builtin_ia32_pmovmskb128">,
+ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_maskmov_dqu : GCCBuiltin<"__builtin_ia32_maskmovdqu">,
+ Intrinsic<[], [llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_ptr_ty], []>;
+ def int_x86_sse2_clflush : GCCBuiltin<"__builtin_ia32_clflush">,
+ Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_x86_sse2_lfence : GCCBuiltin<"__builtin_ia32_lfence">,
+ Intrinsic<[], [], []>;
+ def int_x86_sse2_mfence : GCCBuiltin<"__builtin_ia32_mfence">,
+ Intrinsic<[], [], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE3
+
+// Addition / subtraction ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_addsub_ps : GCCBuiltin<"__builtin_ia32_addsubps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse3_addsub_pd : GCCBuiltin<"__builtin_ia32_addsubpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Horizontal ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_hadd_ps : GCCBuiltin<"__builtin_ia32_haddps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse3_hadd_pd : GCCBuiltin<"__builtin_ia32_haddpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse3_hsub_ps : GCCBuiltin<"__builtin_ia32_hsubps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse3_hsub_pd : GCCBuiltin<"__builtin_ia32_hsubpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Specialized unaligned load.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_ldu_dq : GCCBuiltin<"__builtin_ia32_lddqu">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// Thread synchronization ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_monitor : GCCBuiltin<"__builtin_ia32_monitor">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_i32_ty, llvm_i32_ty], []>;
+ def int_x86_sse3_mwait : GCCBuiltin<"__builtin_ia32_mwait">,
+ Intrinsic<[], [llvm_i32_ty,
+ llvm_i32_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSSE3
+
+// Horizontal arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_ssse3_phadd_w : GCCBuiltin<"__builtin_ia32_phaddw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_phadd_w_128 : GCCBuiltin<"__builtin_ia32_phaddw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_phadd_d : GCCBuiltin<"__builtin_ia32_phaddd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_phadd_d_128 : GCCBuiltin<"__builtin_ia32_phaddd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_phadd_sw : GCCBuiltin<"__builtin_ia32_phaddsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_phadd_sw_128 : GCCBuiltin<"__builtin_ia32_phaddsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_phsub_w : GCCBuiltin<"__builtin_ia32_phsubw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_phsub_w_128 : GCCBuiltin<"__builtin_ia32_phsubw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_phsub_d : GCCBuiltin<"__builtin_ia32_phsubd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_phsub_d_128 : GCCBuiltin<"__builtin_ia32_phsubd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_phsub_sw : GCCBuiltin<"__builtin_ia32_phsubsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_phsub_sw_128 : GCCBuiltin<"__builtin_ia32_phsubsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_pmadd_ub_sw : GCCBuiltin<"__builtin_ia32_pmaddubsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_pmadd_ub_sw_128 : GCCBuiltin<"__builtin_ia32_pmaddubsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+}
+
+// Packed multiply high with round and scale
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_ssse3_pmul_hr_sw : GCCBuiltin<"__builtin_ia32_pmulhrsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_ssse3_pmul_hr_sw_128 : GCCBuiltin<"__builtin_ia32_pmulhrsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem, Commutative]>;
+}
+
+// Shuffle ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_ssse3_pshuf_b : GCCBuiltin<"__builtin_ia32_pshufb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_pshuf_b_128 : GCCBuiltin<"__builtin_ia32_pshufb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse_pshuf_w : GCCBuiltin<"__builtin_ia32_pshufw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+}
+
+// Sign ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_ssse3_psign_b : GCCBuiltin<"__builtin_ia32_psignb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_psign_b_128 : GCCBuiltin<"__builtin_ia32_psignb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_psign_w : GCCBuiltin<"__builtin_ia32_psignw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_psign_w_128 : GCCBuiltin<"__builtin_ia32_psignw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_psign_d : GCCBuiltin<"__builtin_ia32_psignd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_psign_d_128 : GCCBuiltin<"__builtin_ia32_psignd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+// Absolute value ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_ssse3_pabs_b : GCCBuiltin<"__builtin_ia32_pabsb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_pabs_b_128 : GCCBuiltin<"__builtin_ia32_pabsb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_pabs_w : GCCBuiltin<"__builtin_ia32_pabsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_pabs_w_128 : GCCBuiltin<"__builtin_ia32_pabsw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_x86_ssse3_pabs_d : GCCBuiltin<"__builtin_ia32_pabsd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_ssse3_pabs_d_128 : GCCBuiltin<"__builtin_ia32_pabsd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE4.1
+
+// FP rounding ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_round_ss : GCCBuiltin<"__builtin_ia32_roundss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse41_round_ps : GCCBuiltin<"__builtin_ia32_roundps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse41_round_sd : GCCBuiltin<"__builtin_ia32_roundsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse41_round_pd : GCCBuiltin<"__builtin_ia32_roundpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector sign and zero extend
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_pmovsxbd : GCCBuiltin<"__builtin_ia32_pmovsxbd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovsxbq : GCCBuiltin<"__builtin_ia32_pmovsxbq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovsxbw : GCCBuiltin<"__builtin_ia32_pmovsxbw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovsxdq : GCCBuiltin<"__builtin_ia32_pmovsxdq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovsxwd : GCCBuiltin<"__builtin_ia32_pmovsxwd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovsxwq : GCCBuiltin<"__builtin_ia32_pmovsxwq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovzxbd : GCCBuiltin<"__builtin_ia32_pmovzxbd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovzxbq : GCCBuiltin<"__builtin_ia32_pmovzxbq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovzxbw : GCCBuiltin<"__builtin_ia32_pmovzxbw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovzxdq : GCCBuiltin<"__builtin_ia32_pmovzxdq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovzxwd : GCCBuiltin<"__builtin_ia32_pmovzxwd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pmovzxwq : GCCBuiltin<"__builtin_ia32_pmovzxwq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+}
+
+// Vector min element
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_phminposuw : GCCBuiltin<"__builtin_ia32_phminposuw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+}
+
+// Vector compare, min, max
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_pmaxsb : GCCBuiltin<"__builtin_ia32_pmaxsb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pmaxsd : GCCBuiltin<"__builtin_ia32_pmaxsd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pmaxud : GCCBuiltin<"__builtin_ia32_pmaxud128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pmaxuw : GCCBuiltin<"__builtin_ia32_pmaxuw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pminsb : GCCBuiltin<"__builtin_ia32_pminsb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pminsd : GCCBuiltin<"__builtin_ia32_pminsd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pminud : GCCBuiltin<"__builtin_ia32_pminud128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_pminuw : GCCBuiltin<"__builtin_ia32_pminuw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem, Commutative]>;
+}
+
+// Advanced Encryption Standard (AES) Instructions
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_aesni_aesimc : GCCBuiltin<"__builtin_ia32_aesimc128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_aesni_aesenc : GCCBuiltin<"__builtin_ia32_aesenc128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_aesni_aesenclast : GCCBuiltin<"__builtin_ia32_aesenclast128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_aesni_aesdec : GCCBuiltin<"__builtin_ia32_aesdec128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_aesni_aesdeclast : GCCBuiltin<"__builtin_ia32_aesdeclast128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_aesni_aeskeygenassist :
+ GCCBuiltin<"__builtin_ia32_aeskeygenassist128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+}
+
+// Vector pack
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_packusdw : GCCBuiltin<"__builtin_ia32_packusdw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+}
+
+// Vector multiply
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_pmuldq : GCCBuiltin<"__builtin_ia32_pmuldq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem, Commutative]>;
+}
+
+// Vector extract
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_pextrb :
+ Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pextrd :
+ Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pextrq :
+ Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_extractps : GCCBuiltin<"__builtin_ia32_extractps128">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+}
+
+// Vector insert
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_insertps : GCCBuiltin<"__builtin_ia32_insertps128">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+}
+
+// Vector blend
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_pblendw : GCCBuiltin<"__builtin_ia32_pblendw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_blendpd : GCCBuiltin<"__builtin_ia32_blendpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_blendps : GCCBuiltin<"__builtin_ia32_blendps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_blendvpd : GCCBuiltin<"__builtin_ia32_blendvpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_blendvps : GCCBuiltin<"__builtin_ia32_blendvps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+}
+
+// Vector dot product
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_dppd : GCCBuiltin<"__builtin_ia32_dppd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+ def int_x86_sse41_dpps : GCCBuiltin<"__builtin_ia32_dpps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+}
+
+// Vector sum of absolute differences
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_i32_ty],
+ [IntrNoMem, Commutative]>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// Test instruction with bitwise comparison.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse41_ptestz : GCCBuiltin<"__builtin_ia32_ptestz128">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_ptestc : GCCBuiltin<"__builtin_ia32_ptestc128">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse41_ptestnzc : GCCBuiltin<"__builtin_ia32_ptestnzc128">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE4.2
+
+// Miscellaneous
+// CRC Instruction
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse42_crc32_32_8 : GCCBuiltin<"__builtin_ia32_crc32qi">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_crc32_32_16 : GCCBuiltin<"__builtin_ia32_crc32hi">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i16_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_crc32_32_32 : GCCBuiltin<"__builtin_ia32_crc32si">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_crc32_64_8 :
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_crc32_64_64 : GCCBuiltin<"__builtin_ia32_crc32di">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+}
+
+// String/text processing ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse42_pcmpistrm128 : GCCBuiltin<"__builtin_ia32_pcmpistrm128">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpistri128 : GCCBuiltin<"__builtin_ia32_pcmpistri128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestrm128 : GCCBuiltin<"__builtin_ia32_pcmpestrm128">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestri128 : GCCBuiltin<"__builtin_ia32_pcmpestri128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">,
+ Intrinsic<[llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
+ llvm_i8_ty],
+ [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// AVX
+
+// Arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_addsub_pd_256 : GCCBuiltin<"__builtin_ia32_addsubpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_addsub_ps_256 : GCCBuiltin<"__builtin_ia32_addsubps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_max_pd_256 : GCCBuiltin<"__builtin_ia32_maxpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_max_ps_256 : GCCBuiltin<"__builtin_ia32_maxps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_min_pd_256 : GCCBuiltin<"__builtin_ia32_minpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_min_ps_256 : GCCBuiltin<"__builtin_ia32_minps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+
+ def int_x86_avx_sqrt_pd_256 : GCCBuiltin<"__builtin_ia32_sqrtpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_sqrt_ps_256 : GCCBuiltin<"__builtin_ia32_sqrtps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+ def int_x86_avx_rsqrt_ps_256 : GCCBuiltin<"__builtin_ia32_rsqrtps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+ def int_x86_avx_rcp_ps_256 : GCCBuiltin<"__builtin_ia32_rcpps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+
+ def int_x86_avx_round_pd_256 : GCCBuiltin<"__builtin_ia32_roundpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx_round_ps_256 : GCCBuiltin<"__builtin_ia32_roundps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Horizontal ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_hadd_pd_256 : GCCBuiltin<"__builtin_ia32_haddpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_hsub_ps_256 : GCCBuiltin<"__builtin_ia32_hsubps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_hsub_pd_256 : GCCBuiltin<"__builtin_ia32_hsubpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_hadd_ps_256 : GCCBuiltin<"__builtin_ia32_haddps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector permutation
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_vpermilvar_pd : GCCBuiltin<"__builtin_ia32_vpermilvarpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_avx_vpermilvar_ps : GCCBuiltin<"__builtin_ia32_vpermilvarps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ def int_x86_avx_vpermilvar_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vpermilvarpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4i64_ty], [IntrNoMem]>;
+ def int_x86_avx_vpermilvar_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vpermilvarps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8i32_ty], [IntrNoMem]>;
+
+ def int_x86_avx_vperm2f128_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vperm2f128_pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_vperm2f128_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vperm2f128_ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_vperm2f128_si_256 :
+ GCCBuiltin<"__builtin_ia32_vperm2f128_si256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector blend
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_blend_pd_256 : GCCBuiltin<"__builtin_ia32_blendpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx_blend_ps_256 : GCCBuiltin<"__builtin_ia32_blendps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx_blendv_pd_256 : GCCBuiltin<"__builtin_ia32_blendvpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_blendv_ps_256 : GCCBuiltin<"__builtin_ia32_blendvps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector dot product
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_dp_ps_256 : GCCBuiltin<"__builtin_ia32_dpps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector compare
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_cmp_pd_256 : GCCBuiltin<"__builtin_ia32_cmppd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_cmp_ps_256 : GCCBuiltin<"__builtin_ia32_cmpps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector extract and insert
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_vextractf128_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vextractf128_pd256">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_vextractf128_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vextractf128_ps256">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_vextractf128_si_256 :
+ GCCBuiltin<"__builtin_ia32_vextractf128_si256">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
+
+ def int_x86_avx_vinsertf128_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vinsertf128_pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_vinsertf128_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vinsertf128_ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx_vinsertf128_si_256 :
+ GCCBuiltin<"__builtin_ia32_vinsertf128_si256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector convert
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_cvtdq2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtdq2pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_avx_cvtdq2_ps_256 : GCCBuiltin<"__builtin_ia32_cvtdq2ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8i32_ty], [IntrNoMem]>;
+ def int_x86_avx_cvt_pd2_ps_256 : GCCBuiltin<"__builtin_ia32_cvtpd2ps256">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_cvt_ps2dq_256 : GCCBuiltin<"__builtin_ia32_cvtps2dq256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_cvt_ps2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtps2pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_avx_cvtt_pd2dq_256 : GCCBuiltin<"__builtin_ia32_cvttpd2dq256">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_cvt_pd2dq_256 : GCCBuiltin<"__builtin_ia32_cvtpd2dq256">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_cvtt_ps2dq_256 : GCCBuiltin<"__builtin_ia32_cvttps2dq256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector bit test
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_vtestz_pd : GCCBuiltin<"__builtin_ia32_vtestzpd">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestc_pd : GCCBuiltin<"__builtin_ia32_vtestcpd">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestnzc_pd : GCCBuiltin<"__builtin_ia32_vtestnzcpd">,
+ Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestz_ps : GCCBuiltin<"__builtin_ia32_vtestzps">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestc_ps : GCCBuiltin<"__builtin_ia32_vtestcps">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestnzc_ps : GCCBuiltin<"__builtin_ia32_vtestnzcps">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestz_pd_256 : GCCBuiltin<"__builtin_ia32_vtestzpd256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestc_pd_256 : GCCBuiltin<"__builtin_ia32_vtestcpd256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestnzc_pd_256 : GCCBuiltin<"__builtin_ia32_vtestnzcpd256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty,
+ llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestz_ps_256 : GCCBuiltin<"__builtin_ia32_vtestzps256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestc_ps_256 : GCCBuiltin<"__builtin_ia32_vtestcps256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_vtestnzc_ps_256 : GCCBuiltin<"__builtin_ia32_vtestnzcps256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty,
+ llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_avx_ptestz_256 : GCCBuiltin<"__builtin_ia32_ptestz256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
+ llvm_v4i64_ty], [IntrNoMem]>;
+ def int_x86_avx_ptestc_256 : GCCBuiltin<"__builtin_ia32_ptestc256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
+ llvm_v4i64_ty], [IntrNoMem]>;
+ def int_x86_avx_ptestnzc_256 : GCCBuiltin<"__builtin_ia32_ptestnzc256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
+ llvm_v4i64_ty], [IntrNoMem]>;
+}
+
+// Vector extract sign mask
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_movmsk_pd_256 : GCCBuiltin<"__builtin_ia32_movmskpd256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_avx_movmsk_ps_256 : GCCBuiltin<"__builtin_ia32_movmskps256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+}
+
+// Vector zero
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_vzeroall : GCCBuiltin<"__builtin_ia32_vzeroall">,
+ Intrinsic<[], [], []>;
+ def int_x86_avx_vzeroupper : GCCBuiltin<"__builtin_ia32_vzeroupper">,
+ Intrinsic<[], [], []>;
+}
+
+// Vector load with broadcast
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_vbroadcast_ss :
+ GCCBuiltin<"__builtin_ia32_vbroadcastss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_avx_vbroadcast_sd_256 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastsd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_avx_vbroadcast_ss_256 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastss256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_avx_vbroadcastf128_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastf128_pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_avx_vbroadcastf128_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastf128_ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// SIMD load ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_ldu_dq_256 : GCCBuiltin<"__builtin_ia32_lddqu256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_storeu_pd_256 : GCCBuiltin<"__builtin_ia32_storeupd256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v4f64_ty], []>;
+ def int_x86_avx_storeu_ps_256 : GCCBuiltin<"__builtin_ia32_storeups256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v8f32_ty], []>;
+ def int_x86_avx_storeu_dq_256 : GCCBuiltin<"__builtin_ia32_storedqu256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v32i8_ty], []>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_movnt_dq_256 : GCCBuiltin<"__builtin_ia32_movntdq256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty], []>;
+ def int_x86_avx_movnt_pd_256 : GCCBuiltin<"__builtin_ia32_movntpd256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v4f64_ty], []>;
+ def int_x86_avx_movnt_ps_256 : GCCBuiltin<"__builtin_ia32_movntps256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v8f32_ty], []>;
+}
+
+// Conditional load ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_maskload_pd : GCCBuiltin<"__builtin_ia32_maskloadpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty, llvm_v2f64_ty], [IntrReadMem]>;
+ def int_x86_avx_maskload_ps : GCCBuiltin<"__builtin_ia32_maskloadps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty, llvm_v4f32_ty], [IntrReadMem]>;
+ def int_x86_avx_maskload_pd_256 : GCCBuiltin<"__builtin_ia32_maskloadpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_ptr_ty, llvm_v4f64_ty], [IntrReadMem]>;
+ def int_x86_avx_maskload_ps_256 : GCCBuiltin<"__builtin_ia32_maskloadps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8f32_ty], [IntrReadMem]>;
+}
+
+// Conditional store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx_maskstore_pd : GCCBuiltin<"__builtin_ia32_maskstorepd">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v2f64_ty, llvm_v2f64_ty], []>;
+ def int_x86_avx_maskstore_ps : GCCBuiltin<"__builtin_ia32_maskstoreps">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v4f32_ty, llvm_v4f32_ty], []>;
+ def int_x86_avx_maskstore_pd_256 :
+ GCCBuiltin<"__builtin_ia32_maskstorepd256">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v4f64_ty, llvm_v4f64_ty], []>;
+ def int_x86_avx_maskstore_ps_256 :
+ GCCBuiltin<"__builtin_ia32_maskstoreps256">,
+ Intrinsic<[], [llvm_ptr_ty,
+ llvm_v8f32_ty, llvm_v8f32_ty], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// AVX2
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_padds_b : GCCBuiltin<"__builtin_ia32_paddsb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_padds_w : GCCBuiltin<"__builtin_ia32_paddsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmul_dq : GCCBuiltin<"__builtin_ia32_pmuldq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+}
+
+// Vector min, max
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmaxu_w : GCCBuiltin<"__builtin_ia32_pmaxuw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmaxu_d : GCCBuiltin<"__builtin_ia32_pmaxud256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmaxs_b : GCCBuiltin<"__builtin_ia32_pmaxsb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmaxs_d : GCCBuiltin<"__builtin_ia32_pmaxsd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pminu_b : GCCBuiltin<"__builtin_ia32_pminub256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pminu_w : GCCBuiltin<"__builtin_ia32_pminuw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pminu_d : GCCBuiltin<"__builtin_ia32_pminud256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmins_b : GCCBuiltin<"__builtin_ia32_pminsb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_pmins_d : GCCBuiltin<"__builtin_ia32_pminsd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_psll_w : GCCBuiltin<"__builtin_ia32_psllw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_psll_d : GCCBuiltin<"__builtin_ia32_pslld256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psll_q : GCCBuiltin<"__builtin_ia32_psllq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrl_d : GCCBuiltin<"__builtin_ia32_psrld256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_avx2_psra_w : GCCBuiltin<"__builtin_ia32_psraw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_psra_d : GCCBuiltin<"__builtin_ia32_psrad256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ def int_x86_avx2_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_pslli_q : GCCBuiltin<"__builtin_ia32_psllqi256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrli_w : GCCBuiltin<"__builtin_ia32_psrlwi256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrli_d : GCCBuiltin<"__builtin_ia32_psrldi256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrli_q : GCCBuiltin<"__builtin_ia32_psrlqi256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrai_w : GCCBuiltin<"__builtin_ia32_psrawi256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrai_d : GCCBuiltin<"__builtin_ia32_psradi256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+
+ def int_x86_avx2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psll_dq_bs : GCCBuiltin<"__builtin_ia32_pslldqi256_byteshift">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_psrl_dq_bs : GCCBuiltin<"__builtin_ia32_psrldqi256_byteshift">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Pack ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_packsswb : GCCBuiltin<"__builtin_ia32_packsswb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_packssdw : GCCBuiltin<"__builtin_ia32_packssdw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_packuswb : GCCBuiltin<"__builtin_ia32_packuswb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_packusdw : GCCBuiltin<"__builtin_ia32_packusdw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem]>;
+}
+
+// Absolute value ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_pabs_b : GCCBuiltin<"__builtin_ia32_pabsb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_pabs_w : GCCBuiltin<"__builtin_ia32_pabsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_pabs_d : GCCBuiltin<"__builtin_ia32_pabsd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty], [IntrNoMem]>;
+}
+
+// Horizontal arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_phadd_w : GCCBuiltin<"__builtin_ia32_phaddw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_phadd_d : GCCBuiltin<"__builtin_ia32_phaddd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_phadd_sw : GCCBuiltin<"__builtin_ia32_phaddsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_phsub_w : GCCBuiltin<"__builtin_ia32_phsubw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_phsub_d : GCCBuiltin<"__builtin_ia32_phsubd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_phsub_sw : GCCBuiltin<"__builtin_ia32_phsubsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_pmadd_ub_sw : GCCBuiltin<"__builtin_ia32_pmaddubsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem]>;
+}
+
+// Sign ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_psign_b : GCCBuiltin<"__builtin_ia32_psignb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_psign_w : GCCBuiltin<"__builtin_ia32_psignw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_psign_d : GCCBuiltin<"__builtin_ia32_psignd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
+ llvm_v8i32_ty], [IntrNoMem]>;
+}
+
+// Packed multiply high with round and scale
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_pmul_hr_sw : GCCBuiltin<"__builtin_ia32_pmulhrsw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
+ llvm_v16i16_ty], [IntrNoMem, Commutative]>;
+}
+
+// Vector sign and zero extend
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_pmovsxbd : GCCBuiltin<"__builtin_ia32_pmovsxbd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovsxbq : GCCBuiltin<"__builtin_ia32_pmovsxbq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovsxbw : GCCBuiltin<"__builtin_ia32_pmovsxbw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovsxdq : GCCBuiltin<"__builtin_ia32_pmovsxdq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovsxwd : GCCBuiltin<"__builtin_ia32_pmovsxwd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovsxwq : GCCBuiltin<"__builtin_ia32_pmovsxwq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovzxbd : GCCBuiltin<"__builtin_ia32_pmovzxbd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovzxbq : GCCBuiltin<"__builtin_ia32_pmovzxbq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovzxbw : GCCBuiltin<"__builtin_ia32_pmovzxbw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovzxdq : GCCBuiltin<"__builtin_ia32_pmovzxdq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovzxwd : GCCBuiltin<"__builtin_ia32_pmovzxwd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_pmovzxwq : GCCBuiltin<"__builtin_ia32_pmovzxwq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v8i16_ty],
+ [IntrNoMem]>;
+}
+
+// Vector blend
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_pblendw : GCCBuiltin<"__builtin_ia32_pblendw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_pblendd_128 : GCCBuiltin<"__builtin_ia32_pblendd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_pblendd_256 : GCCBuiltin<"__builtin_ia32_pblendd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Vector load with broadcast
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_vbroadcast_ss_ps :
+ GCCBuiltin<"__builtin_ia32_vbroadcastss_ps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_avx2_vbroadcast_sd_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastsd_pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_avx2_vbroadcast_ss_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastss_ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_avx2_vbroadcasti128 :
+ GCCBuiltin<"__builtin_ia32_vbroadcastsi256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_avx2_pbroadcastb_128 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastb128">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastb_256 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastw_128 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastw128">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastw_256 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastd_128 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastd128">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastd_256 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastq_128 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastq128">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_avx2_pbroadcastq_256 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+}
+
+// Vector permutation
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_permd : GCCBuiltin<"__builtin_ia32_permvarsi256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_permps : GCCBuiltin<"__builtin_ia32_permvarsf256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_vperm2i128 : GCCBuiltin<"__builtin_ia32_permti256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_v4i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Vector extract and insert
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_vextracti128 : GCCBuiltin<"__builtin_ia32_extract128i256">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_vinserti128 : GCCBuiltin<"__builtin_ia32_insert128i256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
+ llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
+}
+
+// Conditional load ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_maskload_d : GCCBuiltin<"__builtin_ia32_maskloadd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_v4i32_ty], [IntrReadMem]>;
+ def int_x86_avx2_maskload_q : GCCBuiltin<"__builtin_ia32_maskloadq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_v2i64_ty], [IntrReadMem]>;
+ def int_x86_avx2_maskload_d_256 : GCCBuiltin<"__builtin_ia32_maskloadd256">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_ptr_ty, llvm_v8i32_ty], [IntrReadMem]>;
+ def int_x86_avx2_maskload_q_256 : GCCBuiltin<"__builtin_ia32_maskloadq256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_v4i64_ty], [IntrReadMem]>;
+}
+
+// Conditional store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_maskstore_d : GCCBuiltin<"__builtin_ia32_maskstored">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty], []>;
+ def int_x86_avx2_maskstore_q : GCCBuiltin<"__builtin_ia32_maskstoreq">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty], []>;
+ def int_x86_avx2_maskstore_d_256 :
+ GCCBuiltin<"__builtin_ia32_maskstored256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty], []>;
+ def int_x86_avx2_maskstore_q_256 :
+ GCCBuiltin<"__builtin_ia32_maskstoreq256">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty], []>;
+}
+
+// Variable bit shift ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_psllv_d : GCCBuiltin<"__builtin_ia32_psllv4si">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psllv_d_256 : GCCBuiltin<"__builtin_ia32_psllv8si">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psllv_q : GCCBuiltin<"__builtin_ia32_psllv2di">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psllv_q_256 : GCCBuiltin<"__builtin_ia32_psllv4di">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty],
+ [IntrNoMem]>;
+
+ def int_x86_avx2_psrlv_d : GCCBuiltin<"__builtin_ia32_psrlv4si">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psrlv_d_256 : GCCBuiltin<"__builtin_ia32_psrlv8si">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psrlv_q : GCCBuiltin<"__builtin_ia32_psrlv2di">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psrlv_q_256 : GCCBuiltin<"__builtin_ia32_psrlv4di">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty],
+ [IntrNoMem]>;
+
+ def int_x86_avx2_psrav_d : GCCBuiltin<"__builtin_ia32_psrav4si">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_avx2_psrav_d_256 : GCCBuiltin<"__builtin_ia32_psrav8si">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty],
+ [IntrNoMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_avx2_pmovmskb : GCCBuiltin<"__builtin_ia32_pmovmskb256">,
+ Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_pshuf_b : GCCBuiltin<"__builtin_ia32_pshufb256">,
+ Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty,
+ llvm_v32i8_ty], [IntrNoMem]>;
+ def int_x86_avx2_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw256">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
+ llvm_i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx2_movntdqa : GCCBuiltin<"__builtin_ia32_movntdqa256">,
+ Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// FMA4
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_fma4_vfmadd_ss : GCCBuiltin<"__builtin_ia32_vfmaddss">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmadd_sd : GCCBuiltin<"__builtin_ia32_vfmaddsd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmadd_ps : GCCBuiltin<"__builtin_ia32_vfmaddps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmadd_pd : GCCBuiltin<"__builtin_ia32_vfmaddpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfmaddps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfmaddpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsub_ss : GCCBuiltin<"__builtin_ia32_vfmsubss">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsub_sd : GCCBuiltin<"__builtin_ia32_vfmsubsd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsub_ps : GCCBuiltin<"__builtin_ia32_vfmsubps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsub_pd : GCCBuiltin<"__builtin_ia32_vfmsubpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfmsubps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfmsubpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmadd_ss : GCCBuiltin<"__builtin_ia32_vfnmaddss">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmadd_sd : GCCBuiltin<"__builtin_ia32_vfnmaddsd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmadd_ps : GCCBuiltin<"__builtin_ia32_vfnmaddps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmadd_pd : GCCBuiltin<"__builtin_ia32_vfnmaddpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmadd_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmaddps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmadd_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmaddpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmsub_ss : GCCBuiltin<"__builtin_ia32_vfnmsubss">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmsub_sd : GCCBuiltin<"__builtin_ia32_vfnmsubsd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmsub_ps : GCCBuiltin<"__builtin_ia32_vfnmsubps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmsub_pd : GCCBuiltin<"__builtin_ia32_vfnmsubpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmsub_ps_256 : GCCBuiltin<"__builtin_ia32_vfnmsubps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfnmsub_pd_256 : GCCBuiltin<"__builtin_ia32_vfnmsubpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmaddsub_pd : GCCBuiltin<"__builtin_ia32_vfmaddsubpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmaddsub_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vfmaddsubps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmaddsub_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vfmaddsubpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsubadd_ps : GCCBuiltin<"__builtin_ia32_vfmsubaddps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsubadd_pd : GCCBuiltin<"__builtin_ia32_vfmsubaddpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsubadd_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vfmsubaddps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma4_vfmsubadd_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vfmsubaddpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// XOP
+
+ def int_x86_xop_vpermil2pd : GCCBuiltin<"__builtin_ia32_vpermil2pd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+
+ def int_x86_xop_vpermil2pd_256 :
+ GCCBuiltin<"__builtin_ia32_vpermil2pd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
+ llvm_v4f64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+
+ def int_x86_xop_vpermil2ps : GCCBuiltin<"__builtin_ia32_vpermil2ps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpermil2ps_256 :
+ GCCBuiltin<"__builtin_ia32_vpermil2ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
+ llvm_v8f32_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+
+ def int_x86_xop_vfrcz_pd :
+ GCCBuiltin<"__builtin_ia32_vfrczpd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_xop_vfrcz_ps :
+ GCCBuiltin<"__builtin_ia32_vfrczps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_xop_vfrcz_sd :
+ GCCBuiltin<"__builtin_ia32_vfrczsd">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vfrcz_ss :
+ GCCBuiltin<"__builtin_ia32_vfrczss">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vfrcz_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vfrczpd256">,
+ Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty], [IntrNoMem]>;
+ def int_x86_xop_vfrcz_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vfrczps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty], [IntrNoMem]>;
+ def int_x86_xop_vpcmov :
+ GCCBuiltin<"__builtin_ia32_vpcmov">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcmov_256 :
+ GCCBuiltin<"__builtin_ia32_vpcmov_256">,
+ Intrinsic<[llvm_v4i64_ty],
+ [llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomeqb :
+ GCCBuiltin<"__builtin_ia32_vpcomeqb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomeqw :
+ GCCBuiltin<"__builtin_ia32_vpcomeqw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomeqd :
+ GCCBuiltin<"__builtin_ia32_vpcomeqd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomeqq :
+ GCCBuiltin<"__builtin_ia32_vpcomeqq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomequb :
+ GCCBuiltin<"__builtin_ia32_vpcomequb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomequd :
+ GCCBuiltin<"__builtin_ia32_vpcomequd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomequq :
+ GCCBuiltin<"__builtin_ia32_vpcomequq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomequw :
+ GCCBuiltin<"__builtin_ia32_vpcomequw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalseb :
+ GCCBuiltin<"__builtin_ia32_vpcomfalseb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalsed :
+ GCCBuiltin<"__builtin_ia32_vpcomfalsed">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalseq :
+ GCCBuiltin<"__builtin_ia32_vpcomfalseq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalseub :
+ GCCBuiltin<"__builtin_ia32_vpcomfalseub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalseud :
+ GCCBuiltin<"__builtin_ia32_vpcomfalseud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalseuq :
+ GCCBuiltin<"__builtin_ia32_vpcomfalseuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalseuw :
+ GCCBuiltin<"__builtin_ia32_vpcomfalseuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomfalsew :
+ GCCBuiltin<"__builtin_ia32_vpcomfalsew">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgeb :
+ GCCBuiltin<"__builtin_ia32_vpcomgeb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomged :
+ GCCBuiltin<"__builtin_ia32_vpcomged">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgeq :
+ GCCBuiltin<"__builtin_ia32_vpcomgeq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgeub :
+ GCCBuiltin<"__builtin_ia32_vpcomgeub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgeud :
+ GCCBuiltin<"__builtin_ia32_vpcomgeud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgeuq :
+ GCCBuiltin<"__builtin_ia32_vpcomgeuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgeuw :
+ GCCBuiltin<"__builtin_ia32_vpcomgeuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgew :
+ GCCBuiltin<"__builtin_ia32_vpcomgew">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtb :
+ GCCBuiltin<"__builtin_ia32_vpcomgtb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtd :
+ GCCBuiltin<"__builtin_ia32_vpcomgtd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtq :
+ GCCBuiltin<"__builtin_ia32_vpcomgtq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtub :
+ GCCBuiltin<"__builtin_ia32_vpcomgtub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtud :
+ GCCBuiltin<"__builtin_ia32_vpcomgtud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtuq :
+ GCCBuiltin<"__builtin_ia32_vpcomgtuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtuw :
+ GCCBuiltin<"__builtin_ia32_vpcomgtuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomgtw :
+ GCCBuiltin<"__builtin_ia32_vpcomgtw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomleb :
+ GCCBuiltin<"__builtin_ia32_vpcomleb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomled :
+ GCCBuiltin<"__builtin_ia32_vpcomled">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomleq :
+ GCCBuiltin<"__builtin_ia32_vpcomleq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomleub :
+ GCCBuiltin<"__builtin_ia32_vpcomleub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomleud :
+ GCCBuiltin<"__builtin_ia32_vpcomleud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomleuq :
+ GCCBuiltin<"__builtin_ia32_vpcomleuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomleuw :
+ GCCBuiltin<"__builtin_ia32_vpcomleuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomlew :
+ GCCBuiltin<"__builtin_ia32_vpcomlew">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltb :
+ GCCBuiltin<"__builtin_ia32_vpcomltb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltd :
+ GCCBuiltin<"__builtin_ia32_vpcomltd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltq :
+ GCCBuiltin<"__builtin_ia32_vpcomltq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltub :
+ GCCBuiltin<"__builtin_ia32_vpcomltub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltud :
+ GCCBuiltin<"__builtin_ia32_vpcomltud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltuq :
+ GCCBuiltin<"__builtin_ia32_vpcomltuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltuw :
+ GCCBuiltin<"__builtin_ia32_vpcomltuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomltw :
+ GCCBuiltin<"__builtin_ia32_vpcomltw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomneb :
+ GCCBuiltin<"__builtin_ia32_vpcomneb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomned :
+ GCCBuiltin<"__builtin_ia32_vpcomned">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomneq :
+ GCCBuiltin<"__builtin_ia32_vpcomneq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomneub :
+ GCCBuiltin<"__builtin_ia32_vpcomneub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomneud :
+ GCCBuiltin<"__builtin_ia32_vpcomneud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomneuq :
+ GCCBuiltin<"__builtin_ia32_vpcomneuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomneuw :
+ GCCBuiltin<"__builtin_ia32_vpcomneuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomnew :
+ GCCBuiltin<"__builtin_ia32_vpcomnew">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrueb :
+ GCCBuiltin<"__builtin_ia32_vpcomtrueb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrued :
+ GCCBuiltin<"__builtin_ia32_vpcomtrued">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrueq :
+ GCCBuiltin<"__builtin_ia32_vpcomtrueq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrueub :
+ GCCBuiltin<"__builtin_ia32_vpcomtrueub">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrueud :
+ GCCBuiltin<"__builtin_ia32_vpcomtrueud">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrueuq :
+ GCCBuiltin<"__builtin_ia32_vpcomtrueuq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtrueuw :
+ GCCBuiltin<"__builtin_ia32_vpcomtrueuw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpcomtruew :
+ GCCBuiltin<"__builtin_ia32_vpcomtruew">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vphaddbd :
+ GCCBuiltin<"__builtin_ia32_vphaddbd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddbq :
+ GCCBuiltin<"__builtin_ia32_vphaddbq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddbw :
+ GCCBuiltin<"__builtin_ia32_vphaddbw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphadddq :
+ GCCBuiltin<"__builtin_ia32_vphadddq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddubd :
+ GCCBuiltin<"__builtin_ia32_vphaddubd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddubq :
+ GCCBuiltin<"__builtin_ia32_vphaddubq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddubw :
+ GCCBuiltin<"__builtin_ia32_vphaddubw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddudq :
+ GCCBuiltin<"__builtin_ia32_vphaddudq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_xop_vphadduwd :
+ GCCBuiltin<"__builtin_ia32_vphadduwd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_xop_vphadduwq :
+ GCCBuiltin<"__builtin_ia32_vphadduwq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddwd :
+ GCCBuiltin<"__builtin_ia32_vphaddwd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_xop_vphaddwq :
+ GCCBuiltin<"__builtin_ia32_vphaddwq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_xop_vphsubbw :
+ GCCBuiltin<"__builtin_ia32_vphsubbw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_xop_vphsubdq :
+ GCCBuiltin<"__builtin_ia32_vphsubdq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_xop_vphsubwd :
+ GCCBuiltin<"__builtin_ia32_vphsubwd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_xop_vpmacsdd :
+ GCCBuiltin<"__builtin_ia32_vpmacsdd">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacsdqh :
+ GCCBuiltin<"__builtin_ia32_vpmacsdqh">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacsdql :
+ GCCBuiltin<"__builtin_ia32_vpmacsdql">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacssdd :
+ GCCBuiltin<"__builtin_ia32_vpmacssdd">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacssdqh :
+ GCCBuiltin<"__builtin_ia32_vpmacssdqh">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacssdql :
+ GCCBuiltin<"__builtin_ia32_vpmacssdql">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacsswd :
+ GCCBuiltin<"__builtin_ia32_vpmacsswd">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacssww :
+ GCCBuiltin<"__builtin_ia32_vpmacssww">,
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacswd :
+ GCCBuiltin<"__builtin_ia32_vpmacswd">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmacsww :
+ GCCBuiltin<"__builtin_ia32_vpmacsww">,
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmadcsswd :
+ GCCBuiltin<"__builtin_ia32_vpmadcsswd">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpmadcswd :
+ GCCBuiltin<"__builtin_ia32_vpmadcswd">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpperm :
+ GCCBuiltin<"__builtin_ia32_vpperm">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotb :
+ GCCBuiltin<"__builtin_ia32_vprotb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotd :
+ GCCBuiltin<"__builtin_ia32_vprotd">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotq :
+ GCCBuiltin<"__builtin_ia32_vprotq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vprotw :
+ GCCBuiltin<"__builtin_ia32_vprotw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshab :
+ GCCBuiltin<"__builtin_ia32_vpshab">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshad :
+ GCCBuiltin<"__builtin_ia32_vpshad">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshaq :
+ GCCBuiltin<"__builtin_ia32_vpshaq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshaw :
+ GCCBuiltin<"__builtin_ia32_vpshaw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshlb :
+ GCCBuiltin<"__builtin_ia32_vpshlb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshld :
+ GCCBuiltin<"__builtin_ia32_vpshld">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshlq :
+ GCCBuiltin<"__builtin_ia32_vpshlq">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_x86_xop_vpshlw :
+ GCCBuiltin<"__builtin_ia32_vpshlw">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
+// MMX
+
+// Empty MMX state op.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_emms : GCCBuiltin<"__builtin_ia32_emms">,
+ Intrinsic<[], [], []>;
+ def int_x86_mmx_femms : GCCBuiltin<"__builtin_ia32_femms">,
+ Intrinsic<[], [], []>;
+}
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ // Addition
+ def int_x86_mmx_padd_b : GCCBuiltin<"__builtin_ia32_paddb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_padd_w : GCCBuiltin<"__builtin_ia32_paddw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_padd_d : GCCBuiltin<"__builtin_ia32_paddd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_padd_q : GCCBuiltin<"__builtin_ia32_paddq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+
+ def int_x86_mmx_padds_b : GCCBuiltin<"__builtin_ia32_paddsb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_padds_w : GCCBuiltin<"__builtin_ia32_paddsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ def int_x86_mmx_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ // Subtraction
+ def int_x86_mmx_psub_b : GCCBuiltin<"__builtin_ia32_psubb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_psub_w : GCCBuiltin<"__builtin_ia32_psubw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_psub_d : GCCBuiltin<"__builtin_ia32_psubd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_psub_q : GCCBuiltin<"__builtin_ia32_psubq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+
+ def int_x86_mmx_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+
+ // Multiplication
+ def int_x86_mmx_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pmull_w : GCCBuiltin<"__builtin_ia32_pmullw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ // Bitwise operations
+ def int_x86_mmx_pand : GCCBuiltin<"__builtin_ia32_pand">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_pandn : GCCBuiltin<"__builtin_ia32_pandn">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_por : GCCBuiltin<"__builtin_ia32_por">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_pxor : GCCBuiltin<"__builtin_ia32_pxor">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+
+ // Averages
+ def int_x86_mmx_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ // Maximum
+ def int_x86_mmx_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ // Minimum
+ def int_x86_mmx_pminu_b : GCCBuiltin<"__builtin_ia32_pminub">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ // Packed sum of absolute differences
+ def int_x86_mmx_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ // Shift left logical
+ def int_x86_mmx_psll_w : GCCBuiltin<"__builtin_ia32_psllw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psll_d : GCCBuiltin<"__builtin_ia32_pslld">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psll_q : GCCBuiltin<"__builtin_ia32_psllq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrl_d : GCCBuiltin<"__builtin_ia32_psrld">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psra_w : GCCBuiltin<"__builtin_ia32_psraw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_psra_d : GCCBuiltin<"__builtin_ia32_psrad">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_pslli_w : GCCBuiltin<"__builtin_ia32_psllwi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_pslli_d : GCCBuiltin<"__builtin_ia32_pslldi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_pslli_q : GCCBuiltin<"__builtin_ia32_psllqi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psrli_w : GCCBuiltin<"__builtin_ia32_psrlwi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrli_d : GCCBuiltin<"__builtin_ia32_psrldi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrli_q : GCCBuiltin<"__builtin_ia32_psrlqi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psrai_w : GCCBuiltin<"__builtin_ia32_psrawi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrai_d : GCCBuiltin<"__builtin_ia32_psradi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// Pack ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_packsswb : GCCBuiltin<"__builtin_ia32_packsswb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_packssdw : GCCBuiltin<"__builtin_ia32_packssdw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_packuswb : GCCBuiltin<"__builtin_ia32_packuswb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// Unpacking ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_punpckhbw : GCCBuiltin<"__builtin_ia32_punpckhbw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_punpckhwd : GCCBuiltin<"__builtin_ia32_punpckhwd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_punpckhdq : GCCBuiltin<"__builtin_ia32_punpckhdq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_punpcklbw : GCCBuiltin<"__builtin_ia32_punpcklbw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_punpcklwd : GCCBuiltin<"__builtin_ia32_punpcklwd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+ def int_x86_mmx_punpckldq : GCCBuiltin<"__builtin_ia32_punpckldq">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty],
+ [IntrNoMem]>;
+}
+
+// Integer comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_pcmpeq_b : GCCBuiltin<"__builtin_ia32_pcmpeqb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pcmpeq_w : GCCBuiltin<"__builtin_ia32_pcmpeqw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+ def int_x86_mmx_pcmpeq_d : GCCBuiltin<"__builtin_ia32_pcmpeqd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem, Commutative]>;
+
+ def int_x86_mmx_pcmpgt_b : GCCBuiltin<"__builtin_ia32_pcmpgtb">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_pcmpgt_w : GCCBuiltin<"__builtin_ia32_pcmpgtw">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+ def int_x86_mmx_pcmpgt_d : GCCBuiltin<"__builtin_ia32_pcmpgtd">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty], [IntrNoMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_maskmovq : GCCBuiltin<"__builtin_ia32_maskmovq">,
+ Intrinsic<[], [llvm_x86mmx_ty, llvm_x86mmx_ty, llvm_ptr_ty], []>;
+
+ def int_x86_mmx_pmovmskb : GCCBuiltin<"__builtin_ia32_pmovmskb">,
+ Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_movnt_dq : GCCBuiltin<"__builtin_ia32_movntq">,
+ Intrinsic<[], [llvm_ptrx86mmx_ty, llvm_x86mmx_ty], []>;
+
+ def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">,
+ Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">,
+ Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// BMI
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_bmi_bextr_32 : GCCBuiltin<"__builtin_ia32_bextr_u32">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_bmi_bextr_64 : GCCBuiltin<"__builtin_ia32_bextr_u64">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_bmi_bzhi_32 : GCCBuiltin<"__builtin_ia32_bzhi_si">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_bmi_bzhi_64 : GCCBuiltin<"__builtin_ia32_bzhi_di">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_bmi_pdep_32 : GCCBuiltin<"__builtin_ia32_pdep_si">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_bmi_pdep_64 : GCCBuiltin<"__builtin_ia32_pdep_di">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_x86_bmi_pext_32 : GCCBuiltin<"__builtin_ia32_pext_si">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_bmi_pext_64 : GCCBuiltin<"__builtin_ia32_pext_di">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// FS/GS Base
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_rdfsbase_32 : GCCBuiltin<"__builtin_ia32_rdfsbase32">,
+ Intrinsic<[llvm_i32_ty], []>;
+ def int_x86_rdgsbase_32 : GCCBuiltin<"__builtin_ia32_rdgsbase32">,
+ Intrinsic<[llvm_i32_ty], []>;
+ def int_x86_rdfsbase_64 : GCCBuiltin<"__builtin_ia32_rdfsbase64">,
+ Intrinsic<[llvm_i64_ty], []>;
+ def int_x86_rdgsbase_64 : GCCBuiltin<"__builtin_ia32_rdgsbase64">,
+ Intrinsic<[llvm_i64_ty], []>;
+ def int_x86_wrfsbase_32 : GCCBuiltin<"__builtin_ia32_wrfsbase32">,
+ Intrinsic<[], [llvm_i32_ty]>;
+ def int_x86_wrgsbase_32 : GCCBuiltin<"__builtin_ia32_wrgsbase32">,
+ Intrinsic<[], [llvm_i32_ty]>;
+ def int_x86_wrfsbase_64 : GCCBuiltin<"__builtin_ia32_wrfsbase64">,
+ Intrinsic<[], [llvm_i64_ty]>;
+ def int_x86_wrgsbase_64 : GCCBuiltin<"__builtin_ia32_wrgsbase64">,
+ Intrinsic<[], [llvm_i64_ty]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Half float conversion
+
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_vcvtph2ps_128 : GCCBuiltin<"__builtin_ia32_vcvtph2ps">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_vcvtph2ps_256 : GCCBuiltin<"__builtin_ia32_vcvtph2ps256">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+}
diff --git a/contrib/llvm/include/llvm/IntrinsicsXCore.td b/contrib/llvm/include/llvm/IntrinsicsXCore.td
new file mode 100644
index 000000000000..a4813135da8d
--- /dev/null
+++ b/contrib/llvm/include/llvm/IntrinsicsXCore.td
@@ -0,0 +1,114 @@
+//==- IntrinsicsXCore.td - XCore 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 XCore-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
+ // Miscellaneous instructions.
+ def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>;
+ def int_xcore_crc8 : Intrinsic<[llvm_i32_ty, llvm_i32_ty],
+ [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_xcore_crc32 : Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_xcore_sext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_xcore_zext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>;
+ def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>;
+ def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>;
+ def int_xcore_geted : Intrinsic<[llvm_i32_ty],[]>;
+ def int_xcore_getet : Intrinsic<[llvm_i32_ty],[]>;
+ def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>;
+ def int_xcore_clrsr : Intrinsic<[],[llvm_i32_ty]>;
+
+ // Resource instructions.
+ def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>;
+ def int_xcore_freer : Intrinsic<[],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_in : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],[NoCapture<0>]>;
+ def int_xcore_int : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_inct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_out : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_outt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_outct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_chkct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_testct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_testwct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setd : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_inshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_outshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setpt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_getts : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_syncr : Intrinsic<[],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_settw : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_setev : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
+ def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
+ [NoCapture<0>, NoCapture<1>]>;
+ def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
+ [NoCapture<0>, NoCapture<1>]>;
+ def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
+ [NoCapture<0>]>;
+ def int_xcore_peek : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_endin : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+
+ // Intrinsics for events.
+ def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>;
+
+ // If any of the resources owned by the thread are ready this returns the
+ // vector of one of the ready resources. If no resources owned by the thread
+ // are ready then the operand passed to the intrinsic is returned.
+ def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>;
+
+ def int_xcore_clre : Intrinsic<[],[],[]>;
+
+ // Intrinsics for threads.
+ def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+ def int_xcore_ssync : Intrinsic <[],[]>;
+ def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+ def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+ def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
+ [NoCapture<0>]>;
+}
diff --git a/contrib/llvm/include/llvm/LLVMContext.h b/contrib/llvm/include/llvm/LLVMContext.h
new file mode 100644
index 000000000000..a8306a9e7617
--- /dev/null
+++ b/contrib/llvm/include/llvm/LLVMContext.h
@@ -0,0 +1,111 @@
+//===-- llvm/LLVMContext.h - Class for managing "global" state --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares LLVMContext, a container of "global" state in LLVM, such
+// as the global type and constant uniquing tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LLVMCONTEXT_H
+#define LLVM_LLVMCONTEXT_H
+
+namespace llvm {
+
+class LLVMContextImpl;
+class StringRef;
+class Twine;
+class Instruction;
+class Module;
+class SMDiagnostic;
+template <typename T> class SmallVectorImpl;
+
+/// This is an important class for using LLVM in a threaded context. It
+/// (opaquely) owns and manages the core "global" data of LLVM's core
+/// infrastructure, including the type and constant uniquing tables.
+/// LLVMContext itself provides no locking guarantees, so you should be careful
+/// to have one context per thread.
+class LLVMContext {
+public:
+ LLVMContextImpl *const pImpl;
+ LLVMContext();
+ ~LLVMContext();
+
+ // Pinned metadata names, which always have the same value. This is a
+ // compile-time performance optimization, not a correctness optimization.
+ enum {
+ MD_dbg = 0, // "dbg"
+ MD_tbaa = 1, // "tbaa"
+ MD_prof = 2, // "prof"
+ MD_fpmath = 3, // "fpmath"
+ MD_range = 4 // "range"
+ };
+
+ /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
+ /// This ID is uniqued across modules in the current LLVMContext.
+ unsigned getMDKindID(StringRef Name) const;
+
+ /// getMDKindNames - Populate client supplied SmallVector with the name for
+ /// custom metadata IDs registered in this LLVMContext.
+ void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
+
+
+ typedef void (*InlineAsmDiagHandlerTy)(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.
+ ///
+ /// LLVMContext doesn't take ownership or interpret either of these
+ /// pointers.
+ void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
+ void *DiagContext = 0);
+
+ /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
+ /// setInlineAsmDiagnosticHandler.
+ InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
+
+ /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
+ /// setInlineAsmDiagnosticHandler.
+ void *getInlineAsmDiagnosticContext() const;
+
+
+ /// emitError - Emit an error message to the currently installed error handler
+ /// with optional location information. This function returns, so code should
+ /// be prepared to drop the erroneous construct on the floor and "not crash".
+ /// The generated code need not be correct. The error message will be
+ /// implicitly prefixed with "error: " and should not end with a ".".
+ void emitError(unsigned LocCookie, const Twine &ErrorStr);
+ void emitError(const Instruction *I, const Twine &ErrorStr);
+ void emitError(const Twine &ErrorStr);
+
+private:
+ // DO NOT IMPLEMENT
+ LLVMContext(LLVMContext&);
+ void operator=(LLVMContext&);
+
+ /// addModule - Register a module as being instantiated in this context. If
+ /// the context is deleted, the module will be deleted as well.
+ void addModule(Module*);
+
+ /// removeModule - Unregister a module from this context.
+ void removeModule(Module*);
+
+ // Module needs access to the add/removeModule methods.
+ friend class Module;
+};
+
+/// getGlobalContext - Returns a global context. This is for LLVM clients that
+/// only care about operating on a single thread.
+extern LLVMContext &getGlobalContext();
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/LinkAllPasses.h b/contrib/llvm/include/llvm/LinkAllPasses.h
new file mode 100644
index 000000000000..2258d45ce90a
--- /dev/null
+++ b/contrib/llvm/include/llvm/LinkAllPasses.h
@@ -0,0 +1,169 @@
+//===- llvm/LinkAllPasses.h ------------ Reference All Passes ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all transformation and analysis passes for tools
+// like opt and bugpoint that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKALLPASSES_H
+#define LLVM_LINKALLPASSES_H
+
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/DomPrinter.h"
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Analysis/IntervalPartition.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/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Vectorize.h"
+#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
+#include <cstdlib>
+
+namespace {
+ struct ForcePassLinking {
+ ForcePassLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ (void) llvm::createAAEvalPass();
+ (void) llvm::createAggressiveDCEPass();
+ (void) llvm::createAliasAnalysisCounterPass();
+ (void) llvm::createAliasDebugger();
+ (void) llvm::createArgumentPromotionPass();
+ (void) llvm::createBasicAliasAnalysisPass();
+ (void) llvm::createLibCallAliasAnalysisPass(0);
+ (void) llvm::createScalarEvolutionAliasAnalysisPass();
+ (void) llvm::createTypeBasedAliasAnalysisPass();
+ (void) llvm::createBlockPlacementPass();
+ (void) llvm::createBreakCriticalEdgesPass();
+ (void) llvm::createCFGSimplificationPass();
+ (void) llvm::createConstantMergePass();
+ (void) llvm::createConstantPropagationPass();
+ (void) llvm::createDeadArgEliminationPass();
+ (void) llvm::createDeadCodeEliminationPass();
+ (void) llvm::createDeadInstEliminationPass();
+ (void) llvm::createDeadStoreEliminationPass();
+ (void) llvm::createDomOnlyPrinterPass();
+ (void) llvm::createDomPrinterPass();
+ (void) llvm::createDomOnlyViewerPass();
+ (void) llvm::createDomViewerPass();
+ (void) llvm::createEdgeProfilerPass();
+ (void) llvm::createOptimalEdgeProfilerPass();
+ (void) llvm::createPathProfilerPass();
+ (void) llvm::createGCOVProfilerPass();
+ (void) llvm::createFunctionInliningPass();
+ (void) llvm::createAlwaysInlinerPass();
+ (void) llvm::createGlobalDCEPass();
+ (void) llvm::createGlobalOptimizerPass();
+ (void) llvm::createGlobalsModRefPass();
+ (void) llvm::createIPConstantPropagationPass();
+ (void) llvm::createIPSCCPPass();
+ (void) llvm::createIndVarSimplifyPass();
+ (void) llvm::createInstructionCombiningPass();
+ (void) llvm::createInternalizePass(false);
+ (void) llvm::createLCSSAPass();
+ (void) llvm::createLICMPass();
+ (void) llvm::createLazyValueInfoPass();
+ (void) llvm::createLoopDependenceAnalysisPass();
+ (void) llvm::createLoopExtractorPass();
+ (void) llvm::createLoopSimplifyPass();
+ (void) llvm::createLoopStrengthReducePass();
+ (void) llvm::createLoopUnrollPass();
+ (void) llvm::createLoopUnswitchPass();
+ (void) llvm::createLoopIdiomPass();
+ (void) llvm::createLoopRotatePass();
+ (void) llvm::createLowerExpectIntrinsicPass();
+ (void) llvm::createLowerInvokePass();
+ (void) llvm::createLowerSwitchPass();
+ (void) llvm::createNoAAPass();
+ (void) llvm::createNoProfileInfoPass();
+ (void) llvm::createObjCARCAliasAnalysisPass();
+ (void) llvm::createObjCARCAPElimPass();
+ (void) llvm::createObjCARCExpandPass();
+ (void) llvm::createObjCARCContractPass();
+ (void) llvm::createObjCARCOptPass();
+ (void) llvm::createProfileEstimatorPass();
+ (void) llvm::createProfileVerifierPass();
+ (void) llvm::createPathProfileVerifierPass();
+ (void) llvm::createProfileLoaderPass();
+ (void) llvm::createPathProfileLoaderPass();
+ (void) llvm::createPromoteMemoryToRegisterPass();
+ (void) llvm::createDemoteRegisterToMemoryPass();
+ (void) llvm::createPruneEHPass();
+ (void) llvm::createPostDomOnlyPrinterPass();
+ (void) llvm::createPostDomPrinterPass();
+ (void) llvm::createPostDomOnlyViewerPass();
+ (void) llvm::createPostDomViewerPass();
+ (void) llvm::createReassociatePass();
+ (void) llvm::createRegionInfoPass();
+ (void) llvm::createRegionOnlyPrinterPass();
+ (void) llvm::createRegionOnlyViewerPass();
+ (void) llvm::createRegionPrinterPass();
+ (void) llvm::createRegionViewerPass();
+ (void) llvm::createSCCPPass();
+ (void) llvm::createScalarReplAggregatesPass();
+ (void) llvm::createSimplifyLibCallsPass();
+ (void) llvm::createSingleLoopExtractorPass();
+ (void) llvm::createStripSymbolsPass();
+ (void) llvm::createStripNonDebugSymbolsPass();
+ (void) llvm::createStripDeadDebugInfoPass();
+ (void) llvm::createStripDeadPrototypesPass();
+ (void) llvm::createTailCallEliminationPass();
+ (void) llvm::createJumpThreadingPass();
+ (void) llvm::createUnifyFunctionExitNodesPass();
+ (void) llvm::createInstCountPass();
+ (void) llvm::createCodeGenPreparePass();
+ (void) llvm::createEarlyCSEPass();
+ (void) llvm::createGVNPass();
+ (void) llvm::createMemCpyOptPass();
+ (void) llvm::createLoopDeletionPass();
+ (void) llvm::createPostDomTree();
+ (void) llvm::createInstructionNamerPass();
+ (void) llvm::createFunctionAttrsPass();
+ (void) llvm::createMergeFunctionsPass();
+ (void) llvm::createPrintModulePass(0);
+ (void) llvm::createPrintFunctionPass("", 0);
+ (void) llvm::createDbgInfoPrinterPass();
+ (void) llvm::createModuleDebugInfoPrinterPass();
+ (void) llvm::createPartialInliningPass();
+ (void) llvm::createLintPass();
+ (void) llvm::createSinkingPass();
+ (void) llvm::createLowerAtomicPass();
+ (void) llvm::createCorrelatedValuePropagationPass();
+ (void) llvm::createMemDepPrinter();
+ (void) llvm::createInstructionSimplifierPass();
+ (void) llvm::createBBVectorizePass();
+
+ (void)new llvm::IntervalPartition();
+ (void)new llvm::FindUsedTypes();
+ (void)new llvm::ScalarEvolution();
+ ((llvm::Function*)0)->viewCFGOnly();
+ llvm::RGPassManager RGM;
+ ((llvm::RegionPass*)0)->runOnRegion((llvm::Region*)0, RGM);
+ llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0);
+ X.add((llvm::Value*)0, 0, 0); // for -print-alias-sets
+ }
+ } ForcePassLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/LinkAllVMCore.h b/contrib/llvm/include/llvm/LinkAllVMCore.h
new file mode 100644
index 000000000000..83684c0fb65d
--- /dev/null
+++ b/contrib/llvm/include/llvm/LinkAllVMCore.h
@@ -0,0 +1,53 @@
+//===- LinkAllVMCore.h - Reference All VMCore Code --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all the object modules of the VMCore library so
+// that tools like llc, opt, and lli can ensure they are linked with all symbols
+// from libVMCore.a It should only be used from a tool's main program.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/DynamicLibrary.h"
+#include "llvm/Support/Memory.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#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 {
+ struct ForceVMCoreLinking {
+ ForceVMCoreLinking() {
+ // We must reference VMCore in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+ (void)new llvm::Module("", llvm::getGlobalContext());
+ (void)new llvm::UnreachableInst(llvm::getGlobalContext());
+ (void) llvm::createVerifierPass();
+ }
+ } ForceVMCoreLinking;
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Linker.h b/contrib/llvm/include/llvm/Linker.h
new file mode 100644
index 000000000000..1ebcd6b53863
--- /dev/null
+++ b/contrib/llvm/include/llvm/Linker.h
@@ -0,0 +1,306 @@
+//===- llvm/Linker.h - Module Linker Interface ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface to the module/file/archive linker.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER_H
+#define LLVM_LINKER_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace llvm {
+ namespace sys { class Path; }
+
+class Module;
+class LLVMContext;
+class StringRef;
+
+/// This class provides the core functionality of linking in LLVM. It retains a
+/// Module object which is the composite of the modules and libraries linked
+/// into it. The composite Module can be retrieved via the getModule() method.
+/// In this case the Linker still retains ownership of the Module. If the
+/// releaseModule() method is used, the ownership of the Module is transferred
+/// to the caller and the Linker object is only suitable for destruction.
+/// The Linker can link Modules from memory, bitcode files, or bitcode
+/// archives. It retains a set of search paths in which to find any libraries
+/// presented to it. By default, the linker will generate error and warning
+/// messages to stderr but this capability can be turned off with the
+/// QuietWarnings and QuietErrors flags. It can also be instructed to verbosely
+/// print out the linking actions it is taking with the Verbose flag.
+/// @brief The LLVM Linker.
+class Linker {
+
+ /// @name Types
+ /// @{
+ public:
+ /// This type is used to pass the linkage items (libraries and files) to
+ /// the LinkItems function. It is composed of string/bool pairs. The string
+ /// provides the name of the file or library (as with the -l option). The
+ /// bool should be true for libraries and false for files, signifying
+ /// "isLibrary".
+ /// @brief A list of linkage items
+ typedef std::vector<std::pair<std::string,bool> > ItemList;
+
+ /// This enumeration is used to control various optional features of the
+ /// linker.
+ enum ControlFlags {
+ Verbose = 1, ///< Print to stderr what steps the linker is taking
+ QuietWarnings = 2, ///< Don't print warnings to stderr.
+ QuietErrors = 4 ///< Don't print errors to stderr.
+ };
+
+ enum LinkerMode {
+ DestroySource = 0, // Allow source module to be destroyed.
+ PreserveSource = 1 // Preserve the source module.
+ };
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct the Linker with an empty module which will be given the
+ /// name \p progname. \p progname will also be used for error messages.
+ /// @brief Construct with empty module
+ Linker(StringRef progname, ///< name of tool running linker
+ StringRef modulename, ///< name of linker's end-result module
+ LLVMContext &C, ///< Context for global info
+ unsigned Flags = 0 ///< ControlFlags (one or more |'d together)
+ );
+
+ /// Construct the Linker with a previously defined module, \p aModule. Use
+ /// \p progname for the name of the program in error messages.
+ /// @brief Construct with existing module
+ Linker(StringRef progname, Module* aModule, unsigned Flags = 0);
+
+ /// Destruct the Linker.
+ /// @brief Destructor
+ ~Linker();
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// This method gets the composite module into which linking is being
+ /// done. The Composite module starts out empty and accumulates modules
+ /// linked into it via the various LinkIn* methods. This method does not
+ /// release the Module to the caller. The Linker retains ownership and will
+ /// destruct the Module when the Linker is destructed.
+ /// @see releaseModule
+ /// @brief Get the linked/composite module.
+ Module* getModule() const { return Composite; }
+
+ /// This method releases the composite Module into which linking is being
+ /// done. Ownership of the composite Module is transferred to the caller who
+ /// must arrange for its destruct. After this method is called, the Linker
+ /// terminates the linking session for the returned Module. It will no
+ /// longer utilize the returned Module but instead resets itself for
+ /// subsequent linking as if the constructor had been called. The Linker's
+ /// LibPaths and flags to be reset, and memory will be released.
+ /// @brief Release the linked/composite module.
+ Module* releaseModule();
+
+ /// This method gets the list of libraries that form the path that the
+ /// Linker will search when it is presented with a library name.
+ /// @brief Get the Linkers library path
+ const std::vector<sys::Path>& getLibPaths() const { return LibPaths; }
+
+ /// This method returns an error string suitable for printing to the user.
+ /// The return value will be empty unless an error occurred in one of the
+ /// LinkIn* methods. In those cases, the LinkIn* methods will have returned
+ /// true, indicating an error occurred. At most one error is retained so
+ /// this function always returns the last error that occurred. Note that if
+ /// the Quiet control flag is not set, the error string will have already
+ /// been printed to stderr.
+ /// @brief Get the text of the last error that occurred.
+ const std::string &getLastError() const { return Error; }
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// Add a path to the list of paths that the Linker will search. The Linker
+ /// accumulates the set of libraries added
+ /// library paths for the target platform. The standard libraries will
+ /// always be searched last. The added libraries will be searched in the
+ /// order added.
+ /// @brief Add a path.
+ void addPath(const sys::Path& path);
+
+ /// Add a set of paths to the list of paths that the linker will search. The
+ /// Linker accumulates the set of libraries added. The \p paths will be
+ /// added to the end of the Linker's list. Order will be retained.
+ /// @brief Add a set of paths.
+ void addPaths(const std::vector<std::string>& paths);
+
+ /// This method augments the Linker's list of library paths with the system
+ /// paths of the host operating system, include LLVM_LIB_SEARCH_PATH.
+ /// @brief Add the system paths.
+ void addSystemPaths();
+
+ /// Control optional linker behavior by setting a group of flags. The flags
+ /// are defined in the ControlFlags enumeration.
+ /// @see ControlFlags
+ /// @brief Set control flags.
+ void setFlags(unsigned flags) { Flags = flags; }
+
+ /// This method is the main interface to the linker. It can be used to
+ /// link a set of linkage items into a module. A linkage item is either a
+ /// file name with fully qualified path, or a library for which the Linker's
+ /// LibraryPath will be utilized to locate the library. The bool value in
+ /// the LinkItemKind should be set to true for libraries. This function
+ /// allows linking to preserve the order of specification associated with
+ /// the command line, or for other purposes. Each item will be linked in
+ /// turn as it occurs in \p Items.
+ /// @returns true if an error occurred, false otherwise
+ /// @see LinkItemKind
+ /// @see getLastError
+ bool LinkInItems (
+ const ItemList& Items, ///< Set of libraries/files to link in
+ ItemList& NativeItems ///< Output list of native files/libs
+ );
+
+ /// This function links the bitcode \p Files into the composite module.
+ /// Note that this does not do any linking of unresolved symbols. The \p
+ /// Files are all completely linked into \p HeadModule regardless of
+ /// unresolved symbols. This function just loads each bitcode file and
+ /// calls LinkInModule on them.
+ /// @returns true if an error occurs, false otherwise
+ /// @see getLastError
+ /// @brief Link in multiple files.
+ bool LinkInFiles (
+ const std::vector<sys::Path> & Files ///< Files to link in
+ );
+
+ /// This function links a single bitcode file, \p File, into the composite
+ /// module. Note that this does not attempt to resolve symbols. This method
+ /// just loads the bitcode file and calls LinkInModule on it. If an error
+ /// occurs, the Linker's error string is set.
+ /// @returns true if an error occurs, false otherwise
+ /// @see getLastError
+ /// @brief Link in a single file.
+ bool LinkInFile(
+ const sys::Path& File, ///< File to link in.
+ bool &is_native ///< Indicates if the file is native object file
+ );
+
+ /// This function provides a way to selectively link in a set of modules,
+ /// found in libraries, based on the unresolved symbols in the composite
+ /// module. Each item in \p Libraries should be the base name of a library,
+ /// as if given with the -l option of a linker tool. The Linker's LibPaths
+ /// are searched for the \p Libraries and any found will be linked in with
+ /// LinkInArchive. If an error occurs, the Linker's error string is set.
+ /// @see LinkInArchive
+ /// @see getLastError
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Link libraries into the module
+ bool LinkInLibraries (
+ const std::vector<std::string> & Libraries ///< Libraries to link in
+ );
+
+ /// This function provides a way to selectively link in a set of modules,
+ /// found in one library, based on the unresolved symbols in the composite
+ /// module.The \p Library should be the base name of a library, as if given
+ /// with the -l option of a linker tool. The Linker's LibPaths are searched
+ /// for the \p Library and if found, it will be linked in with via the
+ /// LinkInArchive method. If an error occurs, the Linker's error string is
+ /// set.
+ /// @see LinkInArchive
+ /// @see getLastError
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Link one library into the module
+ bool LinkInLibrary (
+ StringRef Library, ///< The library to link in
+ bool& is_native ///< Indicates if lib a native library
+ );
+
+ /// This function links one bitcode archive, \p Filename, into the module.
+ /// The archive is searched to resolve outstanding symbols. Any modules in
+ /// the archive that resolve outstanding symbols will be linked in. The
+ /// library is searched repeatedly until no more modules that resolve
+ /// symbols can be found. If an error occurs, the error string is set.
+ /// To speed up this function, ensure the archive has been processed
+ /// llvm-ranlib or the S option was given to llvm-ar when the archive was
+ /// created. These tools add a symbol table to the archive which makes the
+ /// search for undefined symbols much faster.
+ /// @see getLastError
+ /// @returns true if an error occurs, otherwise false.
+ /// @brief Link in one archive.
+ bool LinkInArchive(
+ const sys::Path& Filename, ///< Filename of the archive to link
+ bool& is_native ///< Indicates if archive is a native archive
+ );
+
+ /// This method links the \p Src module into the Linker's Composite module
+ /// by calling LinkModules. All the other LinkIn* methods eventually
+ /// result in calling this method to link a Module into the Linker's
+ /// composite.
+ /// @see LinkModules
+ /// @returns True if an error occurs, false otherwise.
+ /// @brief Link in a module.
+ bool LinkInModule(
+ Module* Src, ///< Module linked into \p Dest
+ std::string* ErrorMsg = 0 /// Error/diagnostic string
+ ) {
+ return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg );
+ }
+
+ /// This is the heart of the linker. This method will take unconditional
+ /// control of the \p Src module and link it into the \p Dest module. The
+ /// \p Src module will be destructed or subsumed by this method. In either
+ /// case it is not usable by the caller after this method is invoked. Only
+ /// the \p Dest module will remain. The \p Src module is linked into the
+ /// Linker's composite module such that types, global variables, functions,
+ /// and etc. are matched and resolved. If an error occurs, this function
+ /// returns true and ErrorMsg is set to a descriptive message about the
+ /// error.
+ /// @returns True if an error occurs, false otherwise.
+ /// @brief Generically link two modules together.
+ static bool LinkModules(Module* Dest, Module* Src, unsigned Mode,
+ std::string* ErrorMsg);
+
+ /// This function looks through the Linker's LibPaths to find a library with
+ /// the name \p Filename. If the library cannot be found, the returned path
+ /// will be empty (i.e. sys::Path::isEmpty() will return true).
+ /// @returns A sys::Path to the found library
+ /// @brief Find a library from its short name.
+ sys::Path FindLib(StringRef Filename);
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// Read in and parse the bitcode file named by FN and return the
+ /// Module it contains (wrapped in an auto_ptr), or 0 if an error occurs.
+ std::auto_ptr<Module> LoadObject(const sys::Path& FN);
+
+ bool warning(StringRef message);
+ bool error(StringRef message);
+ void verbose(StringRef message);
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ LLVMContext& Context; ///< The context for global information
+ Module* Composite; ///< The composite module linked together
+ std::vector<sys::Path> LibPaths; ///< The library search paths
+ unsigned Flags; ///< Flags to control optional behavior.
+ std::string Error; ///< Text of error that occurred.
+ std::string ProgramName; ///< Name of the program being linked
+ /// @}
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/EDInstInfo.h b/contrib/llvm/include/llvm/MC/EDInstInfo.h
new file mode 100644
index 000000000000..0b9d3f63f677
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/EDInstInfo.h
@@ -0,0 +1,29 @@
+//===-- 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/contrib/llvm/include/llvm/MC/MCAsmBackend.h b/contrib/llvm/include/llvm/MC/MCAsmBackend.h
new file mode 100644
index 000000000000..05e6286b7cc5
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAsmBackend.h
@@ -0,0 +1,150 @@
+//===-- llvm/MC/MCAsmBack.h - MC Asm Backend --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMBACKEND_H
+#define LLVM_MC_MCASMBACKEND_H
+
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+class MCAsmLayout;
+class MCAssembler;
+class MCELFObjectTargetWriter;
+struct MCFixupKindInfo;
+class MCFragment;
+class MCInst;
+class MCInstFragment;
+class MCObjectWriter;
+class MCSection;
+class MCValue;
+class raw_ostream;
+
+/// MCAsmBackend - Generic interface to target specific assembler backends.
+class MCAsmBackend {
+ MCAsmBackend(const MCAsmBackend &); // DO NOT IMPLEMENT
+ void operator=(const MCAsmBackend &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ MCAsmBackend();
+
+ unsigned HasReliableSymbolDifference : 1;
+
+public:
+ virtual ~MCAsmBackend();
+
+ /// 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;
+
+ /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable
+ /// non-standard ELFObjectWriters.
+ virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const {
+ llvm_unreachable("createELFObjectTargetWriter is not supported by asm "
+ "backend");
+ }
+
+ /// hasReliableSymbolDifference - Check whether this target implements
+ /// accurate relocations for differences between symbols. If not, differences
+ /// between symbols will always be relocatable expressions and any references
+ /// to temporary symbols will be assumed to be in the same atom, unless they
+ /// reside in a different section.
+ ///
+ /// This should always be true (since it results in fewer relocations with no
+ /// loss of functionality), but is currently supported as a way to maintain
+ /// exact object compatibility with Darwin 'as' (on non-x86_64). It should
+ /// eventually should be eliminated.
+ bool hasReliableSymbolDifference() const {
+ return HasReliableSymbolDifference;
+ }
+
+ /// doesSectionRequireSymbols - Check whether the given section requires that
+ /// all symbols (even temporaries) have symbol table entries.
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+ return false;
+ }
+
+ /// isSectionAtomizable - Check whether the given section can be split into
+ /// atoms.
+ ///
+ /// \see MCAssembler::isSymbolLinkerVisible().
+ virtual bool isSectionAtomizable(const MCSection &Section) const {
+ return true;
+ }
+
+ /// @name Target Fixup Interfaces
+ /// @{
+
+ /// getNumFixupKinds - Get the number of target specific fixup kinds.
+ virtual unsigned getNumFixupKinds() const = 0;
+
+ /// getFixupKindInfo - Get information on a fixup kind.
+ virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const;
+
+ /// processFixupValue - Target hook to adjust the literal value of a fixup
+ /// if necessary. IsResolved signals whether the caller believes a relocation
+ /// is needed; the target can modify the value. The default does nothing.
+ virtual void processFixupValue(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFixup &Fixup, const MCFragment *DF,
+ MCValue &Target, uint64_t &Value,
+ bool &IsResolved) {}
+
+ /// @}
+
+ /// applyFixup - Apply the \arg Value for given \arg 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,
+ uint64_t Value) const = 0;
+
+ /// @}
+
+ /// @name Target Relaxation Interfaces
+ /// @{
+
+ /// mayNeedRelaxation - Check whether the given instruction may need
+ /// relaxation.
+ ///
+ /// \param Inst - The instruction to test.
+ virtual bool mayNeedRelaxation(const MCInst &Inst) const = 0;
+
+ /// fixupNeedsRelaxation - Target specific predicate for whether a given
+ /// fixup requires the associated instruction to be relaxed.
+ virtual bool fixupNeedsRelaxation(const MCFixup &Fixup,
+ uint64_t Value,
+ const MCInstFragment *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
+ /// output.
+ /// \parm Res [output] - On return, the relaxed instruction.
+ virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
+
+ /// @}
+
+ /// writeNopData - Write an (optimal) nop sequence of Count bytes to the given
+ /// output. If the target cannot generate such a sequence, it should return an
+ /// error.
+ ///
+ /// \return - True on success.
+ virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
+
+ /// handleAssemblerFlag - Handle any target-specific assembler flags.
+ /// By default, do nothing.
+ virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfo.h b/contrib/llvm/include/llvm/MC/MCAsmInfo.h
new file mode 100644
index 000000000000..0f67c993714c
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfo.h
@@ -0,0 +1,594 @@
+//===-- llvm/MC/MCAsmInfo.h - Asm 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 contains a class to be used as the basis for target specific
+// asm writers. This class primarily takes care of global printing constants,
+// which are used in very similar ways across all targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_ASM_INFO_H
+#define LLVM_TARGET_ASM_INFO_H
+
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/MC/MCDirectives.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+ class MCExpr;
+ class MCSection;
+ class MCStreamer;
+ class MCSymbol;
+ class MCContext;
+
+ namespace ExceptionHandling {
+ enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
+ }
+
+ namespace LCOMM {
+ enum LCOMMType { None, NoAlignment, ByteAlignment };
+ }
+
+ /// MCAsmInfo - This class is intended to be used as a base class for asm
+ /// properties and features specific to the target.
+ class MCAsmInfo {
+ protected:
+ //===------------------------------------------------------------------===//
+ // Properties to be set by the target writer, used to configure asm printer.
+ //
+
+ /// PointerSize - Pointer size in bytes.
+ /// Default is 4.
+ unsigned PointerSize;
+
+ /// IsLittleEndian - True if target is little endian.
+ /// Default is true.
+ bool IsLittleEndian;
+
+ /// StackGrowsUp - True if target stack grow up.
+ /// Default is false.
+ bool StackGrowsUp;
+
+ /// HasSubsectionsViaSymbols - True if this target has the MachO
+ /// .subsections_via_symbols directive.
+ bool HasSubsectionsViaSymbols; // Default is false.
+
+ /// HasMachoZeroFillDirective - True if this is a MachO target that supports
+ /// the macho-specific .zerofill directive for emitting BSS Symbols.
+ bool HasMachoZeroFillDirective; // Default is false.
+
+ /// HasMachoTBSSDirective - True if this is a MachO target that supports
+ /// the macho-specific .tbss directive for emitting thread local BSS Symbols
+ bool HasMachoTBSSDirective; // Default is false.
+
+ /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should
+ /// emit a ".reference .constructors_used" or ".reference .destructors_used"
+ /// directive after the a static ctor/dtor list. This directive is only
+ /// emitted in Static relocation model.
+ bool HasStaticCtorDtorReferenceInStaticMode; // Default is false.
+
+ /// LinkerRequiresNonEmptyDwarfLines - True if the linker has a bug and
+ /// requires that the debug_line section be of a minimum size. In practice
+ /// such a linker requires a non empty line sequence if a file is present.
+ bool LinkerRequiresNonEmptyDwarfLines; // Default to false.
+
+ /// MaxInstLength - This is the maximum possible length of an instruction,
+ /// which is needed to compute the size of an inline asm.
+ unsigned MaxInstLength; // Defaults to 4.
+
+ /// PCSymbol - The symbol used to represent the current PC. Used in PC
+ /// relative expressions.
+ const char *PCSymbol; // Defaults to "$".
+
+ /// SeparatorString - This string, if specified, is used to separate
+ /// instructions from each other when on the same line.
+ const char *SeparatorString; // Defaults to ';'
+
+ /// CommentColumn - This indicates the comment num (zero-based) at
+ /// which asm comments should be printed.
+ unsigned CommentColumn; // Defaults to 40
+
+ /// CommentString - This indicates the comment character used by the
+ /// assembler.
+ const char *CommentString; // Defaults to "#"
+
+ /// LabelSuffix - This is appended to emitted labels.
+ const char *LabelSuffix; // 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 ""
+
+ /// PrivateGlobalPrefix - This prefix is used for globals like constant
+ /// pool entries that are completely private to the .s file and should not
+ /// have names in the .o file. This is often "." or "L".
+ const char *PrivateGlobalPrefix; // Defaults to "."
+
+ /// LinkerPrivateGlobalPrefix - This prefix is used for symbols that should
+ /// be passed through the assembler but be removed by the linker. This
+ /// is "l" on Darwin, currently used for some ObjC metadata.
+ const char *LinkerPrivateGlobalPrefix; // Defaults to ""
+
+ /// InlineAsmStart/End - If these are nonempty, they contain a directive to
+ /// emit before and after an inline assembly statement.
+ const char *InlineAsmStart; // Defaults to "#APP\n"
+ const char *InlineAsmEnd; // Defaults to "#NO_APP\n"
+
+ /// Code16Directive, Code32Directive, Code64Directive - These are assembly
+ /// directives that tells the assembler to interpret the following
+ /// instructions differently.
+ const char *Code16Directive; // Defaults to ".code16"
+ const char *Code32Directive; // Defaults to ".code32"
+ const char *Code64Directive; // Defaults to ".code64"
+
+ /// AssemblerDialect - Which dialect of an assembler variant to use.
+ unsigned AssemblerDialect; // Defaults to 0
+
+ /// AllowQuotesInName - This is true if the assembler allows for complex
+ /// symbol names to be surrounded in quotes. This defaults to false.
+ bool AllowQuotesInName;
+
+ /// AllowNameToStartWithDigit - This is true if the assembler allows symbol
+ /// names to start with a digit (e.g., "0x0021"). This defaults to false.
+ bool AllowNameToStartWithDigit;
+
+ /// AllowPeriodsInName - This is true if the assembler allows periods in
+ /// symbol names. This defaults to true.
+ bool AllowPeriodsInName;
+
+ /// AllowUTF8 - This is true if the assembler accepts UTF-8 input.
+ // FIXME: Make this a more general encoding setting?
+ bool AllowUTF8;
+
+ //===--- Data Emission Directives -------------------------------------===//
+
+ /// ZeroDirective - this should be set to the directive used to get some
+ /// number of zero bytes emitted to the current section. Common cases are
+ /// "\t.zero\t" and "\t.space\t". If this is set to null, the
+ /// Data*bitsDirective's will be used to emit zero bytes.
+ const char *ZeroDirective; // Defaults to "\t.zero\t"
+
+ /// AsciiDirective - This directive allows emission of an ascii string with
+ /// the standard C escape characters embedded into it.
+ const char *AsciiDirective; // Defaults to "\t.ascii\t"
+
+ /// AscizDirective - If not null, this allows for special handling of
+ /// zero terminated strings on this target. This is commonly supported as
+ /// ".asciz". If a target doesn't support this, it can be set to null.
+ const char *AscizDirective; // Defaults to "\t.asciz\t"
+
+ /// DataDirectives - These directives are used to output some unit of
+ /// integer data to the current section. If a data directive is set to
+ /// null, smaller data directives will be used to emit the large sizes.
+ const char *Data8bitsDirective; // Defaults to "\t.byte\t"
+ const char *Data16bitsDirective; // Defaults to "\t.short\t"
+ const char *Data32bitsDirective; // Defaults to "\t.long\t"
+ const char *Data64bitsDirective; // Defaults to "\t.quad\t"
+
+ /// [Data|Code]Begin - These magic labels are used to marked a region as
+ /// data or code, and are used to provide additional information for
+ /// correct disassembly on targets that like to mix data and code within
+ /// a segment. These labels will be implicitly suffixed by the streamer
+ /// to give them unique names.
+ const char *DataBegin; // Defaults to "$d."
+ const char *CodeBegin; // Defaults to "$a."
+ const char *JT8Begin; // Defaults to "$a."
+ const char *JT16Begin; // Defaults to "$a."
+ const char *JT32Begin; // Defaults to "$a."
+ bool SupportsDataRegions;
+
+ /// GPRel64Directive - if non-null, a directive that is used to emit a word
+ /// which should be relocated as a 64-bit GP-relative offset, e.g. .gpdword
+ /// on Mips.
+ const char *GPRel64Directive; // Defaults to NULL.
+
+ /// GPRel32Directive - if non-null, a directive that is used to emit a word
+ /// which should be relocated as a 32-bit GP-relative offset, e.g. .gpword
+ /// on Mips or .gprel32 on Alpha.
+ const char *GPRel32Directive; // Defaults to NULL.
+
+ /// getDataASDirective - Return the directive that should be used to emit
+ /// data of the specified size to the specified numeric address space.
+ virtual const char *getDataASDirective(unsigned Size, unsigned AS) const {
+ assert(AS != 0 && "Don't know the directives for default addr space");
+ return 0;
+ }
+
+ /// SunStyleELFSectionSwitchSyntax - This is true if this target uses "Sun
+ /// Style" syntax for section switching ("#alloc,#write" etc) instead of the
+ /// normal ELF syntax (,"a,w") in .section directives.
+ bool SunStyleELFSectionSwitchSyntax; // Defaults to false.
+
+ /// UsesELFSectionDirectiveForBSS - This is true if this target uses ELF
+ /// '.section' directive before the '.bss' one. It's used for PPC/Linux
+ /// which doesn't support the '.bss' directive only.
+ bool UsesELFSectionDirectiveForBSS; // Defaults to false.
+
+ /// HasMicrosoftFastStdCallMangling - True if this target uses microsoft
+ /// style mangling for functions with X86_StdCall/X86_FastCall calling
+ /// convention.
+ bool HasMicrosoftFastStdCallMangling; // Defaults to false.
+
+ //===--- Alignment Information ----------------------------------------===//
+
+ /// AlignDirective - The directive used to emit round up to an alignment
+ /// boundary.
+ ///
+ const char *AlignDirective; // Defaults to "\t.align\t"
+
+ /// AlignmentIsInBytes - If this is true (the default) then the asmprinter
+ /// emits ".align N" directives, where N is the number of bytes to align to.
+ /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte
+ /// boundary.
+ bool AlignmentIsInBytes; // Defaults to true
+
+ /// TextAlignFillValue - If non-zero, this is used to fill the executable
+ /// space created as the result of a alignment directive.
+ unsigned TextAlignFillValue; // Defaults to 0
+
+ //===--- Global Variable Emission Directives --------------------------===//
+
+ /// GlobalDirective - This is the directive used to declare a global entity.
+ ///
+ const char *GlobalDirective; // Defaults to NULL.
+
+ /// ExternDirective - This is the directive used to declare external
+ /// globals.
+ ///
+ const char *ExternDirective; // Defaults to NULL.
+
+ /// HasSetDirective - True if the assembler supports the .set directive.
+ bool HasSetDirective; // Defaults to true.
+
+ /// HasAggressiveSymbolFolding - False if the assembler requires that we use
+ /// Lc = a - b
+ /// .long Lc
+ /// instead of
+ /// .long a - b
+ bool HasAggressiveSymbolFolding; // Defaults to true.
+
+ /// LCOMMDirectiveType - Describes if the target supports the .lcomm
+ /// directive and whether it has an alignment parameter.
+ LCOMM::LCOMMType LCOMMDirectiveType; // Defaults to LCOMM::None.
+
+ /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional
+ /// alignment is to be specified in bytes instead of log2(n).
+ bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
+
+ /// HasDotTypeDotSizeDirective - True if the target has .type and .size
+ /// directives, this is true for most ELF targets.
+ bool HasDotTypeDotSizeDirective; // Defaults to true.
+
+ /// HasSingleParameterDotFile - True if the target has a single parameter
+ /// .file directive, this is true for ELF targets.
+ bool HasSingleParameterDotFile; // Defaults to true.
+
+ /// HasNoDeadStrip - True if this target supports the MachO .no_dead_strip
+ /// directive.
+ bool HasNoDeadStrip; // Defaults to false.
+
+ /// HasSymbolResolver - True if this target supports the MachO
+ /// .symbol_resolver directive.
+ bool HasSymbolResolver; // Defaults to false.
+
+ /// WeakRefDirective - This directive, if non-null, is used to declare a
+ /// global as being a weak undefined symbol.
+ const char *WeakRefDirective; // Defaults to NULL.
+
+ /// WeakDefDirective - This directive, if non-null, is used to declare a
+ /// global as being a weak defined symbol.
+ const char *WeakDefDirective; // Defaults to NULL.
+
+ /// LinkOnceDirective - This directive, if non-null is used to declare a
+ /// global as being a weak defined symbol. This is used on cygwin/mingw.
+ const char *LinkOnceDirective; // Defaults to NULL.
+
+ /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to
+ /// declare a symbol as having hidden visibility.
+ MCSymbolAttr HiddenVisibilityAttr; // Defaults to MCSA_Hidden.
+
+ /// HiddenDeclarationVisibilityAttr - This attribute, if not MCSA_Invalid,
+ /// is used to declare an undefined symbol as having hidden visibility.
+ MCSymbolAttr HiddenDeclarationVisibilityAttr; // Defaults to MCSA_Hidden.
+
+
+ /// ProtectedVisibilityAttr - This attribute, if not MCSA_Invalid, is used
+ /// to declare a symbol as having protected visibility.
+ MCSymbolAttr ProtectedVisibilityAttr; // Defaults to MCSA_Protected
+
+ //===--- Dwarf Emission Directives -----------------------------------===//
+
+ /// HasLEB128 - True if target asm supports leb128 directives.
+ bool HasLEB128; // Defaults to false.
+
+ /// SupportsDebugInformation - True if target supports emission of debugging
+ /// information.
+ bool SupportsDebugInformation; // Defaults to false.
+
+ /// SupportsExceptionHandling - True if target supports exception handling.
+ ExceptionHandling::ExceptionsType ExceptionsType; // Defaults to None
+
+ /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to
+ /// encode inline subroutine information.
+ bool DwarfUsesInlineInfoSection; // Defaults to false.
+
+ /// DwarfSectionOffsetDirective - Special section offset directive.
+ const char* DwarfSectionOffsetDirective; // Defaults to NULL
+
+ /// DwarfRequiresRelocationForSectionOffset - True if we need to produce a
+ /// relocation when we want a section offset in dwarf.
+ bool DwarfRequiresRelocationForSectionOffset; // Defaults to true;
+
+ /// DwarfUsesLabelOffsetDifference - True if Dwarf2 output can
+ /// use EmitLabelOffsetDifference.
+ bool DwarfUsesLabelOffsetForRanges;
+
+ /// DwarfUsesRelocationsForStringPool - True if this Dwarf output must use
+ /// relocations to refer to entries in the string pool.
+ bool DwarfUsesRelocationsForStringPool;
+
+ /// DwarfRegNumForCFI - True if dwarf register numbers are printed
+ /// instead of symbolic register names in .cfi_* directives.
+ bool DwarfRegNumForCFI; // Defaults to false;
+
+ //===--- CBE Asm Translation Table -----------------------------------===//
+
+ const char *const *AsmTransCBE; // Defaults to empty
+
+ //===--- Prologue State ----------------------------------------------===//
+
+ std::vector<MachineMove> InitialFrameState;
+
+ public:
+ explicit MCAsmInfo();
+ virtual ~MCAsmInfo();
+
+ // FIXME: move these methods to DwarfPrinter when the JIT stops using them.
+ static unsigned getSLEB128Size(int Value);
+ static unsigned getULEB128Size(unsigned Value);
+
+ /// getPointerSize - Get the pointer size in bytes.
+ unsigned getPointerSize() const {
+ return PointerSize;
+ }
+
+ /// islittleendian - True if the target is little endian.
+ bool isLittleEndian() const {
+ return IsLittleEndian;
+ }
+
+ /// isStackGrowthDirectionUp - True if target stack grow up.
+ bool isStackGrowthDirectionUp() const {
+ return StackGrowsUp;
+ }
+
+ bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+
+ // Data directive accessors.
+ //
+ const char *getData8bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data8bitsDirective : getDataASDirective(8, AS);
+ }
+ const char *getData16bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data16bitsDirective : getDataASDirective(16, AS);
+ }
+ const char *getData32bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data32bitsDirective : getDataASDirective(32, AS);
+ }
+ const char *getData64bitsDirective(unsigned AS = 0) const {
+ return AS == 0 ? Data64bitsDirective : getDataASDirective(64, AS);
+ }
+ const char *getGPRel64Directive() const { return GPRel64Directive; }
+ const char *getGPRel32Directive() const { return GPRel32Directive; }
+
+ /// [Code|Data]Begin label name accessors.
+ const char *getCodeBeginLabelName() const { return CodeBegin; }
+ const char *getDataBeginLabelName() const { return DataBegin; }
+ const char *getJumpTable8BeginLabelName() const { return JT8Begin; }
+ const char *getJumpTable16BeginLabelName() const { return JT16Begin; }
+ const char *getJumpTable32BeginLabelName() const { return JT32Begin; }
+ bool getSupportsDataRegions() const { return SupportsDataRegions; }
+
+ /// getNonexecutableStackSection - Targets can implement this method to
+ /// specify a section to switch to if the translation unit doesn't have any
+ /// trampolines that require an executable stack.
+ virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{
+ return 0;
+ }
+
+ virtual const MCExpr *
+ getExprForPersonalitySymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ const MCExpr *
+ getExprForFDESymbol(const MCSymbol *Sym,
+ unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ bool usesSunStyleELFSectionSwitchSyntax() const {
+ return SunStyleELFSectionSwitchSyntax;
+ }
+
+ bool usesELFSectionDirectiveForBSS() const {
+ return UsesELFSectionDirectiveForBSS;
+ }
+
+ bool hasMicrosoftFastStdCallMangling() const {
+ return HasMicrosoftFastStdCallMangling;
+ }
+
+ // Accessors.
+ //
+ bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
+ bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
+ bool hasStaticCtorDtorReferenceInStaticMode() const {
+ return HasStaticCtorDtorReferenceInStaticMode;
+ }
+ bool getLinkerRequiresNonEmptyDwarfLines() const {
+ return LinkerRequiresNonEmptyDwarfLines;
+ }
+ unsigned getMaxInstLength() const {
+ return MaxInstLength;
+ }
+ const char *getPCSymbol() const {
+ return PCSymbol;
+ }
+ const char *getSeparatorString() const {
+ return SeparatorString;
+ }
+ unsigned getCommentColumn() const {
+ return CommentColumn;
+ }
+ const char *getCommentString() const {
+ return CommentString;
+ }
+ const char *getLabelSuffix() const {
+ return LabelSuffix;
+ }
+ const char *getGlobalPrefix() const {
+ return GlobalPrefix;
+ }
+ const char *getPrivateGlobalPrefix() const {
+ return PrivateGlobalPrefix;
+ }
+ const char *getLinkerPrivateGlobalPrefix() const {
+ return LinkerPrivateGlobalPrefix;
+ }
+ const char *getInlineAsmStart() const {
+ return InlineAsmStart;
+ }
+ const char *getInlineAsmEnd() const {
+ return InlineAsmEnd;
+ }
+ const char *getCode16Directive() const {
+ return Code16Directive;
+ }
+ const char *getCode32Directive() const {
+ return Code32Directive;
+ }
+ const char *getCode64Directive() const {
+ return Code64Directive;
+ }
+ unsigned getAssemblerDialect() const {
+ return AssemblerDialect;
+ }
+ bool doesAllowQuotesInName() const {
+ return AllowQuotesInName;
+ }
+ bool doesAllowNameToStartWithDigit() const {
+ return AllowNameToStartWithDigit;
+ }
+ bool doesAllowPeriodsInName() const {
+ return AllowPeriodsInName;
+ }
+ bool doesAllowUTF8() const {
+ return AllowUTF8;
+ }
+ const char *getZeroDirective() const {
+ return ZeroDirective;
+ }
+ const char *getAsciiDirective() const {
+ return AsciiDirective;
+ }
+ const char *getAscizDirective() const {
+ return AscizDirective;
+ }
+ const char *getAlignDirective() const {
+ return AlignDirective;
+ }
+ bool getAlignmentIsInBytes() const {
+ return AlignmentIsInBytes;
+ }
+ unsigned getTextAlignFillValue() const {
+ return TextAlignFillValue;
+ }
+ const char *getGlobalDirective() const {
+ return GlobalDirective;
+ }
+ const char *getExternDirective() const {
+ return ExternDirective;
+ }
+ bool hasSetDirective() const { return HasSetDirective; }
+ bool hasAggressiveSymbolFolding() const {
+ return HasAggressiveSymbolFolding;
+ }
+ LCOMM::LCOMMType getLCOMMDirectiveType() const {
+ return LCOMMDirectiveType;
+ }
+ bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
+ bool getCOMMDirectiveAlignmentIsInBytes() const {
+ return COMMDirectiveAlignmentIsInBytes;
+ }
+ bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
+ bool hasNoDeadStrip() const { return HasNoDeadStrip; }
+ bool hasSymbolResolver() const { return HasSymbolResolver; }
+ const char *getWeakRefDirective() const { return WeakRefDirective; }
+ const char *getWeakDefDirective() const { return WeakDefDirective; }
+ const char *getLinkOnceDirective() const { return LinkOnceDirective; }
+
+ MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
+ MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
+ return HiddenDeclarationVisibilityAttr;
+ }
+ MCSymbolAttr getProtectedVisibilityAttr() const {
+ return ProtectedVisibilityAttr;
+ }
+ bool hasLEB128() const {
+ return HasLEB128;
+ }
+ bool doesSupportDebugInformation() const {
+ return SupportsDebugInformation;
+ }
+ bool doesSupportExceptionHandling() const {
+ return ExceptionsType != ExceptionHandling::None;
+ }
+ ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
+ return ExceptionsType;
+ }
+ bool isExceptionHandlingDwarf() const {
+ return
+ (ExceptionsType == ExceptionHandling::DwarfCFI ||
+ ExceptionsType == ExceptionHandling::ARM ||
+ ExceptionsType == ExceptionHandling::Win64);
+ }
+ bool doesDwarfUseInlineInfoSection() const {
+ return DwarfUsesInlineInfoSection;
+ }
+ const char *getDwarfSectionOffsetDirective() const {
+ return DwarfSectionOffsetDirective;
+ }
+ bool doesDwarfRequireRelocationForSectionOffset() const {
+ return DwarfRequiresRelocationForSectionOffset;
+ }
+ bool doesDwarfUseLabelOffsetForRanges() const {
+ return DwarfUsesLabelOffsetForRanges;
+ }
+ bool doesDwarfUseRelocationsForStringPool() const {
+ return DwarfUsesRelocationsForStringPool;
+ }
+ bool useDwarfRegNumForCFI() const {
+ return DwarfRegNumForCFI;
+ }
+ const char *const *getAsmCBE() const {
+ return AsmTransCBE;
+ }
+
+ void addInitialFrameState(MCSymbol *label, const MachineLocation &D,
+ const MachineLocation &S) {
+ InitialFrameState.push_back(MachineMove(label, D, S));
+ }
+ const std::vector<MachineMove> &getInitialFrameState() const {
+ return InitialFrameState;
+ }
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h b/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h
new file mode 100644
index 000000000000..0ff3e127ed0e
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfoCOFF.h
@@ -0,0 +1,36 @@
+//===-- MCAsmInfoCOFF.h - COFF asm properties -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_COFF_TARGET_ASM_INFO_H
+#define LLVM_COFF_TARGET_ASM_INFO_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+ class MCAsmInfoCOFF : public MCAsmInfo {
+ virtual void anchor();
+ protected:
+ explicit MCAsmInfoCOFF();
+ };
+
+ class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
+ virtual void anchor();
+ protected:
+ explicit MCAsmInfoMicrosoft();
+ };
+
+ class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
+ virtual void anchor();
+ protected:
+ explicit MCAsmInfoGNUCOFF();
+ };
+}
+
+
+#endif // LLVM_COFF_TARGET_ASM_INFO_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h b/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h
new file mode 100644
index 000000000000..af552de6e690
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAsmInfoDarwin.h
@@ -0,0 +1,29 @@
+//===---- MCAsmInfoDarwin.h - Darwin asm properties -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target asm properties related what form asm statements
+// should take in general on Darwin-based targets
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H
+#define LLVM_DARWIN_TARGET_ASM_INFO_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+ class MCAsmInfoDarwin : public MCAsmInfo {
+ virtual void anchor();
+ public:
+ explicit MCAsmInfoDarwin();
+ };
+}
+
+
+#endif // LLVM_DARWIN_TARGET_ASM_INFO_H
diff --git a/contrib/llvm/include/llvm/MC/MCAsmLayout.h b/contrib/llvm/include/llvm/MC/MCAsmLayout.h
new file mode 100644
index 000000000000..cf79216d076a
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAsmLayout.h
@@ -0,0 +1,105 @@
+//===- MCAsmLayout.h - Assembly Layout Object -------------------*- 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_MCASMLAYOUT_H
+#define LLVM_MC_MCASMLAYOUT_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+class MCAssembler;
+class MCFragment;
+class MCSectionData;
+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
+/// 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,
+/// even during the relaxation process.
+class MCAsmLayout {
+public:
+ typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
+ typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
+
+private:
+ MCAssembler &Assembler;
+
+ /// List of sections in layout order.
+ llvm::SmallVector<MCSectionData*, 16> SectionOrder;
+
+ /// 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;
+
+ /// \brief Make sure that the layout for the given fragment is valid, lazily
+ /// computing it if necessary.
+ void EnsureValid(const MCFragment *F) const;
+
+ bool isFragmentUpToDate(const MCFragment *F) const;
+
+public:
+ MCAsmLayout(MCAssembler &_Assembler);
+
+ /// 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 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);
+
+ /// @name Section Access (in layout order)
+ /// @{
+
+ llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() {
+ return SectionOrder;
+ }
+ const llvm::SmallVectorImpl<MCSectionData*> &getSectionOrder() const {
+ return SectionOrder;
+ }
+
+ /// @}
+ /// @name Fragment Layout Data
+ /// @{
+
+ /// \brief Get the offset of the given fragment inside its containing section.
+ uint64_t getFragmentOffset(const MCFragment *F) const;
+
+ /// @}
+ /// @name Utility Functions
+ /// @{
+
+ /// \brief Get the address space size of the given section, as it effects
+ /// layout. This may differ from the size reported by \see getSectionSize() by
+ /// not including section tail padding.
+ uint64_t getSectionAddressSize(const MCSectionData *SD) const;
+
+ /// \brief Get the data size of the given section, as emitted to the object
+ /// file. This may include additional padding, or be 0 for virtual sections.
+ uint64_t getSectionFileSize(const MCSectionData *SD) const;
+
+ /// \brief Get the offset of the given symbol, as computed in the current
+ /// layout.
+ uint64_t getSymbolOffset(const MCSymbolData *SD) const;
+
+ /// @}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCAssembler.h b/contrib/llvm/include/llvm/MC/MCAssembler.h
new file mode 100644
index 000000000000..d139173c3e13
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAssembler.h
@@ -0,0 +1,931 @@
+//===- MCAssembler.h - Object File Generation -------------------*- 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_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/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector> // FIXME: Shouldn't be needed.
+
+namespace llvm {
+class raw_ostream;
+class MCAsmLayout;
+class MCAssembler;
+class MCContext;
+class MCCodeEmitter;
+class MCExpr;
+class MCFragment;
+class MCObjectWriter;
+class MCSection;
+class MCSectionData;
+class MCSymbol;
+class MCSymbolData;
+class MCValue;
+class MCAsmBackend;
+
+class MCFragment : public ilist_node<MCFragment> {
+ friend class MCAsmLayout;
+
+ MCFragment(const MCFragment&); // DO NOT IMPLEMENT
+ void operator=(const MCFragment&); // DO NOT IMPLEMENT
+
+public:
+ enum FragmentType {
+ FT_Align,
+ FT_Data,
+ FT_Fill,
+ FT_Inst,
+ FT_Org,
+ FT_Dwarf,
+ FT_DwarfFrame,
+ FT_LEB
+ };
+
+private:
+ FragmentType Kind;
+
+ /// Parent - The data for the section this fragment is in.
+ MCSectionData *Parent;
+
+ /// Atom - The atom this fragment is in, as represented by it's defining
+ /// symbol. Atom's are only used by backends which set
+ /// \see MCAsmBackend::hasReliableSymbolDifference().
+ MCSymbolData *Atom;
+
+ /// @name Assembler Backend Data
+ /// @{
+ //
+ // FIXME: This could all be kept private to the assembler implementation.
+
+ /// Offset - The offset of this fragment in its section. This is ~0 until
+ /// initialized.
+ uint64_t Offset;
+
+ /// LayoutOrder - The layout order of this fragment.
+ unsigned LayoutOrder;
+
+ /// @}
+
+protected:
+ MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
+
+public:
+ // Only for sentinel.
+ MCFragment();
+ virtual ~MCFragment();
+
+ FragmentType getKind() const { return Kind; }
+
+ MCSectionData *getParent() const { return Parent; }
+ void setParent(MCSectionData *Value) { Parent = Value; }
+
+ MCSymbolData *getAtom() const { return Atom; }
+ void setAtom(MCSymbolData *Value) { Atom = Value; }
+
+ unsigned getLayoutOrder() const { return LayoutOrder; }
+ void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+ static bool classof(const MCFragment *O) { return true; }
+
+ void dump();
+};
+
+class MCDataFragment : public MCFragment {
+ virtual void anchor();
+ SmallString<32> Contents;
+
+ /// Fixups - The list of fixups in this fragment.
+ std::vector<MCFixup> Fixups;
+
+public:
+ typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
+ typedef std::vector<MCFixup>::iterator fixup_iterator;
+
+public:
+ MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
+
+ /// @name Accessors
+ /// @{
+
+ SmallString<32> &getContents() { return Contents; }
+ const SmallString<32> &getContents() const { return Contents; }
+
+ /// @}
+ /// @name Fixup Access
+ /// @{
+
+ 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);
+ }
+
+ std::vector<MCFixup> &getFixups() { return Fixups; }
+ const std::vector<MCFixup> &getFixups() const { return Fixups; }
+
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+
+ fixup_iterator fixup_end() {return Fixups.end();}
+ const_fixup_iterator fixup_end() const {return Fixups.end();}
+
+ size_t fixup_size() const { return Fixups.size(); }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Data;
+ }
+ static bool classof(const MCDataFragment *) { return true; }
+};
+
+// 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 {
+ virtual void anchor();
+
+ /// Inst - The instruction this is a fragment for.
+ MCInst Inst;
+
+ /// Code - Binary data for the currently encoded instruction.
+ SmallString<8> Code;
+
+ /// 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(MCInst _Inst, MCSectionData *SD = 0)
+ : MCFragment(FT_Inst, SD), Inst(_Inst) {
+ }
+
+ /// @name Accessors
+ /// @{
+
+ SmallVectorImpl<char> &getCode() { return Code; }
+ const SmallVectorImpl<char> &getCode() const { return Code; }
+
+ unsigned getInstSize() const { return Code.size(); }
+
+ MCInst &getInst() { return Inst; }
+ const MCInst &getInst() const { return Inst; }
+
+ void setInst(MCInst Value) { Inst = Value; }
+
+ /// @}
+ /// @name Fixup Access
+ /// @{
+
+ SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
+ const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
+
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+
+ fixup_iterator fixup_end() {return Fixups.end();}
+ const_fixup_iterator fixup_end() const {return Fixups.end();}
+
+ size_t fixup_size() const { return Fixups.size(); }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Inst;
+ }
+ static bool classof(const MCInstFragment *) { return true; }
+};
+
+class MCAlignFragment : public MCFragment {
+ virtual void anchor();
+
+ /// Alignment - The alignment to ensure, in bytes.
+ unsigned Alignment;
+
+ /// Value - Value to use for filling padding bytes.
+ int64_t Value;
+
+ /// ValueSize - The size of the integer (in bytes) of \arg Value.
+ unsigned ValueSize;
+
+ /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
+ /// cannot be satisfied in this width then this fragment is ignored.
+ unsigned MaxBytesToEmit;
+
+ /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+ /// of using the provided value. The exact interpretation of this flag is
+ /// target dependent.
+ bool EmitNops : 1;
+
+public:
+ MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
+ unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
+ : MCFragment(FT_Align, SD), Alignment(_Alignment),
+ Value(_Value),ValueSize(_ValueSize),
+ MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
+
+ /// @name Accessors
+ /// @{
+
+ unsigned getAlignment() const { return Alignment; }
+
+ int64_t getValue() const { return Value; }
+
+ unsigned getValueSize() const { return ValueSize; }
+
+ unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
+
+ bool hasEmitNops() const { return EmitNops; }
+ void setEmitNops(bool Value) { EmitNops = Value; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Align;
+ }
+ static bool classof(const MCAlignFragment *) { return true; }
+};
+
+class MCFillFragment : public MCFragment {
+ virtual void anchor();
+
+ /// 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
+ /// this is a virtual fill fragment.
+ unsigned ValueSize;
+
+ /// Size - The number of bytes to insert.
+ uint64_t Size;
+
+public:
+ MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
+ MCSectionData *SD = 0)
+ : MCFragment(FT_Fill, SD),
+ Value(_Value), ValueSize(_ValueSize), Size(_Size) {
+ assert((!ValueSize || (Size % ValueSize) == 0) &&
+ "Fill size must be a multiple of the value size!");
+ }
+
+ /// @name Accessors
+ /// @{
+
+ int64_t getValue() const { return Value; }
+
+ unsigned getValueSize() const { return ValueSize; }
+
+ uint64_t getSize() const { return Size; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Fill;
+ }
+ static bool classof(const MCFillFragment *) { return true; }
+};
+
+class MCOrgFragment : public MCFragment {
+ virtual void anchor();
+
+ /// Offset - The offset this fragment should start at.
+ const MCExpr *Offset;
+
+ /// Value - Value to use for filling bytes.
+ int8_t Value;
+
+public:
+ MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
+ : MCFragment(FT_Org, SD),
+ Offset(&_Offset), Value(_Value) {}
+
+ /// @name Accessors
+ /// @{
+
+ const MCExpr &getOffset() const { return *Offset; }
+
+ uint8_t getValue() const { return Value; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Org;
+ }
+ static bool classof(const MCOrgFragment *) { return true; }
+};
+
+class MCLEBFragment : public MCFragment {
+ virtual void anchor();
+
+ /// Value - The value this fragment should contain.
+ const MCExpr *Value;
+
+ /// IsSigned - True if this is a sleb128, false if uleb128.
+ bool IsSigned;
+
+ SmallString<8> Contents;
+public:
+ MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
+ : MCFragment(FT_LEB, SD),
+ Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ const MCExpr &getValue() const { return *Value; }
+
+ bool isSigned() const { return IsSigned; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_LEB;
+ }
+ static bool classof(const MCLEBFragment *) { return true; }
+};
+
+class MCDwarfLineAddrFragment : public MCFragment {
+ virtual void anchor();
+
+ /// LineDelta - the value of the difference between the two line numbers
+ /// between two .loc dwarf directives.
+ int64_t LineDelta;
+
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .loc dwarf directives.
+ const MCExpr *AddrDelta;
+
+ SmallString<8> Contents;
+
+public:
+ MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
+ MCSectionData *SD)
+ : MCFragment(FT_Dwarf, SD),
+ LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ int64_t getLineDelta() const { return LineDelta; }
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Dwarf;
+ }
+ static bool classof(const MCDwarfLineAddrFragment *) { return true; }
+};
+
+class MCDwarfCallFrameFragment : public MCFragment {
+ virtual void anchor();
+
+ /// AddrDelta - The expression for the difference of the two symbols that
+ /// make up the address delta between two .cfi_* dwarf directives.
+ const MCExpr *AddrDelta;
+
+ SmallString<8> Contents;
+
+public:
+ MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD)
+ : MCFragment(FT_DwarfFrame, SD),
+ AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+
+ /// @name Accessors
+ /// @{
+
+ const MCExpr &getAddrDelta() const { return *AddrDelta; }
+
+ SmallString<8> &getContents() { return Contents; }
+ const SmallString<8> &getContents() const { return Contents; }
+
+ /// @}
+
+ 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
+// we anticipate the fast path being through an MCAssembler, the only reason to
+// keep it out is for API abstraction.
+class MCSectionData : public ilist_node<MCSectionData> {
+ friend class MCAsmLayout;
+
+ MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT
+ void operator=(const MCSectionData&); // DO NOT IMPLEMENT
+
+public:
+ typedef iplist<MCFragment> FragmentListType;
+
+ typedef FragmentListType::const_iterator const_iterator;
+ typedef FragmentListType::iterator iterator;
+
+ typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+ typedef FragmentListType::reverse_iterator reverse_iterator;
+
+private:
+ FragmentListType Fragments;
+ const MCSection *Section;
+
+ /// Ordinal - The section index in the assemblers section list.
+ unsigned Ordinal;
+
+ /// LayoutOrder - The index of this section in the layout order.
+ unsigned LayoutOrder;
+
+ /// Alignment - The maximum alignment seen in this section.
+ unsigned Alignment;
+
+ /// @name Assembler Backend Data
+ /// @{
+ //
+ // FIXME: This could all be kept private to the assembler implementation.
+
+ /// HasInstructions - Whether this section has had instructions emitted into
+ /// it.
+ unsigned HasInstructions : 1;
+
+ /// @}
+
+public:
+ // Only for use as sentinel.
+ MCSectionData();
+ MCSectionData(const MCSection &Section, MCAssembler *A = 0);
+
+ const MCSection &getSection() const { return *Section; }
+
+ unsigned getAlignment() const { return Alignment; }
+ void setAlignment(unsigned Value) { Alignment = Value; }
+
+ bool hasInstructions() const { return HasInstructions; }
+ void setHasInstructions(bool Value) { HasInstructions = Value; }
+
+ unsigned getOrdinal() const { return Ordinal; }
+ void setOrdinal(unsigned Value) { Ordinal = Value; }
+
+ unsigned getLayoutOrder() const { return LayoutOrder; }
+ void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+ /// @name Fragment Access
+ /// @{
+
+ const FragmentListType &getFragmentList() const { return Fragments; }
+ FragmentListType &getFragmentList() { return Fragments; }
+
+ iterator begin() { return Fragments.begin(); }
+ const_iterator begin() const { return Fragments.begin(); }
+
+ iterator end() { return Fragments.end(); }
+ const_iterator end() const { return Fragments.end(); }
+
+ reverse_iterator rbegin() { return Fragments.rbegin(); }
+ const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
+
+ reverse_iterator rend() { return Fragments.rend(); }
+ const_reverse_iterator rend() const { return Fragments.rend(); }
+
+ size_t size() const { return Fragments.size(); }
+
+ bool empty() const { return Fragments.empty(); }
+
+ void dump();
+
+ /// @}
+};
+
+// FIXME: Same concerns as with SectionData.
+class MCSymbolData : public ilist_node<MCSymbolData> {
+public:
+ const MCSymbol *Symbol;
+
+ /// Fragment - The fragment this symbol's value is relative to, if any.
+ MCFragment *Fragment;
+
+ /// Offset - The offset to apply to the fragment address to form this symbol's
+ /// value.
+ uint64_t Offset;
+
+ /// IsExternal - True if this symbol is visible outside this translation
+ /// unit.
+ unsigned IsExternal : 1;
+
+ /// IsPrivateExtern - True if this symbol is private extern.
+ unsigned IsPrivateExtern : 1;
+
+ /// CommonSize - The size of the symbol, if it is 'common', or 0.
+ //
+ // FIXME: Pack this in with other fields? We could put it in offset, since a
+ // common symbol can never get a definition.
+ uint64_t CommonSize;
+
+ /// SymbolSize - An expression describing how to calculate the size of
+ /// a symbol. If a symbol has no size this field will be NULL.
+ const MCExpr *SymbolSize;
+
+ /// CommonAlign - The alignment of the symbol, if it is 'common'.
+ //
+ // FIXME: Pack this in with other fields?
+ unsigned CommonAlign;
+
+ /// Flags - The Flags field is used by object file implementations to store
+ /// additional per symbol information which is not easily classified.
+ uint32_t Flags;
+
+ /// Index - Index field, for use by the object file implementation.
+ uint64_t Index;
+
+public:
+ // Only for use as sentinel.
+ MCSymbolData();
+ MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
+ MCAssembler *A = 0);
+
+ /// @name Accessors
+ /// @{
+
+ const MCSymbol &getSymbol() const { return *Symbol; }
+
+ MCFragment *getFragment() const { return Fragment; }
+ void setFragment(MCFragment *Value) { Fragment = Value; }
+
+ uint64_t getOffset() const { return Offset; }
+ void setOffset(uint64_t Value) { Offset = Value; }
+
+ /// @}
+ /// @name Symbol Attributes
+ /// @{
+
+ bool isExternal() const { return IsExternal; }
+ void setExternal(bool Value) { IsExternal = Value; }
+
+ bool isPrivateExtern() const { return IsPrivateExtern; }
+ void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
+
+ /// isCommon - Is this a 'common' symbol.
+ bool isCommon() const { return CommonSize != 0; }
+
+ /// setCommon - Mark this symbol as being 'common'.
+ ///
+ /// \param Size - The size of the symbol.
+ /// \param Align - The alignment of the symbol.
+ void setCommon(uint64_t Size, unsigned Align) {
+ CommonSize = Size;
+ CommonAlign = Align;
+ }
+
+ /// getCommonSize - Return the size of a 'common' symbol.
+ uint64_t getCommonSize() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonSize;
+ }
+
+ void setSize(const MCExpr *SS) {
+ SymbolSize = SS;
+ }
+
+ const MCExpr *getSize() const {
+ return SymbolSize;
+ }
+
+
+ /// getCommonAlignment - Return the alignment of a 'common' symbol.
+ unsigned getCommonAlignment() const {
+ assert(isCommon() && "Not a 'common' symbol!");
+ return CommonAlign;
+ }
+
+ /// getFlags - Get the (implementation defined) symbol flags.
+ uint32_t getFlags() const { return Flags; }
+
+ /// setFlags - Set the (implementation defined) symbol flags.
+ void setFlags(uint32_t Value) { Flags = Value; }
+
+ /// modifyFlags - Modify the flags via a mask
+ void modifyFlags(uint32_t Value, uint32_t Mask) {
+ Flags = (Flags & ~Mask) | Value;
+ }
+
+ /// getIndex - Get the (implementation defined) index.
+ uint64_t getIndex() const { return Index; }
+
+ /// setIndex - Set the (implementation defined) index.
+ void setIndex(uint64_t Value) { Index = Value; }
+
+ /// @}
+
+ void dump();
+};
+
+// FIXME: This really doesn't belong here. See comments below.
+struct IndirectSymbolData {
+ MCSymbol *Symbol;
+ MCSectionData *SectionData;
+};
+
+class MCAssembler {
+ friend class MCAsmLayout;
+
+public:
+ typedef iplist<MCSectionData> SectionDataListType;
+ typedef iplist<MCSymbolData> SymbolDataListType;
+
+ typedef SectionDataListType::const_iterator const_iterator;
+ typedef SectionDataListType::iterator iterator;
+
+ typedef SymbolDataListType::const_iterator const_symbol_iterator;
+ typedef SymbolDataListType::iterator symbol_iterator;
+
+ typedef std::vector<IndirectSymbolData>::const_iterator
+ const_indirect_symbol_iterator;
+ typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
+
+private:
+ MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT
+ void operator=(const MCAssembler&); // DO NOT IMPLEMENT
+
+ MCContext &Context;
+
+ MCAsmBackend &Backend;
+
+ MCCodeEmitter &Emitter;
+
+ MCObjectWriter &Writer;
+
+ raw_ostream &OS;
+
+ iplist<MCSectionData> Sections;
+
+ iplist<MCSymbolData> Symbols;
+
+ /// The map of sections to their associated assembler backend data.
+ //
+ // FIXME: Avoid this indirection?
+ DenseMap<const MCSection*, MCSectionData*> SectionMap;
+
+ /// The map of symbols to their associated assembler backend data.
+ //
+ // FIXME: Avoid this indirection?
+ DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
+
+ std::vector<IndirectSymbolData> IndirectSymbols;
+
+ /// The set of function symbols for which a .thumb_func directive has
+ /// been seen.
+ //
+ // FIXME: We really would like this in target specific code rather than
+ // here. Maybe when the relocation stuff moves to target specific,
+ // this can go with it? The streamer would need some target specific
+ // refactoring too.
+ SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+
+ unsigned RelaxAll : 1;
+ unsigned NoExecStack : 1;
+ unsigned SubsectionsViaSymbols : 1;
+
+private:
+ /// Evaluate a fixup to a relocatable expression and the value which should be
+ /// placed into the fixup.
+ ///
+ /// \param Layout The layout to use for evaluation.
+ /// \param Fixup The fixup to evaluate.
+ /// \param DF The fragment the fixup is inside.
+ /// \param Target [out] On return, the relocatable expression the fixup
+ /// evaluates to.
+ /// \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
+ /// relocation.
+ bool evaluateFixup(const MCAsmLayout &Layout,
+ const MCFixup &Fixup, const MCFragment *DF,
+ MCValue &Target, uint64_t &Value) const;
+
+ /// 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,
+ const MCAsmLayout &Layout) const;
+
+ /// Check whether the given fragment needs relaxation.
+ bool fragmentNeedsRelaxation(const MCInstFragment *IF,
+ const MCAsmLayout &Layout) const;
+
+ /// layoutOnce - Perform one layout iteration and return true if any offsets
+ /// were adjusted.
+ bool layoutOnce(MCAsmLayout &Layout);
+
+ bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
+
+ bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
+
+ bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
+
+ bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
+ bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
+ MCDwarfCallFrameFragment &DF);
+
+ /// finishLayout - Finalize a layout, including fragment lowering.
+ void finishLayout(MCAsmLayout &Layout);
+
+ uint64_t handleFixup(const MCAsmLayout &Layout,
+ MCFragment &F, const MCFixup &Fixup);
+
+public:
+ /// Compute the effective fragment size assuming it is laid out at the given
+ /// \arg SectionAddress and \arg FragmentOffset.
+ uint64_t computeFragmentSize(const MCAsmLayout &Layout,
+ const MCFragment &F) const;
+
+ /// Find the symbol which defines the atom containing the given symbol, or
+ /// null if there is no such symbol.
+ const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
+
+ /// Check whether a particular symbol is visible to the linker and is required
+ /// in the symbol table, or whether it can be discarded by the assembler. This
+ /// also effects whether the assembler treats the label as potentially
+ /// defining a separate atom.
+ bool isSymbolLinkerVisible(const MCSymbol &SD) const;
+
+ /// Emit the section contents using the given object writer.
+ void writeSectionData(const MCSectionData *Section,
+ const MCAsmLayout &Layout) const;
+
+ /// Check whether a given symbol has been flagged with .thumb_func.
+ bool isThumbFunc(const MCSymbol *Func) const {
+ return ThumbFuncs.count(Func);
+ }
+
+ /// Flag a function symbol as the target of a .thumb_func directive.
+ void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
+
+public:
+ /// Construct a new assembler instance.
+ ///
+ /// \arg 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
+ // option is to make this abstract, and have targets provide concrete
+ // implementations as we do with AsmParser.
+ MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
+ MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
+ raw_ostream &OS);
+ ~MCAssembler();
+
+ MCContext &getContext() const { return Context; }
+
+ MCAsmBackend &getBackend() const { return Backend; }
+
+ MCCodeEmitter &getEmitter() const { return Emitter; }
+
+ MCObjectWriter &getWriter() const { return Writer; }
+
+ /// Finish - Do final processing and write the object to the output stream.
+ /// \arg Writer is used for custom object writer (as the MCJIT does),
+ /// if not specified it is automatically created from backend.
+ void Finish();
+
+ // FIXME: This does not belong here.
+ bool getSubsectionsViaSymbols() const {
+ return SubsectionsViaSymbols;
+ }
+ void setSubsectionsViaSymbols(bool Value) {
+ SubsectionsViaSymbols = Value;
+ }
+
+ bool getRelaxAll() const { return RelaxAll; }
+ void setRelaxAll(bool Value) { RelaxAll = Value; }
+
+ bool getNoExecStack() const { return NoExecStack; }
+ void setNoExecStack(bool Value) { NoExecStack = Value; }
+
+ /// @name Section List Access
+ /// @{
+
+ const SectionDataListType &getSectionList() const { return Sections; }
+ SectionDataListType &getSectionList() { return Sections; }
+
+ iterator begin() { return Sections.begin(); }
+ const_iterator begin() const { return Sections.begin(); }
+
+ iterator end() { return Sections.end(); }
+ const_iterator end() const { return Sections.end(); }
+
+ size_t size() const { return Sections.size(); }
+
+ /// @}
+ /// @name Symbol List Access
+ /// @{
+
+ const SymbolDataListType &getSymbolList() const { return Symbols; }
+ SymbolDataListType &getSymbolList() { return Symbols; }
+
+ symbol_iterator symbol_begin() { return Symbols.begin(); }
+ const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
+
+ symbol_iterator symbol_end() { return Symbols.end(); }
+ const_symbol_iterator symbol_end() const { return Symbols.end(); }
+
+ size_t symbol_size() const { return Symbols.size(); }
+
+ /// @}
+ /// @name Indirect Symbol List Access
+ /// @{
+
+ // FIXME: This is a total hack, this should not be here. Once things are
+ // factored so that the streamer has direct access to the .o writer, it can
+ // disappear.
+ std::vector<IndirectSymbolData> &getIndirectSymbols() {
+ return IndirectSymbols;
+ }
+
+ indirect_symbol_iterator indirect_symbol_begin() {
+ return IndirectSymbols.begin();
+ }
+ const_indirect_symbol_iterator indirect_symbol_begin() const {
+ return IndirectSymbols.begin();
+ }
+
+ indirect_symbol_iterator indirect_symbol_end() {
+ return IndirectSymbols.end();
+ }
+ const_indirect_symbol_iterator indirect_symbol_end() const {
+ return IndirectSymbols.end();
+ }
+
+ size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
+
+ /// @}
+ /// @name Backend Data Access
+ /// @{
+
+ MCSectionData &getSectionData(const MCSection &Section) const {
+ MCSectionData *Entry = SectionMap.lookup(&Section);
+ assert(Entry && "Missing section data!");
+ return *Entry;
+ }
+
+ MCSectionData &getOrCreateSectionData(const MCSection &Section,
+ bool *Created = 0) {
+ MCSectionData *&Entry = SectionMap[&Section];
+
+ if (Created) *Created = !Entry;
+ if (!Entry)
+ Entry = new MCSectionData(Section, this);
+
+ return *Entry;
+ }
+
+ MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
+ MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
+ assert(Entry && "Missing symbol data!");
+ return *Entry;
+ }
+
+ MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
+ bool *Created = 0) {
+ MCSymbolData *&Entry = SymbolMap[&Symbol];
+
+ if (Created) *Created = !Entry;
+ if (!Entry)
+ Entry = new MCSymbolData(Symbol, 0, 0, this);
+
+ return *Entry;
+ }
+
+ /// @}
+
+ void dump();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCAtom.h b/contrib/llvm/include/llvm/MC/MCAtom.h
new file mode 100644
index 000000000000..682cf7cd76c6
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCAtom.h
@@ -0,0 +1,68 @@
+//===-- llvm/MC/MCAtom.h - MCAtom class ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCAtom class, which is used to
+// represent a contiguous region in a decoded object that is uniformly data or
+// instructions;
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCATOM_H
+#define LLVM_MC_MCATOM_H
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MCModule;
+
+/// MCData - An entry in a data MCAtom.
+// NOTE: This may change to a more complex type in the future.
+typedef uint8_t MCData;
+
+/// MCAtom - Represents a contiguous range of either instructions (a TextAtom)
+/// or data (a DataAtom). Address ranges are expressed as _closed_ intervals.
+class MCAtom {
+ friend class MCModule;
+ typedef enum { TextAtom, DataAtom } AtomType;
+
+ AtomType Type;
+ MCModule *Parent;
+ uint64_t Begin, End;
+
+ std::vector<std::pair<uint64_t, MCInst> > Text;
+ std::vector<MCData> Data;
+
+ // Private constructor - only callable by MCModule
+ MCAtom(AtomType T, MCModule *P, uint64_t B, uint64_t E)
+ : Type(T), Parent(P), Begin(B), End(E) { }
+
+public:
+ bool isTextAtom() { return Type == TextAtom; }
+ bool isDataAtom() { return Type == DataAtom; }
+
+ void addInst(const MCInst &I, uint64_t Address, unsigned Size);
+ void addData(const MCData &D);
+
+ /// split - Splits the atom in two at a given address, which must align with
+ /// and instruction boundary if this is a TextAtom. Returns the newly created
+ /// atom representing the high part of the split.
+ MCAtom *split(uint64_t SplitPt);
+
+ /// truncate - Truncates an atom so that TruncPt is the last byte address
+ /// contained in the atom.
+ void truncate(uint64_t TruncPt);
+};
+
+}
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/MC/MCCodeEmitter.h b/contrib/llvm/include/llvm/MC/MCCodeEmitter.h
new file mode 100644
index 000000000000..934ef69ce3fe
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCCodeEmitter.h
@@ -0,0 +1,38 @@
+//===-- llvm/MC/MCCodeEmitter.h - Instruction Encoding ----------*- 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_MCCODEEMITTER_H
+#define LLVM_MC_MCCODEEMITTER_H
+
+namespace llvm {
+class MCFixup;
+class MCInst;
+class raw_ostream;
+template<typename T> class SmallVectorImpl;
+
+/// MCCodeEmitter - Generic instruction encoding interface.
+class MCCodeEmitter {
+private:
+ MCCodeEmitter(const MCCodeEmitter &); // DO NOT IMPLEMENT
+ void operator=(const MCCodeEmitter &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ MCCodeEmitter();
+
+public:
+ virtual ~MCCodeEmitter();
+
+ /// EncodeInstruction - Encode the given \arg Inst to bytes on the output
+ /// stream \arg OS.
+ virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCCodeGenInfo.h b/contrib/llvm/include/llvm/MC/MCCodeGenInfo.h
new file mode 100644
index 000000000000..d1765e1240a4
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCCodeGenInfo.h
@@ -0,0 +1,48 @@
+//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen 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 tracks information about the target which can affect codegen,
+// asm parsing, and asm printing. For example, relocation model.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEGENINFO_H
+#define LLVM_MC_MCCODEGENINFO_H
+
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+
+ class MCCodeGenInfo {
+ /// RelocationModel - Relocation model: static, pic, etc.
+ ///
+ Reloc::Model RelocationModel;
+
+ /// CMModel - Code model.
+ ///
+ CodeModel::Model CMModel;
+
+ /// OptLevel - Optimization level.
+ ///
+ CodeGenOpt::Level OptLevel;
+
+ public:
+ void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CM = CodeModel::Default,
+ CodeGenOpt::Level OL = CodeGenOpt::Default);
+
+ Reloc::Model getRelocationModel() const { return RelocationModel; }
+
+ CodeModel::Model getCodeModel() const { return CMModel; }
+
+ CodeGenOpt::Level getOptLevel() const { return OptLevel; }
+ };
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCContext.h b/contrib/llvm/include/llvm/MC/MCContext.h
new file mode 100644
index 000000000000..b58631919330
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCContext.h
@@ -0,0 +1,406 @@
+//===- MCContext.h - Machine Code Context -----------------------*- 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_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/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector> // FIXME: Shouldn't be needed.
+
+namespace llvm {
+ class MCAsmInfo;
+ class MCExpr;
+ class MCSection;
+ class MCSymbol;
+ class MCLabel;
+ class MCDwarfFile;
+ class MCDwarfLoc;
+ class MCObjectFileInfo;
+ class MCRegisterInfo;
+ class MCLineSection;
+ class SMLoc;
+ class StringRef;
+ class Twine;
+ class MCSectionMachO;
+ class MCSectionELF;
+
+ /// MCContext - Context object for machine code objects. This class owns all
+ /// of the sections that it creates.
+ ///
+ class MCContext {
+ MCContext(const MCContext&); // DO NOT IMPLEMENT
+ MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
+ public:
+ typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
+ private:
+ /// The SourceMgr for this object, if any.
+ const SourceMgr *SrcMgr;
+
+ /// The MCAsmInfo for this target.
+ const MCAsmInfo &MAI;
+
+ /// The MCRegisterInfo for this target.
+ const MCRegisterInfo &MRI;
+
+ /// The MCObjectFileInfo for this target.
+ const MCObjectFileInfo *MOFI;
+
+ /// Allocator - Allocator object used for creating machine code objects.
+ ///
+ /// We use a bump pointer allocator to avoid the need to track all allocated
+ /// objects.
+ BumpPtrAllocator Allocator;
+
+ /// Symbols - Bindings of names to symbols.
+ SymbolTable Symbols;
+
+ /// UsedNames - Keeps tracks of names that were used both for used declared
+ /// and artificial symbols.
+ StringMap<bool, BumpPtrAllocator&> UsedNames;
+
+ /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
+ /// symbol.
+ unsigned NextUniqueID;
+
+ /// Instances of directional local labels.
+ DenseMap<unsigned, MCLabel *> Instances;
+ /// NextInstance() creates the next instance of the directional local label
+ /// for the LocalLabelVal and adds it to the map if needed.
+ unsigned NextInstance(int64_t LocalLabelVal);
+ /// GetInstance() gets the current instance of the directional local label
+ /// for the LocalLabelVal and adds it to the map if needed.
+ unsigned GetInstance(int64_t LocalLabelVal);
+
+ /// The file name of the log file from the environment variable
+ /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique
+ /// directive is used or it is an error.
+ char *SecureLogFile;
+ /// The stream that gets written to for the .secure_log_unique directive.
+ raw_ostream *SecureLog;
+ /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
+ /// catch errors if .secure_log_unique appears twice without
+ /// .secure_log_reset appearing between them.
+ bool SecureLogUsed;
+
+ /// The dwarf file and directory tables from the dwarf .file directive.
+ std::vector<MCDwarfFile *> MCDwarfFiles;
+ std::vector<StringRef> MCDwarfDirs;
+
+ /// The current dwarf line information from the last dwarf .loc directive.
+ MCDwarfLoc CurrentDwarfLoc;
+ bool DwarfLocSeen;
+
+ /// Generate dwarf debugging info for assembly source files.
+ bool GenDwarfForAssembly;
+
+ /// The current dwarf file number when generate dwarf debugging info for
+ /// assembly source files.
+ unsigned GenDwarfFileNumber;
+
+ /// The default initial text section that we generate dwarf debugging line
+ /// info for when generating dwarf assembly source files.
+ const MCSection *GenDwarfSection;
+ /// Symbols created for the start and end of this section.
+ MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
+
+ /// The information gathered from labels that will have dwarf label
+ /// entries when generating dwarf assembly source files.
+ std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries;
+
+ /// The string to embed in the debug information for the compile unit, if
+ /// non-empty.
+ StringRef DwarfDebugFlags;
+
+ /// Honor temporary labels, this is useful for debugging semantic
+ /// differences between temporary and non-temporary labels (primarily on
+ /// Darwin).
+ bool AllowTemporaryLabels;
+
+ /// The dwarf line information from the .loc directives for the sections
+ /// with assembled machine instructions have after seeing .loc directives.
+ DenseMap<const MCSection *, MCLineSection *> MCLineSections;
+ /// We need a deterministic iteration order, so we remember the order
+ /// the elements were added.
+ std::vector<const MCSection *> MCLineSectionOrder;
+
+ void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
+
+ MCSymbol *CreateSymbol(StringRef Name);
+
+ public:
+ explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
+ const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0);
+ ~MCContext();
+
+ const SourceMgr *getSourceManager() const { return SrcMgr; }
+
+ const MCAsmInfo &getAsmInfo() const { return MAI; }
+
+ const MCRegisterInfo &getRegisterInfo() const { return MRI; }
+
+ const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
+
+ void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+
+ /// @name Symbol Management
+ /// @{
+
+ /// CreateTempSymbol - Create and return a new assembler temporary symbol
+ /// with a unique but unspecified name.
+ MCSymbol *CreateTempSymbol();
+
+ /// CreateDirectionalLocalSymbol - Create the definition of a directional
+ /// local symbol for numbered label (used for "1:" definitions).
+ MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
+
+ /// GetDirectionalLocalSymbol - Create and return a directional local
+ /// symbol for numbered label (used for "1b" or 1f" references).
+ MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf);
+
+ /// GetOrCreateSymbol - Lookup the symbol inside with the specified
+ /// @p Name. If it exists, return it. If not, create a forward
+ /// reference and return it.
+ ///
+ /// @param Name - The symbol name, which must be unique across all symbols.
+ MCSymbol *GetOrCreateSymbol(StringRef Name);
+ MCSymbol *GetOrCreateSymbol(const Twine &Name);
+
+ /// LookupSymbol - Get the symbol for \p Name, or null.
+ MCSymbol *LookupSymbol(StringRef Name) const;
+
+ /// getSymbols - Get a reference for the symbol table for clients that
+ /// want to, for example, iterate over all symbols. 'const' because we
+ /// still want any modifications to the table itself to use the MCContext
+ /// APIs.
+ const SymbolTable &getSymbols() const {
+ return Symbols;
+ }
+
+ /// @}
+
+ /// @name Section Management
+ /// @{
+
+ /// getMachOSection - Return the MCSection for the specified mach-o section.
+ /// This requires the operands to be valid.
+ const MCSectionMachO *getMachOSection(StringRef Segment,
+ StringRef Section,
+ unsigned TypeAndAttributes,
+ unsigned Reserved2,
+ SectionKind K);
+ const MCSectionMachO *getMachOSection(StringRef Segment,
+ StringRef Section,
+ unsigned TypeAndAttributes,
+ SectionKind K) {
+ return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
+ }
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind);
+
+ const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind,
+ unsigned EntrySize, StringRef Group);
+
+ const MCSectionELF *CreateELFGroupSection();
+
+ const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
+ int Selection, SectionKind Kind);
+
+ const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
+ SectionKind Kind) {
+ return getCOFFSection (Section, Characteristics, 0, Kind);
+ }
+
+
+ /// @}
+
+ /// @name Dwarf Management
+ /// @{
+
+ /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
+ unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
+ unsigned FileNumber);
+
+ bool isValidDwarfFileNumber(unsigned FileNumber);
+
+ bool hasDwarfFiles() const {
+ return !MCDwarfFiles.empty();
+ }
+
+ const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
+ return MCDwarfFiles;
+ }
+ const std::vector<StringRef> &getMCDwarfDirs() {
+ return MCDwarfDirs;
+ }
+
+ const DenseMap<const MCSection *, MCLineSection *>
+ &getMCLineSections() const {
+ return MCLineSections;
+ }
+ const std::vector<const MCSection *> &getMCLineSectionOrder() const {
+ return MCLineSectionOrder;
+ }
+ void addMCLineSection(const MCSection *Sec, MCLineSection *Line) {
+ MCLineSections[Sec] = Line;
+ MCLineSectionOrder.push_back(Sec);
+ }
+
+ /// setCurrentDwarfLoc - saves the information from the currently parsed
+ /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
+ /// is assembled an entry in the line number table with this information and
+ /// the address of the instruction will be created.
+ void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
+ unsigned Flags, unsigned Isa,
+ unsigned Discriminator) {
+ CurrentDwarfLoc.setFileNum(FileNum);
+ CurrentDwarfLoc.setLine(Line);
+ CurrentDwarfLoc.setColumn(Column);
+ CurrentDwarfLoc.setFlags(Flags);
+ CurrentDwarfLoc.setIsa(Isa);
+ CurrentDwarfLoc.setDiscriminator(Discriminator);
+ DwarfLocSeen = true;
+ }
+ void ClearDwarfLocSeen() { DwarfLocSeen = false; }
+
+ bool getDwarfLocSeen() { return DwarfLocSeen; }
+ const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
+
+ bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
+ void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
+ unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
+ unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; }
+ const MCSection *getGenDwarfSection() { return GenDwarfSection; }
+ void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
+ MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
+ void setGenDwarfSectionStartSym(MCSymbol *Sym) {
+ GenDwarfSectionStartSym = Sym;
+ }
+ MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
+ void setGenDwarfSectionEndSym(MCSymbol *Sym) {
+ GenDwarfSectionEndSym = Sym;
+ }
+ const std::vector<const MCGenDwarfLabelEntry *>
+ &getMCGenDwarfLabelEntries() const {
+ return MCGenDwarfLabelEntries;
+ }
+ void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) {
+ MCGenDwarfLabelEntries.push_back(E);
+ }
+
+ void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
+ StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
+
+ /// @}
+
+ char *getSecureLogFile() { return SecureLogFile; }
+ raw_ostream *getSecureLog() { return SecureLog; }
+ bool getSecureLogUsed() { return SecureLogUsed; }
+ void setSecureLog(raw_ostream *Value) {
+ SecureLog = Value;
+ }
+ void setSecureLogUsed(bool Value) {
+ SecureLogUsed = Value;
+ }
+
+ void *Allocate(unsigned Size, unsigned Align = 8) {
+ return Allocator.Allocate(Size, Align);
+ }
+ void Deallocate(void *Ptr) {
+ }
+
+ // Unrecoverable error has occured. Display the best diagnostic we can
+ // and bail via exit(1). For now, most MC backend errors are unrecoverable.
+ // FIXME: We should really do something about that.
+ LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg);
+ };
+
+} // end namespace llvm
+
+// operator new and delete aren't allowed inside namespaces.
+// The throw specifications are mandated by the standard.
+/// @brief Placement new for using the MCContext's allocator.
+///
+/// This placement form of operator new uses the MCContext's allocator for
+/// obtaining memory. It is a non-throwing new, which means that it returns
+/// null on error. (If that is what the allocator does. The current does, so if
+/// this ever changes, this operator will have to be changed, too.)
+/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
+/// @code
+/// // Default alignment (16)
+/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
+/// // Specific alignment
+/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The MCContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+/// allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new(size_t Bytes, llvm::MCContext &C,
+ size_t Alignment = 16) throw () {
+ return C.Allocate(Bytes, Alignment);
+}
+/// @brief Placement delete companion to the new above.
+///
+/// This operator is just a companion to the new above. There is no way of
+/// invoking it directly; see the new operator for more details. This operator
+/// is called implicitly by the compiler if a placement new expression using
+/// the MCContext throws in the object constructor.
+inline void operator delete(void *Ptr, llvm::MCContext &C, size_t)
+ throw () {
+ C.Deallocate(Ptr);
+}
+
+/// This placement form of operator new[] uses the MCContext's allocator for
+/// obtaining memory. It is a non-throwing new[], which means that it returns
+/// null on error.
+/// Usage looks like this (assuming there's an MCContext 'Context' in scope):
+/// @code
+/// // Default alignment (16)
+/// char *data = new (Context) char[10];
+/// // Specific alignment
+/// char *data = new (Context, 8) char[10];
+/// @endcode
+/// Please note that you cannot use delete on the pointer; it must be
+/// deallocated using an explicit destructor call followed by
+/// @c Context.Deallocate(Ptr).
+///
+/// @param Bytes The number of bytes to allocate. Calculated by the compiler.
+/// @param C The MCContext that provides the allocator.
+/// @param Alignment The alignment of the allocated memory (if the underlying
+/// allocator supports it).
+/// @return The allocated memory. Could be NULL.
+inline void *operator new[](size_t Bytes, llvm::MCContext& C,
+ size_t Alignment = 16) throw () {
+ return C.Allocate(Bytes, Alignment);
+}
+
+/// @brief Placement delete[] companion to the new[] above.
+///
+/// This operator is just a companion to the new[] above. There is no way of
+/// invoking it directly; see the new[] operator for more details. This operator
+/// is called implicitly by the compiler if a placement new[] expression using
+/// the MCContext throws in the object constructor.
+inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () {
+ C.Deallocate(Ptr);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCDirectives.h b/contrib/llvm/include/llvm/MC/MCDirectives.h
new file mode 100644
index 000000000000..9180d1b369fe
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCDirectives.h
@@ -0,0 +1,57 @@
+//===- MCDirectives.h - Enums for directives on various targets -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various enums that represent target-specific directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDIRECTIVES_H
+#define LLVM_MC_MCDIRECTIVES_H
+
+namespace llvm {
+
+enum MCSymbolAttr {
+ MCSA_Invalid = 0, ///< Not a valid directive.
+
+ // Various directives in alphabetical order.
+ MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
+ MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
+ MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
+ MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
+ MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
+ MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
+ MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
+ MCSA_Global, ///< .globl
+ MCSA_Hidden, ///< .hidden (ELF)
+ MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
+ MCSA_Internal, ///< .internal (ELF)
+ MCSA_LazyReference, ///< .lazy_reference (MachO)
+ MCSA_Local, ///< .local (ELF)
+ MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
+ MCSA_SymbolResolver, ///< .symbol_resolver (MachO)
+ MCSA_PrivateExtern, ///< .private_extern (MachO)
+ MCSA_Protected, ///< .protected (ELF)
+ MCSA_Reference, ///< .reference (MachO)
+ MCSA_Weak, ///< .weak
+ MCSA_WeakDefinition, ///< .weak_definition (MachO)
+ MCSA_WeakReference, ///< .weak_reference (MachO)
+ MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO)
+};
+
+enum MCAssemblerFlag {
+ MCAF_SyntaxUnified, ///< .syntax (ARM/ELF)
+ MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO)
+ MCAF_Code16, ///< .code16 (X86) / .code 16 (ARM)
+ MCAF_Code32, ///< .code32 (X86) / .code 32 (ARM)
+ MCAF_Code64 ///< .code64 (X86)
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCDisassembler.h b/contrib/llvm/include/llvm/MC/MCDisassembler.h
new file mode 100644
index 000000000000..4b5fbec47dce
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCDisassembler.h
@@ -0,0 +1,136 @@
+//===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MCDISASSEMBLER_H
+#define MCDISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm-c/Disassembler.h"
+
+namespace llvm {
+
+class MCInst;
+class MCSubtargetInfo;
+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 {
+public:
+ /// Ternary decode status. Most backends will just use Fail and
+ /// Success, however some have a concept of an instruction with
+ /// understandable semantics but which is architecturally
+ /// incorrect. An example of this is ARM UNPREDICTABLE instructions
+ /// which are disassemblable but cause undefined behaviour.
+ ///
+ /// Because it makes sense to disassemble these instructions, there
+ /// is a "soft fail" failure mode that indicates the MCInst& is
+ /// valid but architecturally incorrect.
+ ///
+ /// The enum numbers are deliberately chosen such that reduction
+ /// from Success->SoftFail ->Fail can be done with a simple
+ /// bitwise-AND:
+ ///
+ /// LEFT & TOP = | Success Unpredictable Fail
+ /// --------------+-----------------------------------
+ /// Success | Success Unpredictable Fail
+ /// Unpredictable | Unpredictable Unpredictable Fail
+ /// Fail | Fail Fail Fail
+ ///
+ /// An easy way of encoding this is as 0b11, 0b01, 0b00 for
+ /// Success, SoftFail, Fail respectively.
+ enum DecodeStatus {
+ Fail = 0,
+ SoftFail = 1,
+ Success = 3
+ };
+
+ /// Constructor - Performs initial setup for the disassembler.
+ MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
+ DisInfo(0), Ctx(0),
+ STI(STI), CommentStream(0) {}
+
+ virtual ~MCDisassembler();
+
+ /// getInstruction - Returns the disassembly of a single instruction.
+ ///
+ /// @param instr - An MCInst to populate with the contents of the
+ /// instruction.
+ /// @param size - A value to populate with the size of the instruction, or
+ /// the number of bytes consumed while attempting to decode
+ /// an invalid instruction.
+ /// @param region - The memory object to use as a source for machine code.
+ /// @param address - The address, in the memory space of region, of the first
+ /// byte of the instruction.
+ /// @param vStream - The stream to print warnings and diagnostic messages on.
+ /// @param cStream - The stream to print comments and annotations on.
+ /// @return - MCDisassembler::Success if the instruction is valid,
+ /// MCDisassembler::SoftFail if the instruction was
+ /// disassemblable but invalid,
+ /// MCDisassembler::Fail if the instruction was invalid.
+ virtual DecodeStatus getInstruction(MCInst& instr,
+ uint64_t& size,
+ const MemoryObject &region,
+ uint64_t address,
+ 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.
+ //
+ // The function to get the symbolic information for operands.
+ LLVMOpInfoCallback GetOpInfo;
+ // The function to lookup a symbol name.
+ LLVMSymbolLookupCallback SymbolLookUp;
+ // The pointer to the block of symbolic information for above call back.
+ void *DisInfo;
+ // The assembly context for creating symbols and MCExprs in place of
+ // immediate operands when there is symbolic information.
+ MCContext *Ctx;
+protected:
+ // Subtarget information, for instruction decoding predicates if required.
+ const MCSubtargetInfo &STI;
+
+public:
+ void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo,
+ LLVMSymbolLookupCallback symbolLookUp,
+ void *disInfo,
+ MCContext *ctx) {
+ GetOpInfo = getOpInfo;
+ SymbolLookUp = symbolLookUp;
+ DisInfo = disInfo;
+ Ctx = ctx;
+ }
+ LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; }
+ LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const {
+ return SymbolLookUp;
+ }
+ void *getDisInfoBlock() const { return DisInfo; }
+ MCContext *getMCContext() const { return Ctx; }
+
+ // Marked mutable because we cache it inside the disassembler, rather than
+ // having to pass it around as an argument through all the autogenerated code.
+ mutable raw_ostream *CommentStream;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCDwarf.h b/contrib/llvm/include/llvm/MC/MCDwarf.h
new file mode 100644
index 000000000000..fdb7ab23c09f
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCDwarf.h
@@ -0,0 +1,337 @@
+//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCDwarfFile to support the dwarf
+// .file directive and the .loc directive.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCDWARF_H
+#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 <vector>
+
+namespace llvm {
+ class MCContext;
+ class MCObjectWriter;
+ class MCSection;
+ class MCStreamer;
+ class MCSymbol;
+ class SourceMgr;
+ class SMLoc;
+
+ /// MCDwarfFile - Instances of this class represent the name of the dwarf
+ /// .file directive and its associated dwarf file number in the MC file,
+ /// and MCDwarfFile's are created and unique'd by the MCContext class where
+ /// the file number for each is its index into the vector of DwarfFiles (note
+ /// index 0 is not used and not a valid dwarf file number).
+ class MCDwarfFile {
+ // Name - the base name of the file without its directory path.
+ // The StringRef references memory allocated in the MCContext.
+ StringRef Name;
+
+ // DirIndex - the index into the list of directory names for this file name.
+ unsigned DirIndex;
+
+ private: // MCContext creates and uniques these.
+ friend class MCContext;
+ MCDwarfFile(StringRef name, unsigned dirIndex)
+ : Name(name), DirIndex(dirIndex) {}
+
+ MCDwarfFile(const MCDwarfFile&); // DO NOT IMPLEMENT
+ void operator=(const MCDwarfFile&); // DO NOT IMPLEMENT
+ public:
+ /// getName - Get the base name of this MCDwarfFile.
+ StringRef getName() const { return Name; }
+
+ /// getDirIndex - Get the dirIndex of this MCDwarfFile.
+ unsigned getDirIndex() const { return DirIndex; }
+
+
+ /// print - Print the value to the stream \arg OS.
+ void print(raw_ostream &OS) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
+ DwarfFile.print(OS);
+ return OS;
+ }
+
+ /// MCDwarfLoc - Instances of this class represent the information from a
+ /// dwarf .loc directive.
+ class MCDwarfLoc {
+ // FileNum - the file number.
+ unsigned FileNum;
+ // Line - the line number.
+ unsigned Line;
+ // Column - the column position.
+ unsigned Column;
+ // Flags (see #define's below)
+ unsigned Flags;
+ // Isa
+ unsigned Isa;
+ // Discriminator
+ unsigned Discriminator;
+
+// Flag that indicates the initial value of the is_stmt_start flag.
+#define DWARF2_LINE_DEFAULT_IS_STMT 1
+
+#define DWARF2_FLAG_IS_STMT (1 << 0)
+#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
+#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
+#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
+
+ private: // MCContext manages these
+ friend class MCContext;
+ friend class MCLineEntry;
+ MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
+ unsigned isa, unsigned discriminator)
+ : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
+ Discriminator(discriminator) {}
+
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCDwarfLoc object.
+
+ public:
+ /// getFileNum - Get the FileNum of this MCDwarfLoc.
+ unsigned getFileNum() const { return FileNum; }
+
+ /// getLine - Get the Line of this MCDwarfLoc.
+ unsigned getLine() const { return Line; }
+
+ /// getColumn - Get the Column of this MCDwarfLoc.
+ unsigned getColumn() const { return Column; }
+
+ /// getFlags - Get the Flags of this MCDwarfLoc.
+ unsigned getFlags() const { return Flags; }
+
+ /// getIsa - Get the Isa of this MCDwarfLoc.
+ unsigned getIsa() const { return Isa; }
+
+ /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
+ unsigned getDiscriminator() const { return Discriminator; }
+
+ /// setFileNum - Set the FileNum of this MCDwarfLoc.
+ void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+ /// setLine - Set the Line of this MCDwarfLoc.
+ void setLine(unsigned line) { Line = line; }
+
+ /// setColumn - Set the Column of this MCDwarfLoc.
+ void setColumn(unsigned column) { Column = column; }
+
+ /// setFlags - Set the Flags of this MCDwarfLoc.
+ void setFlags(unsigned flags) { Flags = flags; }
+
+ /// setIsa - Set the Isa of this MCDwarfLoc.
+ void setIsa(unsigned isa) { Isa = isa; }
+
+ /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
+ void setDiscriminator(unsigned discriminator) {
+ Discriminator = discriminator;
+ }
+ };
+
+ /// MCLineEntry - Instances of this class represent the line information for
+ /// the dwarf line table entries. Which is created after a machine
+ /// instruction is assembled and uses an address from a temporary label
+ /// created at the current address in the current section and the info from
+ /// the last .loc directive seen as stored in the context.
+ class MCLineEntry : public MCDwarfLoc {
+ MCSymbol *Label;
+
+ private:
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCLineEntry object.
+
+ public:
+ // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
+ MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
+ Label(label) {}
+
+ MCSymbol *getLabel() const { return Label; }
+
+ // This is called when an instruction is assembled into the specified
+ // section and if there is information from the last .loc directive that
+ // has yet to have a line entry made for it is made.
+ static void Make(MCStreamer *MCOS, const MCSection *Section);
+ };
+
+ /// MCLineSection - Instances of this class represent the line information
+ /// for a section where machine instructions have been assembled after seeing
+ /// .loc directives. This is the information used to build the dwarf line
+ /// table for a section.
+ class MCLineSection {
+
+ private:
+ MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT
+ void operator=(const MCLineSection&); // DO NOT IMPLEMENT
+
+ public:
+ // Constructor to create an MCLineSection with an empty MCLineEntries
+ // vector.
+ MCLineSection() {}
+
+ // addLineEntry - adds an entry to this MCLineSection's line entries
+ void addLineEntry(const MCLineEntry &LineEntry) {
+ MCLineEntries.push_back(LineEntry);
+ }
+
+ typedef std::vector<MCLineEntry> MCLineEntryCollection;
+ typedef MCLineEntryCollection::iterator iterator;
+ typedef MCLineEntryCollection::const_iterator const_iterator;
+
+ private:
+ MCLineEntryCollection MCLineEntries;
+
+ public:
+ const MCLineEntryCollection *getMCLineEntries() const {
+ return &MCLineEntries;
+ }
+ };
+
+ class MCDwarfFileTable {
+ public:
+ //
+ // This emits the Dwarf file and the line tables.
+ //
+ static const MCSymbol *Emit(MCStreamer *MCOS);
+ };
+
+ class MCDwarfLineAddr {
+ public:
+ /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
+ static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
+
+ /// Utility function to emit the encoding to a streamer.
+ static void Emit(MCStreamer *MCOS,
+ int64_t LineDelta,uint64_t AddrDelta);
+
+ /// Utility function to write the encoding to an object writer.
+ static void Write(MCObjectWriter *OW,
+ int64_t LineDelta, uint64_t AddrDelta);
+ };
+
+ class MCGenDwarfInfo {
+ public:
+ //
+ // When generating dwarf for assembly source files this emits the Dwarf
+ // sections.
+ //
+ static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
+ };
+
+ // When generating dwarf for assembly source files this is the info that is
+ // needed to be gathered for each symbol that will have a dwarf label.
+ class MCGenDwarfLabelEntry {
+ private:
+ // Name of the symbol without a leading underbar, if any.
+ StringRef Name;
+ // The dwarf file number this symbol is in.
+ unsigned FileNumber;
+ // The line number this symbol is at.
+ unsigned LineNumber;
+ // The low_pc for the dwarf label is taken from this symbol.
+ MCSymbol *Label;
+
+ public:
+ MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber,
+ unsigned lineNumber, MCSymbol *label) :
+ Name(name), FileNumber(fileNumber), LineNumber(lineNumber), Label(label){}
+
+ StringRef getName() const { return Name; }
+ unsigned getFileNumber() const { return FileNumber; }
+ unsigned getLineNumber() const { return LineNumber; }
+ MCSymbol *getLabel() const { return Label; }
+
+ // This is called when label is created when we are generating dwarf for
+ // assembly source files.
+ static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
+ SMLoc &Loc);
+ };
+
+ class MCCFIInstruction {
+ public:
+ enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape,
+ Restore};
+ private:
+ OpType Operation;
+ MCSymbol *Label;
+ // Move to & from location.
+ MachineLocation Destination;
+ MachineLocation Source;
+ std::vector<char> Values;
+ public:
+ MCCFIInstruction(OpType Op, MCSymbol *L)
+ : Operation(Op), Label(L) {
+ assert(Op == RememberState || Op == RestoreState);
+ }
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
+ : Operation(Op), Label(L), Destination(Register) {
+ assert(Op == SameValue || Op == Restore);
+ }
+ MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
+ const MachineLocation &S)
+ : Operation(Move), Label(L), Destination(D), Source(S) {
+ }
+ MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
+ const MachineLocation &S)
+ : Operation(Op), Label(L), Destination(D), Source(S) {
+ assert(Op == RelMove);
+ }
+ MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals)
+ : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) {
+ assert(Op == Escape);
+ }
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+ const StringRef getValues() const {
+ return StringRef(&Values[0], Values.size());
+ }
+ };
+
+ struct MCDwarfFrameInfo {
+ MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
+ Function(0), Instructions(), PersonalityEncoding(),
+ LsdaEncoding(0), CompactUnwindEncoding(0),
+ IsSignalFrame(false) {}
+ MCSymbol *Begin;
+ MCSymbol *End;
+ const MCSymbol *Personality;
+ const MCSymbol *Lsda;
+ const MCSymbol *Function;
+ std::vector<MCCFIInstruction> Instructions;
+ unsigned PersonalityEncoding;
+ unsigned LsdaEncoding;
+ uint32_t CompactUnwindEncoding;
+ bool IsSignalFrame;
+ };
+
+ class MCDwarfFrameEmitter {
+ public:
+ //
+ // This emits the frame info section.
+ //
+ static void Emit(MCStreamer &streamer, bool usingCFI,
+ bool isEH);
+ static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
+ static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
+ };
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h
new file mode 100644
index 000000000000..f153cb0c1af0
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCELFObjectWriter.h
@@ -0,0 +1,110 @@
+//===-- llvm/MC/MCELFObjectWriter.h - ELF Object Writer ---------*- 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_MCELFOBJECTWRITER_H
+#define LLVM_MC_MCELFOBJECTWRITER_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ELF.h"
+#include <vector>
+
+namespace llvm {
+class MCAssembler;
+class MCFixup;
+class MCFragment;
+class MCObjectWriter;
+class MCSymbol;
+class MCValue;
+
+/// @name Relocation Data
+/// @{
+
+struct ELFRelocationEntry {
+ // Make these big enough for both 32-bit and 64-bit
+ uint64_t r_offset;
+ int Index;
+ unsigned Type;
+ const MCSymbol *Symbol;
+ uint64_t r_addend;
+ const MCFixup *Fixup;
+
+ ELFRelocationEntry()
+ : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {}
+
+ ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType,
+ const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup)
+ : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym),
+ r_addend(Addend), Fixup(&Fixup) {}
+
+ // Support lexicographic sorting.
+ bool operator<(const ELFRelocationEntry &RE) const {
+ return RE.r_offset < r_offset;
+ }
+};
+
+class MCELFObjectTargetWriter {
+ const uint8_t OSABI;
+ const uint16_t EMachine;
+ const unsigned HasRelocationAddend : 1;
+ const unsigned Is64Bit : 1;
+
+protected:
+
+ MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
+ uint16_t EMachine_, bool HasRelocationAddend_);
+
+public:
+ static uint8_t getOSABI(Triple::OSType OSType) {
+ switch (OSType) {
+ case Triple::FreeBSD:
+ return ELF::ELFOSABI_FREEBSD;
+ case Triple::Linux:
+ return ELF::ELFOSABI_LINUX;
+ default:
+ return ELF::ELFOSABI_NONE;
+ }
+ }
+
+ virtual ~MCELFObjectTargetWriter() {}
+
+ virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
+ bool IsPCRel, bool IsRelocWithSymbol,
+ int64_t Addend) const = 0;
+ virtual unsigned getEFlags() const;
+ virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
+ const MCValue &Target,
+ const MCFragment &F,
+ const MCFixup &Fixup,
+ bool IsPCRel) const;
+ virtual void adjustFixupOffset(const MCFixup &Fixup,
+ uint64_t &RelocOffset);
+
+ virtual void sortRelocs(const MCAssembler &Asm,
+ std::vector<ELFRelocationEntry> &Relocs);
+
+ /// @name Accessors
+ /// @{
+ uint8_t getOSABI() { return OSABI; }
+ uint16_t getEMachine() { return EMachine; }
+ bool hasRelocationAddend() { return HasRelocationAddend; }
+ bool is64Bit() const { return Is64Bit; }
+ /// @}
+};
+
+/// \brief Construct a new ELF writer instance.
+///
+/// \param MOTW - The target specific ELF writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
+ raw_ostream &OS, bool IsLittleEndian);
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h b/contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h
new file mode 100644
index 000000000000..2225ea07868f
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCELFSymbolFlags.h
@@ -0,0 +1,58 @@
+//===- MCELFSymbolFlags.h - ELF Symbol Flags ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolFlags used for the ELF target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELFSYMBOLFLAGS_H
+#define LLVM_MC_MCELFSYMBOLFLAGS_H
+
+#include "llvm/Support/ELF.h"
+
+// Because all the symbol flags need to be stored in the MCSymbolData
+// 'flags' variable we need to provide shift constants per flag type.
+
+namespace llvm {
+ enum {
+ ELF_STT_Shift = 0, // Shift value for STT_* flags.
+ ELF_STB_Shift = 4, // Shift value for STB_* flags.
+ ELF_STV_Shift = 8, // Shift value for STV_* flags.
+ ELF_Other_Shift = 10 // Shift value for other flags.
+ };
+
+ enum SymbolFlags {
+ ELF_STB_Local = (ELF::STB_LOCAL << ELF_STB_Shift),
+ ELF_STB_Global = (ELF::STB_GLOBAL << ELF_STB_Shift),
+ ELF_STB_Weak = (ELF::STB_WEAK << ELF_STB_Shift),
+ ELF_STB_Loproc = (ELF::STB_LOPROC << ELF_STB_Shift),
+ ELF_STB_Hiproc = (ELF::STB_HIPROC << ELF_STB_Shift),
+
+ ELF_STT_Notype = (ELF::STT_NOTYPE << ELF_STT_Shift),
+ ELF_STT_Object = (ELF::STT_OBJECT << ELF_STT_Shift),
+ ELF_STT_Func = (ELF::STT_FUNC << ELF_STT_Shift),
+ ELF_STT_Section = (ELF::STT_SECTION << ELF_STT_Shift),
+ ELF_STT_File = (ELF::STT_FILE << ELF_STT_Shift),
+ ELF_STT_Common = (ELF::STT_COMMON << ELF_STT_Shift),
+ ELF_STT_Tls = (ELF::STT_TLS << ELF_STT_Shift),
+ ELF_STT_Loproc = (ELF::STT_LOPROC << ELF_STT_Shift),
+ ELF_STT_Hiproc = (ELF::STT_HIPROC << ELF_STT_Shift),
+
+ ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift),
+ ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift),
+ ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift),
+ ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift),
+
+ ELF_Other_Weakref = (1 << ELF_Other_Shift),
+ ELF_Other_ThumbFunc = (2 << ELF_Other_Shift)
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCExpr.h b/contrib/llvm/include/llvm/MC/MCExpr.h
new file mode 100644
index 000000000000..ff33641dba7f
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCExpr.h
@@ -0,0 +1,464 @@
+//===- MCExpr.h - Assembly Level Expressions --------------------*- 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_MCEXPR_H
+#define LLVM_MC_MCEXPR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class MCAsmLayout;
+class MCAssembler;
+class MCContext;
+class MCSection;
+class MCSectionData;
+class MCSymbol;
+class MCValue;
+class raw_ostream;
+class StringRef;
+typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
+
+/// MCExpr - Base class for the full range of assembler expressions which are
+/// needed for parsing.
+class MCExpr {
+public:
+ enum ExprKind {
+ Binary, ///< Binary expressions.
+ Constant, ///< Constant expressions.
+ SymbolRef, ///< References to labels and assigned expressions.
+ Unary, ///< Unary expressions.
+ Target ///< Target specific expression.
+ };
+
+private:
+ ExprKind Kind;
+
+ MCExpr(const MCExpr&); // DO NOT IMPLEMENT
+ void operator=(const MCExpr&); // DO NOT IMPLEMENT
+
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs) const;
+protected:
+ explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
+
+ bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
+ const MCAsmLayout *Layout,
+ const SectionAddrMap *Addrs,
+ bool InSet) const;
+public:
+ /// @name Accessors
+ /// @{
+
+ ExprKind getKind() const { return Kind; }
+
+ /// @}
+ /// @name Utility Methods
+ /// @{
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
+ /// @}
+ /// @name Expression Evaluation
+ /// @{
+
+ /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
+ ///
+ /// @param Res - The absolute value, if evaluation succeeds.
+ /// @param Layout - The assembler layout object to use for evaluating symbol
+ /// values. If not given, then only non-symbolic expressions will be
+ /// evaluated.
+ /// @result - True on success.
+ bool EvaluateAsAbsolute(int64_t &Res) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
+ const SectionAddrMap &Addrs) const;
+
+ /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
+ /// value, i.e. an expression of the fixed form (a - b + constant).
+ ///
+ /// @param Res - The relocatable value, if evaluation succeeds.
+ /// @param Layout - The assembler layout object to use for evaluating values.
+ /// @result - True on success.
+ bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const;
+
+ /// FindAssociatedSection - Find the "associated section" for this expression,
+ /// which is currently defined as the absolute section for constants, or
+ /// otherwise the section associated with the first defined symbol in the
+ /// expression.
+ const MCSection *FindAssociatedSection() const;
+
+ /// @}
+
+ static bool classof(const MCExpr *) { return true; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
+ E.print(OS);
+ return OS;
+}
+
+//// MCConstantExpr - Represent a constant integer expression.
+class MCConstantExpr : public MCExpr {
+ int64_t Value;
+
+ explicit MCConstantExpr(int64_t _Value)
+ : MCExpr(MCExpr::Constant), Value(_Value) {}
+
+public:
+ /// @name Construction
+ /// @{
+
+ static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+
+ int64_t getValue() const { return Value; }
+
+ /// @}
+
+ 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
+/// expression.
+///
+/// A symbol reference in an expression may be a use of a label, a use of an
+/// assembler variable (defined constant), or constitute an implicit definition
+/// of the symbol as external.
+class MCSymbolRefExpr : public MCExpr {
+public:
+ enum VariantKind {
+ VK_None,
+ VK_Invalid,
+
+ VK_GOT,
+ VK_GOTOFF,
+ VK_GOTPCREL,
+ VK_GOTTPOFF,
+ VK_INDNTPOFF,
+ VK_NTPOFF,
+ VK_GOTNTPOFF,
+ VK_PLT,
+ VK_TLSGD,
+ VK_TLSLD,
+ VK_TLSLDM,
+ VK_TPOFF,
+ VK_DTPOFF,
+ 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_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,
+ VK_ARM_GOTOFF,
+ VK_ARM_TPOFF,
+ VK_ARM_GOTTPOFF,
+ VK_ARM_TARGET1,
+
+ VK_PPC_TOC,
+ 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_Mips_GPREL,
+ VK_Mips_GOT_CALL,
+ VK_Mips_GOT16,
+ VK_Mips_GOT,
+ VK_Mips_ABS_HI,
+ VK_Mips_ABS_LO,
+ VK_Mips_TLSGD,
+ VK_Mips_TLSLDM,
+ VK_Mips_DTPREL_HI,
+ VK_Mips_DTPREL_LO,
+ VK_Mips_GOTTPREL,
+ VK_Mips_TPREL_HI,
+ VK_Mips_TPREL_LO,
+ VK_Mips_GPOFF_HI,
+ VK_Mips_GPOFF_LO,
+ VK_Mips_GOT_DISP,
+ VK_Mips_GOT_PAGE,
+ VK_Mips_GOT_OFST
+ };
+
+private:
+ /// The symbol being referenced.
+ const MCSymbol *Symbol;
+
+ /// The symbol reference modifier.
+ const VariantKind Kind;
+
+ explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
+ : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {
+ assert(Symbol);
+ }
+
+public:
+ /// @name Construction
+ /// @{
+
+ static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
+ return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
+ }
+
+ static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
+ MCContext &Ctx);
+ static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
+ MCContext &Ctx);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+
+ const MCSymbol &getSymbol() const { return *Symbol; }
+
+ VariantKind getKind() const { return Kind; }
+
+ /// @}
+ /// @name Static Utility Functions
+ /// @{
+
+ static StringRef getVariantKindName(VariantKind Kind);
+
+ static VariantKind getVariantKindForName(StringRef Name);
+
+ /// @}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::SymbolRef;
+ }
+ static bool classof(const MCSymbolRefExpr *) { return true; }
+};
+
+/// MCUnaryExpr - Unary assembler expressions.
+class MCUnaryExpr : public MCExpr {
+public:
+ enum Opcode {
+ LNot, ///< Logical negation.
+ Minus, ///< Unary minus.
+ Not, ///< Bitwise negation.
+ Plus ///< Unary plus.
+ };
+
+private:
+ Opcode Op;
+ const MCExpr *Expr;
+
+ MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
+ : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
+
+public:
+ /// @name Construction
+ /// @{
+
+ static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
+ MCContext &Ctx);
+ static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
+ return Create(LNot, Expr, Ctx);
+ }
+ static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
+ return Create(Minus, Expr, Ctx);
+ }
+ static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
+ return Create(Not, Expr, Ctx);
+ }
+ static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
+ return Create(Plus, Expr, Ctx);
+ }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+
+ /// getOpcode - Get the kind of this unary expression.
+ Opcode getOpcode() const { return Op; }
+
+ /// getSubExpr - Get the child of this unary expression.
+ const MCExpr *getSubExpr() const { return Expr; }
+
+ /// @}
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Unary;
+ }
+ static bool classof(const MCUnaryExpr *) { return true; }
+};
+
+/// MCBinaryExpr - Binary assembler expressions.
+class MCBinaryExpr : public MCExpr {
+public:
+ enum Opcode {
+ Add, ///< Addition.
+ And, ///< Bitwise and.
+ Div, ///< Signed division.
+ EQ, ///< Equality comparison.
+ GT, ///< Signed greater than comparison (result is either 0 or some
+ ///< target-specific non-zero value)
+ GTE, ///< Signed greater than or equal comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ LAnd, ///< Logical and.
+ LOr, ///< Logical or.
+ LT, ///< Signed less than comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ LTE, ///< Signed less than or equal comparison (result is either 0 or
+ ///< some target-specific non-zero value).
+ Mod, ///< Signed remainder.
+ Mul, ///< Multiplication.
+ NE, ///< Inequality comparison.
+ Or, ///< Bitwise or.
+ Shl, ///< Shift left.
+ Shr, ///< Shift right (arithmetic or logical, depending on target)
+ Sub, ///< Subtraction.
+ Xor ///< Bitwise exclusive or.
+ };
+
+private:
+ Opcode Op;
+ const MCExpr *LHS, *RHS;
+
+ MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
+ : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
+
+public:
+ /// @name Construction
+ /// @{
+
+ static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
+ const MCExpr *RHS, MCContext &Ctx);
+ static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Add, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(And, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Div, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(EQ, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(GT, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(GTE, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(LAnd, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(LOr, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(LT, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(LTE, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Mod, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Mul, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(NE, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Or, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Shl, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Shr, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Sub, LHS, RHS, Ctx);
+ }
+ static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
+ MCContext &Ctx) {
+ return Create(Xor, LHS, RHS, Ctx);
+ }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+
+ /// getOpcode - Get the kind of this binary expression.
+ Opcode getOpcode() const { return Op; }
+
+ /// getLHS - Get the left-hand side expression of the binary operator.
+ const MCExpr *getLHS() const { return LHS; }
+
+ /// getRHS - Get the right-hand side expression of the binary operator.
+ const MCExpr *getRHS() const { return RHS; }
+
+ /// @}
+
+ 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
+/// subclasses to implement.
+///
+/// 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();
+protected:
+ MCTargetExpr() : MCExpr(Target) {}
+ virtual ~MCTargetExpr() {}
+public:
+
+ virtual void PrintImpl(raw_ostream &OS) const = 0;
+ virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout) const = 0;
+ virtual void AddValueSymbols(MCAssembler *) const = 0;
+ virtual const MCSection *FindAssociatedSection() const = 0;
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Target;
+ }
+ static bool classof(const MCTargetExpr *) { return true; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCFixup.h b/contrib/llvm/include/llvm/MC/MCFixup.h
new file mode 100644
index 000000000000..16e9eb730b4e
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCFixup.h
@@ -0,0 +1,112 @@
+//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- 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_MCFIXUP_H
+#define LLVM_MC_MCFIXUP_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SMLoc.h"
+#include <cassert>
+
+namespace llvm {
+class MCExpr;
+
+/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
+enum MCFixupKind {
+ FK_Data_1 = 0, ///< A one-byte fixup.
+ FK_Data_2, ///< A two-byte fixup.
+ FK_Data_4, ///< A four-byte fixup.
+ FK_Data_8, ///< A eight-byte fixup.
+ FK_PCRel_1, ///< A one-byte pc relative fixup.
+ FK_PCRel_2, ///< A two-byte pc relative fixup.
+ FK_PCRel_4, ///< A four-byte pc relative fixup.
+ FK_PCRel_8, ///< A eight-byte pc relative fixup.
+ FK_GPRel_1, ///< A one-byte gp relative fixup.
+ FK_GPRel_2, ///< A two-byte gp relative fixup.
+ FK_GPRel_4, ///< A four-byte gp relative fixup.
+ FK_GPRel_8, ///< A eight-byte gp relative fixup.
+ FK_SecRel_1, ///< A one-byte section relative fixup.
+ FK_SecRel_2, ///< A two-byte section relative fixup.
+ FK_SecRel_4, ///< A four-byte section relative fixup.
+ FK_SecRel_8, ///< A eight-byte section relative fixup.
+
+ FirstTargetFixupKind = 128,
+
+ // Limit range of target fixups, in case we want to pack more efficiently
+ // later.
+ MaxTargetFixupKind = (1 << 8)
+};
+
+/// MCFixup - Encode information on a single operation to perform on a byte
+/// sequence (e.g., an encoded instruction) which requires assemble- or run-
+/// time patching.
+///
+/// Fixups are used any time the target instruction encoder needs to represent
+/// some value in an instruction which is not yet concrete. The encoder will
+/// encode the instruction assuming the value is 0, and emit a fixup which
+/// communicates to the assembler backend how it should rewrite the encoded
+/// value.
+///
+/// During the process of relaxation, the assembler will apply fixups as
+/// symbolic values become concrete. When relaxation is complete, any remaining
+/// fixups become relocations in the object file (or errors, if the fixup cannot
+/// be encoded on the target).
+class MCFixup {
+ /// The value to put into the fixup location. The exact interpretation of the
+ /// expression is target dependent, usually it will be one of the operands to
+ /// an instruction or an assembler directive.
+ const MCExpr *Value;
+
+ /// The byte index of start of the relocation inside the encoded instruction.
+ uint32_t Offset;
+
+ /// The target dependent kind of fixup item this is. The kind is used to
+ /// determine how the operand value should be encoded into the instruction.
+ unsigned Kind;
+
+ /// The source location which gave rise to the fixup, if any.
+ SMLoc Loc;
+public:
+ static MCFixup Create(uint32_t Offset, const MCExpr *Value,
+ MCFixupKind Kind, SMLoc Loc = SMLoc()) {
+ assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
+ MCFixup FI;
+ FI.Value = Value;
+ FI.Offset = Offset;
+ FI.Kind = unsigned(Kind);
+ FI.Loc = Loc;
+ return FI;
+ }
+
+ MCFixupKind getKind() const { return MCFixupKind(Kind); }
+
+ uint32_t getOffset() const { return Offset; }
+ void setOffset(uint32_t Value) { Offset = Value; }
+
+ const MCExpr *getValue() const { return Value; }
+
+ /// getKindForSize - Return the generic fixup kind for a value with the given
+ /// size. It is an error to pass an unsupported size.
+ static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
+ switch (Size) {
+ default: llvm_unreachable("Invalid generic fixup size!");
+ case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
+ case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
+ case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
+ case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
+ }
+ }
+
+ SMLoc getLoc() const { return Loc; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCFixupKindInfo.h b/contrib/llvm/include/llvm/MC/MCFixupKindInfo.h
new file mode 100644
index 000000000000..1961687146a8
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCFixupKindInfo.h
@@ -0,0 +1,43 @@
+//===-- llvm/MC/MCFixupKindInfo.h - Fixup Descriptors -----------*- 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_MCFIXUPKINDINFO_H
+#define LLVM_MC_MCFIXUPKINDINFO_H
+
+namespace llvm {
+
+/// MCFixupKindInfo - Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+ enum FixupKindFlags {
+ /// Is this fixup kind PCrelative? This is used by the assembler backend to
+ /// evaluate fixup values in a target independent manner when possible.
+ FKF_IsPCRel = (1 << 0),
+
+ /// Should this fixup kind force a 4-byte aligned effective PC value?
+ FKF_IsAlignedDownTo32Bits = (1 << 1)
+ };
+
+ /// A target specific name for the fixup kind. The names will be unique for
+ /// distinct kinds on any given target.
+ const char *Name;
+
+ /// The bit offset to write the relocation into.
+ unsigned TargetOffset;
+
+ /// The number of bits written by this fixup. The bits are assumed to be
+ /// contiguous.
+ unsigned TargetSize;
+
+ /// Flags describing additional information on this fixup kind.
+ unsigned Flags;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCInst.h b/contrib/llvm/include/llvm/MC/MCInst.h
new file mode 100644
index 000000000000..397a37d3ce48
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCInst.h
@@ -0,0 +1,204 @@
+//===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCInst and MCOperand classes, which
+// is the basic representation used to represent low-level machine code
+// instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINST_H
+#define LLVM_MC_MCINST_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class raw_ostream;
+class MCAsmInfo;
+class MCInstPrinter;
+class MCExpr;
+class MCInst;
+
+/// MCOperand - Instances of this class represent operands of the MCInst class.
+/// This is a simple discriminated union.
+class MCOperand {
+ enum MachineOperandType {
+ kInvalid, ///< Uninitialized.
+ kRegister, ///< Register operand.
+ kImmediate, ///< Immediate operand.
+ kFPImmediate, ///< Floating-point immediate operand.
+ kExpr, ///< Relocatable immediate operand.
+ kInst ///< Sub-instruction operand.
+ };
+ unsigned char Kind;
+
+ union {
+ unsigned RegVal;
+ int64_t ImmVal;
+ double FPImmVal;
+ const MCExpr *ExprVal;
+ const MCInst *InstVal;
+ };
+public:
+
+ MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
+
+ bool isValid() const { return Kind != kInvalid; }
+ bool isReg() const { return Kind == kRegister; }
+ bool isImm() const { return Kind == kImmediate; }
+ bool isFPImm() const { return Kind == kFPImmediate; }
+ bool isExpr() const { return Kind == kExpr; }
+ bool isInst() const { return Kind == kInst; }
+
+ /// getReg - Returns the register number.
+ unsigned getReg() const {
+ assert(isReg() && "This is not a register operand!");
+ return RegVal;
+ }
+
+ /// setReg - Set the register number.
+ void setReg(unsigned Reg) {
+ assert(isReg() && "This is not a register operand!");
+ RegVal = Reg;
+ }
+
+ int64_t getImm() const {
+ assert(isImm() && "This is not an immediate");
+ return ImmVal;
+ }
+ void setImm(int64_t Val) {
+ assert(isImm() && "This is not an immediate");
+ ImmVal = Val;
+ }
+
+ double getFPImm() const {
+ assert(isFPImm() && "This is not an FP immediate");
+ return FPImmVal;
+ }
+
+ void setFPImm(double Val) {
+ assert(isFPImm() && "This is not an FP immediate");
+ FPImmVal = Val;
+ }
+
+ const MCExpr *getExpr() const {
+ assert(isExpr() && "This is not an expression");
+ return ExprVal;
+ }
+ void setExpr(const MCExpr *Val) {
+ assert(isExpr() && "This is not an expression");
+ ExprVal = Val;
+ }
+
+ const MCInst *getInst() const {
+ assert(isInst() && "This is not a sub-instruction");
+ return InstVal;
+ }
+ void setInst(const MCInst *Val) {
+ assert(isInst() && "This is not a sub-instruction");
+ InstVal = Val;
+ }
+
+ static MCOperand CreateReg(unsigned Reg) {
+ MCOperand Op;
+ Op.Kind = kRegister;
+ Op.RegVal = Reg;
+ return Op;
+ }
+ static MCOperand CreateImm(int64_t Val) {
+ MCOperand Op;
+ Op.Kind = kImmediate;
+ Op.ImmVal = Val;
+ return Op;
+ }
+ static MCOperand CreateFPImm(double Val) {
+ MCOperand Op;
+ Op.Kind = kFPImmediate;
+ Op.FPImmVal = Val;
+ return Op;
+ }
+ static MCOperand CreateExpr(const MCExpr *Val) {
+ MCOperand Op;
+ Op.Kind = kExpr;
+ Op.ExprVal = Val;
+ return Op;
+ }
+ static MCOperand CreateInst(const MCInst *Val) {
+ MCOperand Op;
+ Op.Kind = kInst;
+ Op.InstVal = Val;
+ return Op;
+ }
+
+ void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ void dump() const;
+};
+
+template <> struct isPodLike<MCOperand> { static const bool value = true; };
+
+/// MCInst - Instances of this class represent a single low-level machine
+/// instruction.
+class MCInst {
+ unsigned Opcode;
+ SMLoc Loc;
+ SmallVector<MCOperand, 8> Operands;
+public:
+ MCInst() : Opcode(0) {}
+
+ void setOpcode(unsigned Op) { Opcode = Op; }
+ unsigned getOpcode() const { return Opcode; }
+
+ void setLoc(SMLoc loc) { Loc = loc; }
+ SMLoc getLoc() const { return Loc; }
+
+ const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
+ MCOperand &getOperand(unsigned i) { return Operands[i]; }
+ unsigned getNumOperands() const { return Operands.size(); }
+
+ void addOperand(const MCOperand &Op) {
+ Operands.push_back(Op);
+ }
+
+ void clear() { Operands.clear(); }
+ size_t size() { return Operands.size(); }
+
+ typedef SmallVector<MCOperand, 8>::iterator iterator;
+ iterator begin() { return Operands.begin(); }
+ iterator end() { return Operands.end(); }
+ iterator insert(iterator I, const MCOperand &Op) {
+ return Operands.insert(I, Op);
+ }
+
+ void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+ 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
+ /// string.
+ void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0,
+ const MCInstPrinter *Printer = 0,
+ StringRef Separator = " ") const;
+};
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
+ MO.print(OS, 0);
+ return OS;
+}
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
+ MI.print(OS, 0);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCInstPrinter.h b/contrib/llvm/include/llvm/MC/MCInstPrinter.h
new file mode 100644
index 000000000000..3c4f28be7ca6
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCInstPrinter.h
@@ -0,0 +1,66 @@
+//===-- MCInstPrinter.h - Convert an MCInst to target assembly syntax -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTPRINTER_H
+#define LLVM_MC_MCINSTPRINTER_H
+
+namespace llvm {
+class MCInst;
+class raw_ostream;
+class MCAsmInfo;
+class MCInstrInfo;
+class MCRegisterInfo;
+class StringRef;
+
+/// MCInstPrinter - This is an instance of a target assembly language printer
+/// that converts an MCInst to valid target assembly syntax.
+class MCInstPrinter {
+protected:
+ /// CommentStream - a stream that comments can be emitted to if desired.
+ /// Each comment must end with a newline. This will be null if verbose
+ /// assembly emission is disable.
+ raw_ostream *CommentStream;
+ const MCAsmInfo &MAI;
+ const MCInstrInfo &MII;
+ const MCRegisterInfo &MRI;
+
+ /// The current set of available features.
+ unsigned AvailableFeatures;
+
+ /// 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) {}
+
+ virtual ~MCInstPrinter();
+
+ /// setCommentStream - Specify a stream to emit comments to.
+ void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
+
+ /// printInst - Print the specified MCInst to the specified raw_ostream.
+ ///
+ virtual void printInst(const MCInst *MI, raw_ostream &OS,
+ StringRef Annot) = 0;
+
+ /// getOpcodeName - Return the name of the specified opcode enum (e.g.
+ /// "MOV32ri") or empty if we can't resolve it.
+ StringRef getOpcodeName(unsigned Opcode) const;
+
+ /// printRegName - Print the assembler register name.
+ virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
+
+ unsigned getAvailableFeatures() const { return AvailableFeatures; }
+ void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h b/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h
new file mode 100644
index 000000000000..acad6336aca7
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCInstrAnalysis.h
@@ -0,0 +1,61 @@
+//===-- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks ------*- 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 MCInstrAnalysis class which the MCTargetDescs can
+// derive from to give additional information to MC.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+
+namespace llvm {
+
+class MCInstrAnalysis {
+protected:
+ friend class Target;
+ const MCInstrInfo *Info;
+
+public:
+ MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
+
+ virtual ~MCInstrAnalysis() {}
+
+ virtual bool isBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isBranch();
+ }
+
+ virtual bool isConditionalBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isConditionalBranch();
+ }
+
+ virtual bool isUnconditionalBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isUnconditionalBranch();
+ }
+
+ virtual bool isIndirectBranch(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isIndirectBranch();
+ }
+
+ virtual bool isCall(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isCall();
+ }
+
+ virtual bool isReturn(const MCInst &Inst) const {
+ return Info->get(Inst.getOpcode()).isReturn();
+ }
+
+ /// evaluateBranch - Given a branch instruction try to get the address the
+ /// branch targets. Otherwise return -1.
+ virtual uint64_t
+ evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size) const;
+};
+
+}
diff --git a/contrib/llvm/include/llvm/MC/MCInstrDesc.h b/contrib/llvm/include/llvm/MC/MCInstrDesc.h
new file mode 100644
index 000000000000..186612d904d8
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCInstrDesc.h
@@ -0,0 +1,535 @@
+//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- 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 MCOperandInfo and MCInstrDesc classes, which
+// are used to describe target instructions and their operands.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRDESC_H
+#define LLVM_MC_MCINSTRDESC_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Machine Operand Flags and Description
+//===----------------------------------------------------------------------===//
+
+namespace MCOI {
+ // Operand constraints
+ enum OperandConstraint {
+ TIED_TO = 0, // Must be allocated the same register as.
+ EARLY_CLOBBER // Operand is an early clobber register operand
+ };
+
+ /// OperandFlags - These are flags set on operands, but should be considered
+ /// private, all access should go through the MCOperandInfo accessors.
+ /// See the accessors for a description of what these are.
+ enum OperandFlags {
+ LookupPtrRegClass = 0,
+ Predicate,
+ OptionalDef
+ };
+
+ /// Operand Type - Operands are tagged with one of the values of this enum.
+ enum OperandType {
+ OPERAND_UNKNOWN,
+ OPERAND_IMMEDIATE,
+ OPERAND_REGISTER,
+ OPERAND_MEMORY,
+ OPERAND_PCREL
+ };
+}
+
+/// MCOperandInfo - This holds information about one operand of a machine
+/// instruction, indicating the register class for register operands, etc.
+///
+class MCOperandInfo {
+public:
+ /// RegClass - This specifies the register class enumeration of the operand
+ /// if the operand is a register. If isLookupPtrRegClass is set, then this is
+ /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
+ /// get a dynamic register class.
+ int16_t RegClass;
+
+ /// Flags - These are flags from the MCOI::OperandFlags enum.
+ uint8_t Flags;
+
+ /// OperandType - Information about the type of the operand.
+ uint8_t OperandType;
+
+ /// Lower 16 bits are used to specify which constraints are set. The higher 16
+ /// bits are used to specify the value of constraints (4 bits each).
+ uint32_t Constraints;
+ /// Currently no other information.
+
+ /// isLookupPtrRegClass - Set if this operand is a pointer value and it
+ /// requires a callback to look up its register class.
+ bool isLookupPtrRegClass() const {return Flags&(1 <<MCOI::LookupPtrRegClass);}
+
+ /// isPredicate - Set if this is one of the operands that made up of
+ /// the predicate operand that controls an isPredicable() instruction.
+ bool isPredicate() const { return Flags & (1 << MCOI::Predicate); }
+
+ /// isOptionalDef - Set if this operand is a optional def.
+ ///
+ bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Machine Instruction Flags and Description
+//===----------------------------------------------------------------------===//
+
+/// MCInstrDesc flags - These should be considered private to the
+/// implementation of the MCInstrDesc class. Clients should use the predicate
+/// methods on MCInstrDesc, not use these directly. These all correspond to
+/// bitfields in the MCInstrDesc::Flags field.
+namespace MCID {
+ enum {
+ Variadic = 0,
+ HasOptionalDef,
+ Pseudo,
+ Return,
+ Call,
+ Barrier,
+ Terminator,
+ Branch,
+ IndirectBranch,
+ Compare,
+ MoveImm,
+ Bitcast,
+ DelaySlot,
+ FoldableAsLoad,
+ MayLoad,
+ MayStore,
+ Predicable,
+ NotDuplicable,
+ UnmodeledSideEffects,
+ Commutable,
+ ConvertibleTo3Addr,
+ UsesCustomInserter,
+ HasPostISelHook,
+ Rematerializable,
+ CheapAsAMove,
+ ExtraSrcRegAllocReq,
+ ExtraDefRegAllocReq
+ };
+}
+
+/// MCInstrDesc - Describe properties that are true of each instruction in the
+/// target description file. This captures information about side effects,
+/// register use and many other things. There is one instance of this struct
+/// for each target instruction class, and the MachineInstr class points to
+/// this struct directly to describe itself.
+class MCInstrDesc {
+public:
+ unsigned short Opcode; // The opcode number
+ unsigned short NumOperands; // Num of args (may be more if variable_ops)
+ unsigned short NumDefs; // Num of args that are definitions
+ unsigned short SchedClass; // enum identifying instr sched class
+ unsigned short Size; // Number of bytes in encoding.
+ unsigned Flags; // Flags identifying machine instr class
+ uint64_t TSFlags; // Target Specific Flag values
+ const uint16_t *ImplicitUses; // Registers implicitly read by this instr
+ 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
+ /// it is set. Returns -1 if it is not set.
+ int getOperandConstraint(unsigned OpNum,
+ MCOI::OperandConstraint Constraint) const {
+ if (OpNum < NumOperands &&
+ (OpInfo[OpNum].Constraints & (1 << Constraint))) {
+ unsigned Pos = 16 + Constraint * 4;
+ return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
+ }
+ return -1;
+ }
+
+ /// getOpcode - Return the opcode number for this descriptor.
+ unsigned getOpcode() const {
+ return Opcode;
+ }
+
+ /// getNumOperands - 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
+ /// well.
+ unsigned getNumOperands() const {
+ return NumOperands;
+ }
+
+ /// getNumDefs - 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.
+ unsigned getNumDefs() const {
+ return NumDefs;
+ }
+
+ /// getFlags - Return flags of this instruction.
+ ///
+ unsigned getFlags() const { return Flags; }
+
+ /// isVariadic - 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).
+ bool isVariadic() const {
+ return Flags & (1 << MCID::Variadic);
+ }
+
+ /// hasOptionalDef - 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
+ /// correspond to a real machine instruction.
+ ///
+ bool isPseudo() const {
+ return Flags & (1 << MCID::Pseudo);
+ }
+
+ bool isReturn() const {
+ return Flags & (1 << MCID::Return);
+ }
+
+ bool isCall() const {
+ return Flags & (1 << MCID::Call);
+ }
+
+ /// isBarrier - 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
+ /// a basic block. Typically this is things like return and branch
+ /// instructions.
+ ///
+ /// Various passes use this to insert code into the bottom of a basic block,
+ /// but before control flow occurs.
+ bool isTerminator() const {
+ return Flags & (1 << MCID::Terminator);
+ }
+
+ /// isBranch - 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.
+ bool isBranch() const {
+ return Flags & (1 << MCID::Branch);
+ }
+
+ /// isIndirectBranch - 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
+ /// 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.
+ bool isConditionalBranch() const {
+ return isBranch() & !isBarrier() & !isIndirectBranch();
+ }
+
+ /// isUnconditionalBranch - 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.
+ bool isUnconditionalBranch() const {
+ 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
+ /// 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.
+ bool isCompare() const {
+ return Flags & (1 << MCID::Compare);
+ }
+
+ /// isMoveImmediate - 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.
+ ///
+ bool isBitcast() const {
+ return Flags & (1 << MCID::Bitcast);
+ }
+
+ /// isNotDuplicable - 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 {
+ return Flags & (1 << MCID::NotDuplicable);
+ }
+
+ /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+ /// which must be filled by the code generator.
+ bool hasDelaySlot() const {
+ return Flags & (1 << MCID::DelaySlot);
+ }
+
+ /// canFoldAsLoad - Return true for instructions that can be folded as
+ /// memory operands in other instructions. The most common use for this
+ /// is instructions that are simple loads from memory that don't modify
+ /// the loaded value in any way, but it can also be used for instructions
+ /// that can be expressed as constant-pool loads, such as V_SETALLONES
+ /// on x86, to allow them to be folded when it is beneficial.
+ /// This should only be set on instructions that return a value in their
+ /// only virtual register definition.
+ bool canFoldAsLoad() const {
+ return Flags & (1 << MCID::FoldableAsLoad);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Side Effect Analysis
+ //===--------------------------------------------------------------------===//
+
+ /// mayLoad - 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 {
+ return Flags & (1 << MCID::MayLoad);
+ }
+
+
+ /// mayStore - 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.
+ bool mayStore() const {
+ return Flags & (1 << MCID::MayStore);
+ }
+
+ /// hasUnmodeledSideEffects - Return true if this instruction has side
+ /// effects that are not modeled by other flags. This does not return true
+ /// for instructions whose effects are captured by:
+ ///
+ /// 1. Their operand list and implicit definition/use list. Register use/def
+ /// info is explicit for instructions.
+ /// 2. Memory accesses. Use mayLoad/mayStore.
+ /// 3. Calling, branching, returning: use isCall/isReturn/isBranch.
+ ///
+ /// Examples of side effects would be modifying 'invisible' machine state like
+ /// a control register, flushing a cache, modifying a register invisible to
+ /// LLVM, etc.
+ ///
+ bool hasUnmodeledSideEffects() const {
+ return Flags & (1 << MCID::UnmodeledSideEffects);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Flags that indicate whether an instruction can be modified by a method.
+ //===--------------------------------------------------------------------===//
+
+ /// isCommutable - Return true if this may be a 2- or 3-address
+ /// instruction (of the form "X = op Y, Z, ..."), which produces the same
+ /// result if Y and Z are exchanged. If this flag is set, then the
+ /// TargetInstrInfo::commuteInstruction method may be used to hack on the
+ /// instruction.
+ ///
+ /// Note that this flag may be set on instructions that are only commutable
+ /// sometimes. In these cases, the call to commuteInstruction will fail.
+ /// Also note that some instructions require non-trivial modification to
+ /// commute them.
+ bool isCommutable() const {
+ return Flags & (1 << MCID::Commutable);
+ }
+
+ /// isConvertibleTo3Addr - Return true if this is a 2-address instruction
+ /// which can be changed into a 3-address instruction if needed. Doing this
+ /// transformation can be profitable in the register allocator, because it
+ /// means that the instruction can use a 2-address form if possible, but
+ /// degrade into a less efficient form if the source and dest register cannot
+ /// be assigned to the same register. For example, this allows the x86
+ /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which
+ /// is the same speed as the shift but has bigger code size.
+ ///
+ /// If this returns true, then the target must implement the
+ /// TargetInstrInfo::convertToThreeAddress method for this instruction, which
+ /// is allowed to fail if the transformation isn't valid for this specific
+ /// instruction (e.g. shl reg, 4 on x86).
+ ///
+ bool isConvertibleTo3Addr() const {
+ return Flags & (1 << MCID::ConvertibleTo3Addr);
+ }
+
+ /// usesCustomInsertionHook - Return true if this instruction requires
+ /// custom insertion support when the DAG scheduler is inserting it into a
+ /// machine basic block. If this is true for the instruction, it basically
+ /// means that it is a pseudo instruction used at SelectionDAG time that is
+ /// expanded out into magic code by the target when MachineInstrs are formed.
+ ///
+ /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
+ /// is used to insert this into the MachineBasicBlock.
+ bool usesCustomInsertionHook() const {
+ return Flags & (1 << MCID::UsesCustomInserter);
+ }
+
+ /// hasPostISelHook - Return true if this instruction requires *adjustment*
+ /// after instruction selection by calling a target hook. For example, this
+ /// can be used to fill in ARM 's' optional operand depending on whether
+ /// the conditional flag register is used.
+ bool hasPostISelHook() const {
+ return Flags & (1 << MCID::HasPostISelHook);
+ }
+
+ /// isRematerializable - Returns true if this instruction is a candidate for
+ /// remat. This flag is deprecated, please don't use it anymore. If this
+ /// flag is set, the isReallyTriviallyReMaterializable() method is called to
+ /// verify the instruction is really rematable.
+ bool isRematerializable() const {
+ return Flags & (1 << MCID::Rematerializable);
+ }
+
+ /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
+ /// less) than a move instruction. This is useful during certain types of
+ /// optimizations (e.g., remat during two-address conversion or machine licm)
+ /// where we would like to remat or hoist the instruction, but not if it costs
+ /// more than moving the instruction into the appropriate register. Note, we
+ /// are not marking copies from and to the same register class with this flag.
+ bool isAsCheapAsAMove() const {
+ return Flags & (1 << MCID::CheapAsAMove);
+ }
+
+ /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::STRD's two source registers must be an
+ /// even / odd pair, ARM::STM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for sources of instructions with this flag.
+ bool hasExtraSrcRegAllocReq() const {
+ return Flags & (1 << MCID::ExtraSrcRegAllocReq);
+ }
+
+ /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+ /// even / odd pair, ARM::LDM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for definitions of instructions with this flag.
+ bool hasExtraDefRegAllocReq() const {
+ return Flags & (1 << MCID::ExtraDefRegAllocReq);
+ }
+
+
+ /// getImplicitUses - Return a list of registers that are potentially
+ /// read by any instance of this machine instruction. For example, on X86,
+ /// the "adc" instruction adds two register operands and adds the carry bit in
+ /// from the flags register. In this case, the instruction is marked as
+ /// implicitly reading the flags. Likewise, the variable shift instruction on
+ /// X86 is marked as implicitly reading the 'CL' register, which it always
+ /// does.
+ ///
+ /// This method returns null if the instruction has no implicit uses.
+ const uint16_t *getImplicitUses() const {
+ return ImplicitUses;
+ }
+
+ /// getNumImplicitUses - Return the number of implicit uses this instruction
+ /// has.
+ unsigned getNumImplicitUses() const {
+ if (ImplicitUses == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitUses[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// getImplicitDefs - Return a list of registers that are potentially
+ /// written by any instance of this machine instruction. For example, on X86,
+ /// many instructions implicitly set the flags register. In this case, they
+ /// are marked as setting the FLAGS. Likewise, many instructions always
+ /// deposit their result in a physical register. For example, the X86 divide
+ /// instruction always deposits the quotient and remainder in the EAX/EDX
+ /// registers. For that instruction, this will return a list containing the
+ /// EAX/EDX/EFLAGS registers.
+ ///
+ /// This method returns null if the instruction has no implicit defs.
+ const uint16_t *getImplicitDefs() const {
+ return ImplicitDefs;
+ }
+
+ /// getNumImplicitDefs - Return the number of implicit defs this instruction
+ /// has.
+ unsigned getNumImplicitDefs() const {
+ if (ImplicitDefs == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitDefs[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// uses the specified physical register.
+ bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+ if (const uint16_t *ImpUses = ImplicitUses)
+ for (; *ImpUses; ++ImpUses)
+ if (*ImpUses == Reg) return true;
+ return false;
+ }
+
+ /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// defines the specified physical register.
+ bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ if (const uint16_t *ImpDefs = ImplicitDefs)
+ for (; *ImpDefs; ++ImpDefs)
+ if (*ImpDefs == Reg) return true;
+ return false;
+ }
+
+ /// getSchedClass - 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,
+ /// 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
+ /// operand list that is used to represent the predicate. It returns -1 if
+ /// none is found.
+ int findFirstPredOperandIdx() const {
+ if (isPredicable()) {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (OpInfo[i].isPredicate())
+ return i;
+ }
+ return -1;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCInstrInfo.h b/contrib/llvm/include/llvm/MC/MCInstrInfo.h
new file mode 100644
index 000000000000..1d3a36ca7c73
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCInstrInfo.h
@@ -0,0 +1,62 @@
+//===-- llvm/MC/MCInstrInfo.h - Target Instruction 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 describes the target machine instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRINFO_H
+#define LLVM_MC_MCINSTRINFO_H
+
+#include "llvm/MC/MCInstrDesc.h"
+#include <cassert>
+
+namespace llvm {
+
+//---------------------------------------------------------------------------
+///
+/// MCInstrInfo - Interface to description of machine instruction set
+///
+class MCInstrInfo {
+ const MCInstrDesc *Desc; // Raw array to allow static init'n
+ const unsigned *InstrNameIndices; // Array for name indices in InstrNameData
+ const char *InstrNameData; // Instruction name string pool
+ unsigned NumOpcodes; // Number of entries in the desc array
+
+public:
+ /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND,
+ unsigned NO) {
+ Desc = D;
+ InstrNameIndices = NI;
+ InstrNameData = ND;
+ NumOpcodes = NO;
+ }
+
+ unsigned getNumOpcodes() const { return NumOpcodes; }
+
+ /// get - Return the machine instruction descriptor that corresponds to the
+ /// specified instruction opcode.
+ ///
+ const MCInstrDesc &get(unsigned Opcode) const {
+ assert(Opcode < NumOpcodes && "Invalid opcode!");
+ return Desc[Opcode];
+ }
+
+ /// getName - Returns the name for the instructions with the given opcode.
+ const char *getName(unsigned Opcode) const {
+ assert(Opcode < NumOpcodes && "Invalid opcode!");
+ return &InstrNameData[InstrNameIndices[Opcode]];
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCInstrItineraries.h b/contrib/llvm/include/llvm/MC/MCInstrItineraries.h
new file mode 100644
index 000000000000..e942892da13e
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCInstrItineraries.h
@@ -0,0 +1,253 @@
+//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the structures used for instruction
+// itineraries, stages, and operand reads/writes. This is used by
+// schedulers to determine instruction stages and latencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRITINERARIES_H
+#define LLVM_MC_MCINSTRITINERARIES_H
+
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// Instruction stage - These values represent a non-pipelined step in
+/// the execution of an instruction. Cycles represents the number of
+/// discrete time slots needed to complete the stage. Units represent
+/// the choice of functional units that can be used to complete the
+/// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+/// cycles should elapse from the start of this stage to the start of
+/// the next stage in the itinerary. A value of -1 indicates that the
+/// next stage should start immediately after the current one.
+/// For example:
+///
+/// { 1, x, -1 }
+/// indicates that the stage occupies FU x for 1 cycle and that
+/// the next stage starts immediately after this one.
+///
+/// { 2, x|y, 1 }
+/// indicates that the stage occupies either FU x or FU y for 2
+/// consecuative cycles and that the next stage starts one cycle
+/// after this stage starts. That is, the stage requirements
+/// overlap in time.
+///
+/// { 1, x, 0 }
+/// indicates that the stage occupies FU x for 1 cycle and that
+/// the next stage starts in this same cycle. This can be used to
+/// indicate that the instruction requires multiple stages at the
+/// same time.
+///
+/// FU reservation can be of two different kinds:
+/// - FUs which instruction actually requires
+/// - FUs which instruction just reserves. Reserved unit is not available for
+/// execution of other instruction. However, several instructions can reserve
+/// the same unit several times.
+/// Such two types of units reservation is used to model instruction domain
+/// change stalls, FUs using the same resource (e.g. same register file), etc.
+
+struct InstrStage {
+ enum ReservationKinds {
+ Required = 0,
+ Reserved = 1
+ };
+
+ unsigned Cycles_; ///< Length of stage in machine cycles
+ unsigned Units_; ///< Choice of functional units
+ int NextCycles_; ///< Number of machine cycles to next stage
+ ReservationKinds Kind_; ///< Kind of the FU reservation
+
+ /// getCycles - returns the number of cycles the stage is occupied
+ unsigned getCycles() const {
+ return Cycles_;
+ }
+
+ /// getUnits - returns the choice of FUs
+ unsigned getUnits() const {
+ return Units_;
+ }
+
+ ReservationKinds getReservationKind() const {
+ return Kind_;
+ }
+
+ /// getNextCycles - returns the number of cycles from the start of
+ /// this stage to the start of the next stage in the itinerary
+ unsigned getNextCycles() const {
+ return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary - An itinerary represents the scheduling
+/// information for an instruction. This includes a set of stages
+/// occupies by the instruction, and the pipeline cycle in which
+/// operands are read and written.
+///
+struct InstrItinerary {
+ unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable
+ unsigned FirstStage; ///< Index of first stage in itinerary
+ unsigned LastStage; ///< Index of last + 1 stage in itinerary
+ unsigned FirstOperandCycle; ///< Index of first operand rd/wr
+ unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr
+};
+
+
+//===----------------------------------------------------------------------===//
+/// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
+/// used by a target.
+///
+class InstrItineraryData {
+public:
+ const InstrStage *Stages; ///< Array of stages selected
+ const unsigned *OperandCycles; ///< Array of operand cycles selected
+ const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
+ const InstrItinerary *Itineraries; ///< Array of itineraries selected
+ unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
+
+ /// Ctors.
+ ///
+ InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
+ Itineraries(0), IssueWidth(0) {}
+
+ InstrItineraryData(const InstrStage *S, const unsigned *OS,
+ const unsigned *F, const InstrItinerary *I)
+ : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
+ IssueWidth(0) {}
+
+ /// isEmpty - Returns true if there are no itineraries.
+ ///
+ bool isEmpty() const { return Itineraries == 0; }
+
+ /// isEndMarker - Returns true if the index is for the end marker
+ /// itinerary.
+ ///
+ bool isEndMarker(unsigned ItinClassIndx) const {
+ return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
+ (Itineraries[ItinClassIndx].LastStage == ~0U));
+ }
+
+ /// beginStage - Return the first stage of the itinerary.
+ ///
+ const InstrStage *beginStage(unsigned ItinClassIndx) const {
+ unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
+ return Stages + StageIdx;
+ }
+
+ /// endStage - Return the last+1 stage of the itinerary.
+ ///
+ const InstrStage *endStage(unsigned ItinClassIndx) const {
+ unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
+ return Stages + StageIdx;
+ }
+
+ /// getStageLatency - Return the total stage latency of the given
+ /// class. The latency is the maximum completion time for any stage
+ /// in the itinerary.
+ ///
+ unsigned getStageLatency(unsigned ItinClassIndx) const {
+ // If the target doesn't provide itinerary information, use a simple
+ // non-zero default value for all instructions. Some target's provide a
+ // dummy (Generic) itinerary which should be handled as if it's itinerary is
+ // empty. We identify this by looking for a reference to stage zero (invalid
+ // stage). This is different from beginStage == endState != 0, which could
+ // be used for zero-latency pseudo ops.
+ if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
+ return 1;
+
+ // Calculate the maximum completion time for any stage.
+ unsigned Latency = 0, StartCycle = 0;
+ for (const InstrStage *IS = beginStage(ItinClassIndx),
+ *E = endStage(ItinClassIndx); IS != E; ++IS) {
+ Latency = std::max(Latency, StartCycle + IS->getCycles());
+ StartCycle += IS->getNextCycles();
+ }
+
+ return Latency;
+ }
+
+ /// getOperandCycle - Return the cycle for the given class and
+ /// operand. Return -1 if no cycle is specified for the operand.
+ ///
+ int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
+ if (isEmpty())
+ return -1;
+
+ unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
+ unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
+ if ((FirstIdx + OperandIdx) >= LastIdx)
+ return -1;
+
+ return (int)OperandCycles[FirstIdx + OperandIdx];
+ }
+
+ /// hasPipelineForwarding - Return true if there is a pipeline forwarding
+ /// between instructions of itinerary classes DefClass and UseClasses so that
+ /// value produced by an instruction of itinerary class DefClass, operand
+ /// index DefIdx can be bypassed when it's read by an instruction of
+ /// itinerary class UseClass, operand index UseIdx.
+ bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
+ unsigned UseClass, unsigned UseIdx) const {
+ unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
+ unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
+ if ((FirstDefIdx + DefIdx) >= LastDefIdx)
+ return false;
+ if (Forwardings[FirstDefIdx + DefIdx] == 0)
+ return false;
+
+ unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
+ unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
+ if ((FirstUseIdx + UseIdx) >= LastUseIdx)
+ return false;
+
+ return Forwardings[FirstDefIdx + DefIdx] ==
+ Forwardings[FirstUseIdx + UseIdx];
+ }
+
+ /// getOperandLatency - Compute and return the use operand latency of a given
+ /// itinerary class and operand index if the value is produced by an
+ /// instruction of the specified itinerary class and def operand index.
+ int getOperandLatency(unsigned DefClass, unsigned DefIdx,
+ unsigned UseClass, unsigned UseIdx) const {
+ if (isEmpty())
+ return -1;
+
+ int DefCycle = getOperandCycle(DefClass, DefIdx);
+ if (DefCycle == -1)
+ return -1;
+
+ int UseCycle = getOperandCycle(UseClass, UseIdx);
+ if (UseCycle == -1)
+ return -1;
+
+ UseCycle = DefCycle - UseCycle + 1;
+ if (UseCycle > 0 &&
+ hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
+ // FIXME: This assumes one cycle benefit for every pipeline forwarding.
+ --UseCycle;
+ return UseCycle;
+ }
+
+ /// isMicroCoded - Return true if the instructions in the given class decode
+ /// to more than one micro-ops.
+ bool isMicroCoded(unsigned ItinClassIndx) const {
+ if (isEmpty())
+ return false;
+ return Itineraries[ItinClassIndx].NumMicroOps != 1;
+ }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCLabel.h b/contrib/llvm/include/llvm/MC/MCLabel.h
new file mode 100644
index 000000000000..727520d4af9d
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCLabel.h
@@ -0,0 +1,56 @@
+//===- MCLabel.h - Machine Code Directional Local Labels --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCLabel class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLABEL_H
+#define LLVM_MC_MCLABEL_H
+
+namespace llvm {
+ class MCContext;
+ class raw_ostream;
+
+ /// MCLabel - Instances of this class represent a label name in the MC file,
+ /// and MCLabel are created and unique'd by the MCContext class. MCLabel
+ /// should only be constructed for valid instances in the object file.
+ class MCLabel {
+ // Instance - the instance number of this Directional Local Label
+ unsigned Instance;
+
+ private: // MCContext creates and uniques these.
+ friend class MCContext;
+ MCLabel(unsigned instance)
+ : Instance(instance) {}
+
+ MCLabel(const MCLabel&); // DO NOT IMPLEMENT
+ void operator=(const MCLabel&); // DO NOT IMPLEMENT
+ public:
+ /// getInstance - Get the current instance of this Directional Local Label.
+ unsigned getInstance() const { return Instance; }
+
+ /// incInstance - Increment the current instance of this Directional Local
+ /// Label.
+ unsigned incInstance() { return ++Instance; }
+
+ /// print - Print the value to the stream \arg OS.
+ void print(raw_ostream &OS) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const MCLabel &Label) {
+ Label.print(OS);
+ return OS;
+ }
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h b/contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h
new file mode 100644
index 000000000000..696436dffa6e
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCMachOSymbolFlags.h
@@ -0,0 +1,46 @@
+//===- MCMachOSymbolFlags.h - MachO Symbol Flags ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolFlags used for the MachO target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMACHOSYMBOLFLAGS_H
+#define LLVM_MC_MCMACHOSYMBOLFLAGS_H
+
+// These flags are mostly used in MCMachOStreamer.cpp but also needed in
+// MachObjectWriter.cpp to test for Weak Definitions of symbols to emit
+// the correct relocation information.
+
+namespace llvm {
+ /// SymbolFlags - We store the value for the 'desc' symbol field in the lowest
+ /// 16 bits of the implementation defined flags.
+ enum SymbolFlags { // See <mach-o/nlist.h>.
+ SF_DescFlagsMask = 0xFFFF,
+
+ // Reference type flags.
+ SF_ReferenceTypeMask = 0x0007,
+ SF_ReferenceTypeUndefinedNonLazy = 0x0000,
+ SF_ReferenceTypeUndefinedLazy = 0x0001,
+ SF_ReferenceTypeDefined = 0x0002,
+ SF_ReferenceTypePrivateDefined = 0x0003,
+ SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
+ SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
+
+ // Other 'desc' flags.
+ SF_ThumbFunc = 0x0008,
+ SF_NoDeadStrip = 0x0020,
+ SF_WeakReference = 0x0040,
+ SF_WeakDefinition = 0x0080,
+ SF_SymbolResolver = 0x0100
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h
new file mode 100644
index 000000000000..9bb598f5468a
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCMachObjectWriter.h
@@ -0,0 +1,257 @@
+//===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- 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_MCMACHOBJECTWRITER_H
+#define LLVM_MC_MCMACHOBJECTWRITER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Object/MachOFormat.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MCSectionData;
+class MachObjectWriter;
+
+class MCMachObjectTargetWriter {
+ const unsigned Is64Bit : 1;
+ const uint32_t CPUType;
+ const uint32_t CPUSubtype;
+ // FIXME: Remove this, we should just always use it once we no longer care
+ // about Darwin 'as' compatibility.
+ const unsigned UseAggressiveSymbolFolding : 1;
+ unsigned LocalDifference_RIT;
+
+protected:
+ MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
+ uint32_t CPUSubtype_,
+ bool UseAggressiveSymbolFolding_ = false);
+
+ void setLocalDifferenceRelocationType(unsigned Type) {
+ LocalDifference_RIT = Type;
+ }
+
+public:
+ virtual ~MCMachObjectTargetWriter();
+
+ /// @name Accessors
+ /// @{
+
+ bool is64Bit() const { return Is64Bit; }
+ bool useAggressiveSymbolFolding() const { return UseAggressiveSymbolFolding; }
+ uint32_t getCPUType() const { return CPUType; }
+ uint32_t getCPUSubtype() const { return CPUSubtype; }
+ unsigned getLocalDifferenceRelocationType() const {
+ return LocalDifference_RIT;
+ }
+
+ /// @}
+
+ /// @name API
+ /// @{
+
+ virtual void RecordRelocation(MachObjectWriter *Writer,
+ const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup,
+ MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// @}
+};
+
+class MachObjectWriter : public MCObjectWriter {
+ /// MachSymbolData - Helper struct for containing some precomputed information
+ /// on symbols.
+ struct MachSymbolData {
+ MCSymbolData *SymbolData;
+ uint64_t StringIndex;
+ uint8_t SectionIndex;
+
+ // Support lexicographic sorting.
+ bool operator<(const MachSymbolData &RHS) const;
+ };
+
+ /// The target specific Mach-O writer instance.
+ llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter;
+
+ /// @name Relocation Data
+ /// @{
+
+ llvm::DenseMap<const MCSectionData*,
+ std::vector<object::macho::RelocationEntry> > Relocations;
+ llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
+
+ /// @}
+ /// @name Symbol Table Data
+ /// @{
+
+ SmallString<256> StringTable;
+ std::vector<MachSymbolData> LocalSymbolData;
+ std::vector<MachSymbolData> ExternalSymbolData;
+ std::vector<MachSymbolData> UndefinedSymbolData;
+
+ /// @}
+
+public:
+ MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
+ bool _IsLittleEndian)
+ : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
+ }
+
+ /// @name Utility Methods
+ /// @{
+
+ bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+
+ SectionAddrMap SectionAddress;
+
+ SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
+
+ uint64_t getSectionAddress(const MCSectionData* SD) const {
+ return SectionAddress.lookup(SD);
+ }
+ uint64_t getSymbolAddress(const MCSymbolData* SD,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getFragmentAddress(const MCFragment *Fragment,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getPaddingSize(const MCSectionData *SD,
+ const MCAsmLayout &Layout) const;
+
+ bool doesSymbolRequireExternRelocation(const MCSymbolData *SD);
+
+ /// @}
+
+ /// @name Target Writer Proxy Accessors
+ /// @{
+
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool isARM() const {
+ uint32_t CPUType = TargetObjectWriter->getCPUType() &
+ ~object::mach::CTFM_ArchMask;
+ return CPUType == object::mach::CTM_ARM;
+ }
+
+ /// @}
+
+ void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
+ bool SubsectionsViaSymbols);
+
+ /// WriteSegmentLoadCommand - Write a segment load command.
+ ///
+ /// \arg NumSections - The number of sections in this segment.
+ /// \arg SectionDataSize - The total size of the sections.
+ void WriteSegmentLoadCommand(unsigned NumSections,
+ uint64_t VMSize,
+ uint64_t SectionDataStartOffset,
+ uint64_t SectionDataSize);
+
+ void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCSectionData &SD, uint64_t FileOffset,
+ uint64_t RelocationsStart, unsigned NumRelocations);
+
+ void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
+ uint32_t StringTableOffset,
+ uint32_t StringTableSize);
+
+ void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
+ uint32_t NumLocalSymbols,
+ uint32_t FirstExternalSymbol,
+ uint32_t NumExternalSymbols,
+ uint32_t FirstUndefinedSymbol,
+ uint32_t NumUndefinedSymbols,
+ uint32_t IndirectSymbolOffset,
+ uint32_t NumIndirectSymbols);
+
+ void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+
+ // FIXME: We really need to improve the relocation validation. Basically, we
+ // want to implement a separate computation which evaluates the relocation
+ // entry as the linker would, and verifies that the resultant fixup value is
+ // exactly what the encoder wanted. This will catch several classes of
+ // problems:
+ //
+ // - Relocation entry bugs, the two algorithms are unlikely to have the same
+ // exact bug.
+ //
+ // - Relaxation issues, where we forget to relax something.
+ //
+ // - Input errors, where something cannot be correctly encoded. 'as' allows
+ // these through in many cases.
+
+ void addRelocation(const MCSectionData *SD,
+ object::macho::RelocationEntry &MRE) {
+ Relocations[SD].push_back(MRE);
+ }
+
+ void RecordScatteredRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ unsigned Log2Size,
+ uint64_t &FixedValue);
+
+ void RecordTLVPRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue);
+
+ void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
+
+ void BindIndirectSymbols(MCAssembler &Asm);
+
+ /// 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,
+ std::vector<MachSymbolData> &UndefinedSymbolData);
+
+ void computeSectionAddresses(const MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
+
+ virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+};
+
+
+/// \brief Construct a new Mach-O writer instance.
+///
+/// This routine takes ownership of the target writer subclass.
+///
+/// \param MOTW - The target specific Mach-O writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
+ raw_ostream &OS, bool IsLittleEndian);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCModule.h b/contrib/llvm/include/llvm/MC/MCModule.h
new file mode 100644
index 000000000000..755fa025fbc7
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCModule.h
@@ -0,0 +1,58 @@
+//===-- llvm/MC/MCModule.h - MCModule class ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCModule class, which is used to
+// represent a complete, disassembled object file or executable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCMODULE_H
+#define LLVM_MC_MCMODULE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class MCAtom;
+
+/// MCModule - This class represent a completely disassembled object file or
+/// executable. It comprises a list of MCAtom's, and a branch target table.
+/// Each atom represents a contiguous range of either instructions or data.
+class MCModule {
+ /// AtomAllocationTracker - An MCModule owns its component MCAtom's, so it
+ /// must track them in order to ensure they are properly freed as atoms are
+ /// merged or otherwise manipulated.
+ SmallPtrSet<MCAtom*, 8> AtomAllocationTracker;
+
+ /// OffsetMap - Efficiently maps offset ranges to MCAtom's.
+ IntervalMap<uint64_t, MCAtom*> OffsetMap;
+
+ /// BranchTargetMap - Maps offsets that are determined to be branches and
+ /// can be statically resolved to their target offsets.
+ DenseMap<uint64_t, MCAtom*> BranchTargetMap;
+
+ friend class MCAtom;
+
+ /// remap - Update the interval mapping for an MCAtom.
+ void remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd);
+
+public:
+ MCModule(IntervalMap<uint64_t, MCAtom*>::Allocator &A) : OffsetMap(A) { }
+
+ /// createAtom - Creates a new MCAtom covering the specified offset range.
+ MCAtom *createAtom(MCAtom::AtomType Type, uint64_t Begin, uint64_t End);
+};
+
+}
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h
new file mode 100644
index 000000000000..aea4b410fea2
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -0,0 +1,312 @@
+//===-- llvm/MC/MCObjectFileInfo.h - Object File 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 describes common object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCBJECTFILEINFO_H
+#define LLVM_MC_MCBJECTFILEINFO_H
+
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+ class MCContext;
+ class MCSection;
+ class StringRef;
+ class Triple;
+
+class MCObjectFileInfo {
+protected:
+ /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This
+ /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't
+ /// support alignment on comm.
+ bool CommDirectiveSupportsAlignment;
+
+ /// SupportsWeakEmptyEHFrame - True if target object file supports a
+ /// weak_definition of constant 0 for an omitted EH frame.
+ bool SupportsWeakOmittedEHFrame;
+
+ /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the
+ /// "EH_frame" symbol for EH information should be an assembler temporary (aka
+ /// private linkage, aka an L or .L label) or false if it should be a normal
+ /// non-.globl label. This defaults to true.
+ bool IsFunctionEHFrameSymbolPrivate;
+
+ /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some
+ /// encoding values for EH.
+ unsigned PersonalityEncoding;
+ unsigned LSDAEncoding;
+ unsigned FDEEncoding;
+ unsigned FDECFIEncoding;
+ unsigned TTypeEncoding;
+ // Section flags for eh_frame
+ unsigned EHSectionType;
+ unsigned EHSectionFlags;
+
+ /// TextSection - Section directive for standard text.
+ ///
+ const MCSection *TextSection;
+
+ /// DataSection - Section directive for standard data.
+ ///
+ const MCSection *DataSection;
+
+ /// BSSSection - Section that is default initialized to zero.
+ const MCSection *BSSSection;
+
+ /// ReadOnlySection - Section that is readonly and can contain arbitrary
+ /// initialized data. Targets are not required to have a readonly section.
+ /// If they don't, various bits of code will fall back to using the data
+ /// section for constants.
+ const MCSection *ReadOnlySection;
+
+ /// StaticCtorSection - This section contains the static constructor pointer
+ /// list.
+ const MCSection *StaticCtorSection;
+
+ /// StaticDtorSection - This section contains the static destructor pointer
+ /// list.
+ const MCSection *StaticDtorSection;
+
+ /// LSDASection - If exception handling is supported by the target, this is
+ /// the section the Language Specific Data Area information is emitted to.
+ const MCSection *LSDASection;
+
+ /// CompactUnwindSection - If exception handling is supported by the target
+ /// and the target can support a compact representation of the CIE and FDE,
+ /// 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;
+ const MCSection *DwarfInfoSection;
+ const MCSection *DwarfLineSection;
+ const MCSection *DwarfFrameSection;
+ const MCSection *DwarfPubTypesSection;
+ const MCSection *DwarfDebugInlineSection;
+ const MCSection *DwarfStrSection;
+ const MCSection *DwarfLocSection;
+ const MCSection *DwarfARangesSection;
+ const MCSection *DwarfRangesSection;
+ const MCSection *DwarfMacroInfoSection;
+
+ // Extra TLS Variable Data section. If the target needs to put additional
+ // information for a TLS variable, it'll go here.
+ const MCSection *TLSExtraDataSection;
+
+ /// TLSDataSection - Section directive for Thread Local data.
+ /// ELF, MachO and COFF.
+ const MCSection *TLSDataSection; // Defaults to ".tdata".
+
+ /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+ /// Null if this target doesn't support a BSS section.
+ /// ELF and MachO only.
+ const MCSection *TLSBSSSection; // Defaults to ".tbss".
+
+
+ /// EHFrameSection - EH frame section. It is initialized on demand so it
+ /// can be overwritten (with uniquing).
+ const MCSection *EHFrameSection;
+
+ /// ELF specific sections.
+ ///
+ const MCSection *DataRelSection;
+ const MCSection *DataRelLocalSection;
+ const MCSection *DataRelROSection;
+ const MCSection *DataRelROLocalSection;
+ const MCSection *MergeableConst4Section;
+ const MCSection *MergeableConst8Section;
+ const MCSection *MergeableConst16Section;
+
+ /// MachO specific sections.
+ ///
+
+ /// TLSTLVSection - Section for thread local structure information.
+ /// Contains the source code name of the variable, visibility and a pointer
+ /// to the initial value (.tdata or .tbss).
+ const MCSection *TLSTLVSection; // Defaults to ".tlv".
+
+ /// TLSThreadInitSection - Section for thread local data initialization
+ /// functions.
+ const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func".
+
+ const MCSection *CStringSection;
+ const MCSection *UStringSection;
+ const MCSection *TextCoalSection;
+ const MCSection *ConstTextCoalSection;
+ const MCSection *ConstDataSection;
+ const MCSection *DataCoalSection;
+ const MCSection *DataCommonSection;
+ const MCSection *DataBSSSection;
+ const MCSection *FourByteConstantSection;
+ const MCSection *EightByteConstantSection;
+ const MCSection *SixteenByteConstantSection;
+ const MCSection *LazySymbolPointerSection;
+ const MCSection *NonLazySymbolPointerSection;
+
+ /// COFF specific sections.
+ ///
+ const MCSection *DrectveSection;
+ const MCSection *PDataSection;
+ const MCSection *XDataSection;
+
+public:
+ void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM,
+ MCContext &ctx);
+
+ bool isFunctionEHFrameSymbolPrivate() const {
+ return IsFunctionEHFrameSymbolPrivate;
+ }
+ bool getSupportsWeakOmittedEHFrame() const {
+ return SupportsWeakOmittedEHFrame;
+ }
+ bool getCommDirectiveSupportsAlignment() const {
+ return CommDirectiveSupportsAlignment;
+ }
+
+ unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
+ unsigned getLSDAEncoding() const { return LSDAEncoding; }
+ unsigned getFDEEncoding(bool CFI) const {
+ return CFI ? FDECFIEncoding : FDEEncoding;
+ }
+ unsigned getTTypeEncoding() const { return TTypeEncoding; }
+
+ const MCSection *getTextSection() const { return TextSection; }
+ const MCSection *getDataSection() const { return DataSection; }
+ const MCSection *getBSSSection() const { return BSSSection; }
+ const MCSection *getLSDASection() const { return LSDASection; }
+ 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; }
+ const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+ const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}
+ const MCSection *getDwarfDebugInlineSection() const {
+ return DwarfDebugInlineSection;
+ }
+ const MCSection *getDwarfStrSection() const { return DwarfStrSection; }
+ const MCSection *getDwarfLocSection() const { return DwarfLocSection; }
+ const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;}
+ const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
+ const MCSection *getDwarfMacroInfoSection() const {
+ return DwarfMacroInfoSection;
+ }
+ const MCSection *getTLSExtraDataSection() const {
+ return TLSExtraDataSection;
+ }
+ const MCSection *getTLSDataSection() const { return TLSDataSection; }
+ const MCSection *getTLSBSSSection() const { return TLSBSSSection; }
+
+ /// ELF specific sections.
+ ///
+ const MCSection *getDataRelSection() const { return DataRelSection; }
+ const MCSection *getDataRelLocalSection() const {
+ return DataRelLocalSection;
+ }
+ const MCSection *getDataRelROSection() const { return DataRelROSection; }
+ const MCSection *getDataRelROLocalSection() const {
+ return DataRelROLocalSection;
+ }
+ const MCSection *getMergeableConst4Section() const {
+ return MergeableConst4Section;
+ }
+ const MCSection *getMergeableConst8Section() const {
+ return MergeableConst8Section;
+ }
+ const MCSection *getMergeableConst16Section() const {
+ return MergeableConst16Section;
+ }
+
+ /// MachO specific sections.
+ ///
+ const MCSection *getTLSTLVSection() const { return TLSTLVSection; }
+ const MCSection *getTLSThreadInitSection() const {
+ return TLSThreadInitSection;
+ }
+ const MCSection *getCStringSection() const { return CStringSection; }
+ const MCSection *getUStringSection() const { return UStringSection; }
+ const MCSection *getTextCoalSection() const { return TextCoalSection; }
+ const MCSection *getConstTextCoalSection() const {
+ return ConstTextCoalSection;
+ }
+ const MCSection *getConstDataSection() const { return ConstDataSection; }
+ const MCSection *getDataCoalSection() const { return DataCoalSection; }
+ const MCSection *getDataCommonSection() const { return DataCommonSection; }
+ const MCSection *getDataBSSSection() const { return DataBSSSection; }
+ const MCSection *getFourByteConstantSection() const {
+ return FourByteConstantSection;
+ }
+ const MCSection *getEightByteConstantSection() const {
+ return EightByteConstantSection;
+ }
+ const MCSection *getSixteenByteConstantSection() const {
+ return SixteenByteConstantSection;
+ }
+ const MCSection *getLazySymbolPointerSection() const {
+ return LazySymbolPointerSection;
+ }
+ const MCSection *getNonLazySymbolPointerSection() const {
+ return NonLazySymbolPointerSection;
+ }
+
+ /// COFF specific sections.
+ ///
+ const MCSection *getDrectveSection() const { return DrectveSection; }
+ const MCSection *getPDataSection() const { return PDataSection; }
+ const MCSection *getXDataSection() const { return XDataSection; }
+
+ const MCSection *getEHFrameSection() {
+ if (!EHFrameSection)
+ InitEHFrameSection();
+ return EHFrameSection;
+ }
+
+private:
+ enum Environment { IsMachO, IsELF, IsCOFF };
+ Environment Env;
+ Reloc::Model RelocM;
+ CodeModel::Model CMModel;
+ MCContext *Ctx;
+
+ void InitMachOMCObjectFileInfo(Triple T);
+ void InitELFMCObjectFileInfo(Triple T);
+ void InitCOFFMCObjectFileInfo(Triple T);
+
+ /// InitEHFrameSection - Initialize EHFrameSection on demand.
+ ///
+ void InitEHFrameSection();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCObjectStreamer.h b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h
new file mode 100644
index 000000000000..a69075ddd002
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -0,0 +1,90 @@
+//===- MCObjectStreamer.h - MCStreamer 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_MCOBJECTSTREAMER_H
+#define LLVM_MC_MCOBJECTSTREAMER_H
+
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+class MCAssembler;
+class MCCodeEmitter;
+class MCSectionData;
+class MCExpr;
+class MCFragment;
+class MCDataFragment;
+class MCAsmBackend;
+class raw_ostream;
+
+/// \brief Streaming object file generation interface.
+///
+/// This class provides an implementation of the MCStreamer interface which is
+/// suitable for use with the assembler backend. Specific object file formats
+/// are expected to subclass this interface to implement directives specific
+/// to that file format or custom semantics expected by the object writer
+/// implementation.
+class MCObjectStreamer : public MCStreamer {
+ MCAssembler *Assembler;
+ MCSectionData *CurSectionData;
+
+ virtual void EmitInstToData(const MCInst &Inst) = 0;
+ virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
+ virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
+
+protected:
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &_OS, MCCodeEmitter *_Emitter);
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &_OS, MCCodeEmitter *_Emitter,
+ MCAssembler *_Assembler);
+ ~MCObjectStreamer();
+
+ MCSectionData *getCurrentSectionData() const {
+ return CurSectionData;
+ }
+
+ MCFragment *getCurrentFragment() const;
+
+ /// Get a data fragment to write into, creating a new one if the current
+ /// fragment is not a data fragment.
+ MCDataFragment *getOrCreateDataFragment() const;
+
+ const MCExpr *AddValueSymbols(const MCExpr *Value);
+
+public:
+ MCAssembler &getAssembler() { return *Assembler; }
+
+ /// @name MCStreamer Interface
+ /// @{
+
+ virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace);
+ virtual void EmitULEB128Value(const MCExpr *Value);
+ virtual void EmitSLEB128Value(const MCExpr *Value);
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+ virtual void ChangeSection(const MCSection *Section);
+ virtual void EmitInstruction(const MCInst &Inst);
+ virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize);
+ virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label);
+ virtual void EmitGPRel32Value(const MCExpr *Value);
+ virtual void FinishImpl();
+
+ /// @}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCObjectWriter.h b/contrib/llvm/include/llvm/MC/MCObjectWriter.h
new file mode 100644
index 000000000000..6e44e6ceffa3
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCObjectWriter.h
@@ -0,0 +1,194 @@
+//===-- llvm/MC/MCObjectWriter.h - Object File Writer 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_MCOBJECTWRITER_H
+#define LLVM_MC_MCOBJECTWRITER_H
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class MCAsmLayout;
+class MCAssembler;
+class MCFixup;
+class MCFragment;
+class MCSymbolData;
+class MCSymbolRefExpr;
+class MCValue;
+
+/// MCObjectWriter - Defines the object file and target independent interfaces
+/// used by the assembler backend to write native file format object files.
+///
+/// The object writer contains a few callbacks used by the assembler to allow
+/// the object writer to modify the assembler data structures at appropriate
+/// points. Once assembly is complete, the object writer is given the
+/// MCAssembler instance, which contains all the symbol and section data which
+/// should be emitted as part of WriteObject().
+///
+/// The object writer also contains a number of helper methods for writing
+/// binary data to the output stream.
+class MCObjectWriter {
+ MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT
+ void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT
+
+protected:
+ raw_ostream &OS;
+
+ unsigned IsLittleEndian : 1;
+
+protected: // Can only create subclasses.
+ MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
+ : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
+
+public:
+ virtual ~MCObjectWriter();
+
+ bool isLittleEndian() const { return IsLittleEndian; }
+
+ raw_ostream &getStream() { return OS; }
+
+ /// @name High-Level API
+ /// @{
+
+ /// Perform any late binding of symbols (for example, to assign symbol indices
+ /// for use when generating relocations).
+ ///
+ /// This routine is called by the assembler after layout and relaxation is
+ /// complete.
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) = 0;
+
+ /// Record a relocation entry.
+ ///
+ /// This routine is called by the assembler after layout and relaxation, and
+ /// post layout binding. The implementation is responsible for storing
+ /// information about the relocation so that it can be emitted during
+ /// WriteObject().
+ virtual void RecordRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// \brief Check whether the difference (A - B) between two symbol
+ /// references is fully resolved.
+ ///
+ /// Clients are not required to answer precisely and may conservatively return
+ /// false, even when a difference is fully resolved.
+ bool
+ IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+ const MCSymbolRefExpr *A,
+ const MCSymbolRefExpr *B,
+ bool InSet) const;
+
+ virtual bool
+ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+
+ /// Write the object file.
+ ///
+ /// This routine is called by the assembler after layout and relaxation is
+ /// complete, fixups have been evaluated and applied, and relocations
+ /// generated.
+ virtual void WriteObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) = 0;
+
+ /// @}
+ /// @name Binary Output
+ /// @{
+
+ void Write8(uint8_t Value) {
+ OS << char(Value);
+ }
+
+ void WriteLE16(uint16_t Value) {
+ Write8(uint8_t(Value >> 0));
+ Write8(uint8_t(Value >> 8));
+ }
+
+ void WriteLE32(uint32_t Value) {
+ WriteLE16(uint16_t(Value >> 0));
+ WriteLE16(uint16_t(Value >> 16));
+ }
+
+ void WriteLE64(uint64_t Value) {
+ WriteLE32(uint32_t(Value >> 0));
+ WriteLE32(uint32_t(Value >> 32));
+ }
+
+ void WriteBE16(uint16_t Value) {
+ Write8(uint8_t(Value >> 8));
+ Write8(uint8_t(Value >> 0));
+ }
+
+ void WriteBE32(uint32_t Value) {
+ WriteBE16(uint16_t(Value >> 16));
+ WriteBE16(uint16_t(Value >> 0));
+ }
+
+ void WriteBE64(uint64_t Value) {
+ WriteBE32(uint32_t(Value >> 32));
+ WriteBE32(uint32_t(Value >> 0));
+ }
+
+ void Write16(uint16_t Value) {
+ if (IsLittleEndian)
+ WriteLE16(Value);
+ else
+ WriteBE16(Value);
+ }
+
+ void Write32(uint32_t Value) {
+ if (IsLittleEndian)
+ WriteLE32(Value);
+ else
+ WriteBE32(Value);
+ }
+
+ void Write64(uint64_t Value) {
+ if (IsLittleEndian)
+ WriteLE64(Value);
+ else
+ WriteBE64(Value);
+ }
+
+ void WriteZeros(unsigned N) {
+ const char Zeros[16] = { 0 };
+
+ for (unsigned i = 0, e = N / 16; i != e; ++i)
+ OS << StringRef(Zeros, 16);
+
+ OS << StringRef(Zeros, N % 16);
+ }
+
+ void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+ assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
+ "data size greater than fill size, unexpected large write will occur");
+ OS << Str;
+ if (ZeroFillSize)
+ WriteZeros(ZeroFillSize - Str.size());
+ }
+
+ /// @}
+
+ /// Utility function to encode a SLEB128 value.
+ static void EncodeSLEB128(int64_t Value, raw_ostream &OS);
+ /// Utility function to encode a ULEB128 value.
+ static void EncodeULEB128(uint64_t Value, raw_ostream &OS,
+ unsigned Padding = 0);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h b/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h
new file mode 100644
index 000000000000..92a115eb8038
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCParser/AsmCond.h
@@ -0,0 +1,40 @@
+//===- AsmCond.h - Assembly file conditional assembly ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMCOND_H
+#define ASMCOND_H
+
+namespace llvm {
+
+/// AsmCond - Class to support conditional assembly
+///
+/// The conditional assembly feature (.if, .else, .elseif and .endif) is
+/// implemented with AsmCond that tells us what we are in the middle of
+/// processing. Ignore can be either true or false. When true we are ignoring
+/// the block of code in the middle of a conditional.
+
+class AsmCond {
+public:
+ enum ConditionalAssemblyType {
+ NoCond, // no conditional is being processed
+ IfCond, // inside if conditional
+ ElseIfCond, // inside elseif conditional
+ ElseCond // inside else conditional
+ };
+
+ ConditionalAssemblyType TheCond;
+ bool CondMet;
+ bool Ignore;
+
+ AsmCond() : TheCond(NoCond), CondMet(false), Ignore(false) {}
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h
new file mode 100644
index 000000000000..9a8735f3e726
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCParser/AsmLexer.h
@@ -0,0 +1,70 @@
+//===- AsmLexer.h - Lexer for Assembly Files --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class declares the lexer for assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASMLEXER_H
+#define ASMLEXER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+class MemoryBuffer;
+class MCAsmInfo;
+
+/// AsmLexer - Lexer class for assembly files.
+class AsmLexer : public MCAsmLexer {
+ const MCAsmInfo &MAI;
+
+ const char *CurPtr;
+ const MemoryBuffer *CurBuf;
+ bool isAtStartOfLine;
+
+ void operator=(const AsmLexer&); // DO NOT IMPLEMENT
+ AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT
+
+protected:
+ /// LexToken - Read the next token and return its code.
+ virtual AsmToken LexToken();
+
+public:
+ AsmLexer(const MCAsmInfo &MAI);
+ ~AsmLexer();
+
+ void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
+
+ virtual StringRef LexUntilEndOfStatement();
+ StringRef LexUntilEndOfLine();
+
+ bool isAtStartOfComment(char Char);
+ bool isAtStatementSeparator(const char *Ptr);
+
+ const MCAsmInfo &getMAI() const { return MAI; }
+
+private:
+ int getNextChar();
+ AsmToken ReturnError(const char *Loc, const std::string &Msg);
+
+ AsmToken LexIdentifier();
+ AsmToken LexSlash();
+ AsmToken LexLineComment();
+ AsmToken LexDigit();
+ AsmToken LexSingleQuote();
+ AsmToken LexQuote();
+ AsmToken LexFloatLiteral();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
new file mode 100644
index 000000000000..5e29ad49dd3f
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -0,0 +1,181 @@
+//===-- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer 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_MCASMLEXER_H
+#define LLVM_MC_MCASMLEXER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+
+/// AsmToken - Target independent representation for an assembler token.
+class AsmToken {
+public:
+ enum TokenKind {
+ // Markers
+ Eof, Error,
+
+ // String values.
+ Identifier,
+ String,
+
+ // Integer values.
+ Integer,
+
+ // Real values.
+ Real,
+
+ // Register values (stored in IntVal). Only used by MCTargetAsmLexer.
+ Register,
+
+ // No-value.
+ EndOfStatement,
+ Colon,
+ Plus, Minus, Tilde,
+ Slash, // '/'
+ BackSlash, // '\'
+ LParen, RParen, LBrac, RBrac, LCurly, RCurly,
+ Star, Dot, Comma, Dollar, Equal, EqualEqual,
+
+ Pipe, PipePipe, Caret,
+ Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
+ Less, LessEqual, LessLess, LessGreater,
+ Greater, GreaterEqual, GreaterGreater, At
+ };
+
+private:
+ TokenKind Kind;
+
+ /// A reference to the entire token contents; this is always a pointer into
+ /// a memory buffer owned by the source manager.
+ StringRef Str;
+
+ int64_t IntVal;
+
+public:
+ AsmToken() {}
+ AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+ : Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
+
+ TokenKind getKind() const { return Kind; }
+ bool is(TokenKind K) const { return Kind == K; }
+ bool isNot(TokenKind K) const { return Kind != K; }
+
+ SMLoc getLoc() const;
+ SMLoc getEndLoc() const;
+
+ /// getStringContents - Get the contents of a string token (without quotes).
+ StringRef getStringContents() const {
+ assert(Kind == String && "This token isn't a string!");
+ return Str.slice(1, Str.size() - 1);
+ }
+
+ /// getIdentifier - Get the identifier string for the current token, which
+ /// should be an identifier or a string. This gets the portion of the string
+ /// which should be used as the identifier, e.g., it does not include the
+ /// quotes on strings.
+ StringRef getIdentifier() const {
+ if (Kind == Identifier)
+ return getString();
+ return getStringContents();
+ }
+
+ /// getString - Get the string for the current token, this includes all
+ /// characters (for example, the quotes on strings) in the token.
+ ///
+ /// The returned StringRef points into the source manager's memory buffer, and
+ /// is safe to store across calls to Lex().
+ StringRef getString() const { return Str; }
+
+ // FIXME: Don't compute this in advance, it makes every token larger, and is
+ // also not generally what we want (it is nicer for recovery etc. to lex 123br
+ // as a single token, then diagnose as an invalid number).
+ int64_t getIntVal() const {
+ 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
+/// assembly lexers.
+class MCAsmLexer {
+ /// The current token, stored in the base class for faster access.
+ AsmToken CurTok;
+
+ /// The location and description of the current error
+ SMLoc ErrLoc;
+ std::string Err;
+
+ MCAsmLexer(const MCAsmLexer &); // DO NOT IMPLEMENT
+ void operator=(const MCAsmLexer &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ const char *TokStart;
+
+ MCAsmLexer();
+
+ virtual AsmToken LexToken() = 0;
+
+ void SetError(const SMLoc &errLoc, const std::string &err) {
+ ErrLoc = errLoc;
+ Err = err;
+ }
+
+public:
+ virtual ~MCAsmLexer();
+
+ /// Lex - Consume the next token from the input stream and return it.
+ ///
+ /// The lexer will continuosly return the end-of-file token once the end of
+ /// the main input file has been reached.
+ const AsmToken &Lex() {
+ return CurTok = LexToken();
+ }
+
+ virtual StringRef LexUntilEndOfStatement() = 0;
+
+ /// getLoc - Get the current source location.
+ SMLoc getLoc() const;
+
+ /// 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/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h
new file mode 100644
index 000000000000..793c7097ba14
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h
@@ -0,0 +1,146 @@
+//===-- llvm/MC/MCAsmParser.h - Abstract Asm Parser 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_MCASMPARSER_H
+#define LLVM_MC_MCASMPARSER_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+class AsmToken;
+class MCAsmInfo;
+class MCAsmLexer;
+class MCAsmParserExtension;
+class MCContext;
+class MCExpr;
+class MCStreamer;
+class MCTargetAsmParser;
+class SMLoc;
+class SMRange;
+class SourceMgr;
+class StringRef;
+class Twine;
+
+/// MCAsmParser - Generic assembler parser interface, for use by target specific
+/// assembly parsers.
+class MCAsmParser {
+public:
+ typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
+
+private:
+ MCAsmParser(const MCAsmParser &); // DO NOT IMPLEMENT
+ void operator=(const MCAsmParser &); // DO NOT IMPLEMENT
+
+ MCTargetAsmParser *TargetParser;
+
+ unsigned ShowParsedOperands : 1;
+
+protected: // Can only create subclasses.
+ MCAsmParser();
+
+public:
+ virtual ~MCAsmParser();
+
+ virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
+ StringRef Directive,
+ DirectiveHandler Handler) = 0;
+
+ virtual SourceMgr &getSourceManager() = 0;
+
+ virtual MCAsmLexer &getLexer() = 0;
+
+ virtual MCContext &getContext() = 0;
+
+ /// getStreamer - Return the output streamer for the assembler.
+ virtual MCStreamer &getStreamer() = 0;
+
+ MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
+ void setTargetParser(MCTargetAsmParser &P);
+
+ virtual unsigned getAssemblerDialect() { return 0;}
+ virtual void setAssemblerDialect(unsigned i) { }
+
+ bool getShowParsedOperands() const { return ShowParsedOperands; }
+ void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
+
+ /// 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.
+ ///
+ /// \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.
+ ///
+ /// \return The return value is always true, as an idiomatic convenience to
+ /// clients.
+ virtual bool Error(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
+
+ /// Lex - Get the next AsmToken in the stream, possibly handling file
+ /// inclusion first.
+ virtual const AsmToken &Lex() = 0;
+
+ /// getTok - Get the current AsmToken from the stream.
+ const AsmToken &getTok();
+
+ /// \brief Report an error at the current lexer location.
+ bool TokError(const Twine &Msg,
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
+
+ /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// and set \arg 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
+ /// current token until the end of the statement; the current token on exit
+ /// will be either the EndOfStatement or EOF.
+ virtual StringRef ParseStringToEndOfStatement() = 0;
+
+ /// EatToEndOfStatement - Skip to the end of the current statement, for error
+ /// recovery.
+ virtual void EatToEndOfStatement() = 0;
+
+ /// ParseExpression - Parse an arbitrary expression.
+ ///
+ /// @param Res - The value of the expression. The result is undefined
+ /// on error.
+ /// @result - False on success.
+ virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ bool ParseExpression(const MCExpr *&Res);
+
+ /// ParseParenExpression - Parse an arbitrary expression, assuming that an
+ /// initial '(' has already been consumed.
+ ///
+ /// @param Res - The value of the expression. The result is undefined
+ /// on error.
+ /// @result - False on success.
+ virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+
+ /// ParseAbsoluteExpression - Parse an expression which must evaluate to an
+ /// absolute value.
+ ///
+ /// @param Res - The value of the absolute expression. The result is undefined
+ /// on error.
+ /// @result - False on success.
+ virtual bool ParseAbsoluteExpression(int64_t &Res) = 0;
+};
+
+/// \brief Create an MCAsmParser instance.
+MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &,
+ MCStreamer &, const MCAsmInfo &);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
new file mode 100644
index 000000000000..4e2aee992877
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -0,0 +1,80 @@
+//===-- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks -------*- 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_MCASMPARSEREXTENSION_H
+#define LLVM_MC_MCASMPARSEREXTENSION_H
+
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class Twine;
+
+/// \brief Generic interface for extending the MCAsmParser,
+/// which is implemented by target and object file assembly parser
+/// implementations.
+class MCAsmParserExtension {
+ MCAsmParserExtension(const MCAsmParserExtension &); // DO NOT IMPLEMENT
+ void operator=(const MCAsmParserExtension &); // DO NOT IMPLEMENT
+
+ MCAsmParser *Parser;
+
+protected:
+ MCAsmParserExtension();
+
+ // Helper template for implementing static dispatch functions.
+ template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
+ static bool HandleDirective(MCAsmParserExtension *Target,
+ StringRef Directive,
+ SMLoc DirectiveLoc) {
+ T *Obj = static_cast<T*>(Target);
+ return (Obj->*Handler)(Directive, DirectiveLoc);
+ }
+
+ bool BracketExpressionsSupported;
+
+public:
+ virtual ~MCAsmParserExtension();
+
+ /// \brief Initialize the extension for parsing using the given \arg
+ /// Parser. The extension should use the AsmParser interfaces to register its
+ /// parsing routines.
+ virtual void Initialize(MCAsmParser &Parser);
+
+ /// @name MCAsmParser Proxy Interfaces
+ /// @{
+
+ MCContext &getContext() { return getParser().getContext(); }
+ MCAsmLexer &getLexer() { return getParser().getLexer(); }
+ MCAsmParser &getParser() { return *Parser; }
+ SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
+ MCStreamer &getStreamer() { return getParser().getStreamer(); }
+ bool Warning(SMLoc L, const Twine &Msg) {
+ return getParser().Warning(L, Msg);
+ }
+ bool Error(SMLoc L, const Twine &Msg) {
+ return getParser().Error(L, Msg);
+ }
+ bool TokError(const Twine &Msg) {
+ return getParser().TokError(Msg);
+ }
+
+ const AsmToken &Lex() { return getParser().Lex(); }
+
+ const AsmToken &getTok() { return getParser().getTok(); }
+
+ bool HasBracketExpressions() const { return BracketExpressionsSupported; }
+
+ /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
new file mode 100644
index 000000000000..2556e5f27a30
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -0,0 +1,47 @@
+//===-- llvm/MC/MCParsedAsmOperand.h - Asm Parser Operand -------*- 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_MCASMOPERAND_H
+#define LLVM_MC_MCASMOPERAND_H
+
+namespace llvm {
+class SMLoc;
+class raw_ostream;
+
+/// MCParsedAsmOperand - This abstract class represents a source-level assembly
+/// instruction operand. It should be subclassed by target-specific code. This
+/// base class is used by target-independent clients and is the interface
+/// between parsing an asm instruction and recognizing it.
+class MCParsedAsmOperand {
+public:
+ MCParsedAsmOperand() {}
+ virtual ~MCParsedAsmOperand() {}
+
+ /// 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;
+
+ /// 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.
+ virtual void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+inline raw_ostream& operator<<(raw_ostream &OS, const MCParsedAsmOperand &MO) {
+ MO.print(OS);
+ return OS;
+}
+
+} // end namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCRegisterInfo.h b/contrib/llvm/include/llvm/MC/MCRegisterInfo.h
new file mode 100644
index 000000000000..27acf2f2cc21
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -0,0 +1,361 @@
+//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file. This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCREGISTERINFO_H
+#define LLVM_MC_MCREGISTERINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+
+/// MCRegisterClass - Base class of TargetRegisterClass.
+class MCRegisterClass {
+public:
+ typedef const uint16_t* iterator;
+ typedef const uint16_t* const_iterator;
+
+ const char *Name;
+ const iterator RegsBegin;
+ const uint8_t *const RegSet;
+ const uint16_t RegsSize;
+ const uint16_t RegSetSize;
+ const uint16_t ID;
+ const uint16_t RegSize, Alignment; // Size & Alignment of register in bytes
+ const int8_t CopyCost;
+ const bool Allocatable;
+
+ /// getID() - Return the register class ID number.
+ ///
+ unsigned getID() const { return ID; }
+
+ /// getName() - Return the register class name for debugging.
+ ///
+ const char *getName() const { return Name; }
+
+ /// begin/end - Return all of the registers in this class.
+ ///
+ iterator begin() const { return RegsBegin; }
+ iterator end() const { return RegsBegin + RegsSize; }
+
+ /// getNumRegs - Return the number of registers in this class.
+ ///
+ unsigned getNumRegs() const { return RegsSize; }
+
+ /// getRegister - Return the specified register in the class.
+ ///
+ unsigned getRegister(unsigned i) const {
+ assert(i < getNumRegs() && "Register number out of range!");
+ return RegsBegin[i];
+ }
+
+ /// contains - Return true if the specified register is included in this
+ /// register class. This does not include virtual registers.
+ bool contains(unsigned Reg) const {
+ unsigned InByte = Reg % 8;
+ unsigned Byte = Reg / 8;
+ if (Byte >= RegSetSize)
+ return false;
+ return (RegSet[Byte] & (1 << InByte)) != 0;
+ }
+
+ /// contains - Return true if both registers are in this class.
+ bool contains(unsigned Reg1, unsigned Reg2) const {
+ return contains(Reg1) && contains(Reg2);
+ }
+
+ /// getSize - Return the size of the register in bytes, which is also the size
+ /// of a stack slot allocated to hold a spilled copy of this register.
+ unsigned getSize() const { return RegSize; }
+
+ /// getAlignment - Return the minimum required alignment for a register of
+ /// this class.
+ unsigned getAlignment() const { return Alignment; }
+
+ /// getCopyCost - Return the cost of copying a value between two registers in
+ /// this class. A negative number means the register class is very expensive
+ /// to copy e.g. status flag register classes.
+ int getCopyCost() const { return CopyCost; }
+
+ /// isAllocatable - Return true if this register class may be used to create
+ /// virtual registers.
+ bool isAllocatable() const { return Allocatable; }
+};
+
+/// MCRegisterDesc - This record contains all of the information known about
+/// a particular register. The Overlaps field contains a pointer to a zero
+/// terminated array of registers that this register aliases, starting with
+/// itself. This is needed for architectures like X86 which have AL alias AX
+/// alias EAX. The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
+/// AX. The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
+/// of AX.
+///
+struct MCRegisterDesc {
+ const char *Name; // Printable name for the reg (for debugging)
+ uint32_t Overlaps; // Overlapping registers, described above
+ uint32_t SubRegs; // Sub-register set, described above
+ uint32_t SuperRegs; // Super-register set, described above
+};
+
+/// MCRegisterInfo base class - We assume that the target defines a static
+/// array of MCRegisterDesc objects that represent all of the machine
+/// registers that the target has. As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+/// Note this class is designed to be a base class of TargetRegisterInfo, which
+/// is the interface used by codegen. However, specific targets *should never*
+/// specialize this class. MCRegisterInfo should only contain getters to access
+/// TableGen generated physical register data. It must not be extended with
+/// virtual methods.
+///
+class MCRegisterInfo {
+public:
+ typedef const MCRegisterClass *regclass_iterator;
+
+ /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
+ /// performed with a binary search.
+ struct DwarfLLVMRegPair {
+ unsigned FromReg;
+ unsigned ToReg;
+
+ bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; }
+ };
+private:
+ const MCRegisterDesc *Desc; // Pointer to the descriptor array
+ unsigned NumRegs; // Number of entries in the array
+ unsigned RAReg; // Return address register
+ const MCRegisterClass *Classes; // Pointer to the regclass array
+ unsigned NumClasses; // Number of entries in the array
+ const uint16_t *RegLists; // Pointer to the reglists array
+ const uint16_t *SubRegIndices; // Pointer to the subreg lookup
+ // array.
+ unsigned NumSubRegIndices; // Number of subreg indices.
+
+ unsigned L2DwarfRegsSize;
+ unsigned EHL2DwarfRegsSize;
+ unsigned Dwarf2LRegsSize;
+ unsigned EHDwarf2LRegsSize;
+ const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping
+ const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH
+ const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping
+ const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH
+ DenseMap<unsigned, int> L2SEHRegs; // LLVM to SEH regs mapping
+
+public:
+ /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
+ const MCRegisterClass *C, unsigned NC,
+ const uint16_t *RL,
+ const uint16_t *SubIndices,
+ unsigned NumIndices) {
+ Desc = D;
+ NumRegs = NR;
+ RAReg = RA;
+ Classes = C;
+ RegLists = RL;
+ NumClasses = NC;
+ SubRegIndices = SubIndices;
+ NumSubRegIndices = NumIndices;
+ }
+
+ /// mapLLVMRegsToDwarfRegs - 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,
+ bool isEH) {
+ if (isEH) {
+ EHL2DwarfRegs = Map;
+ EHL2DwarfRegsSize = Size;
+ } else {
+ L2DwarfRegs = Map;
+ L2DwarfRegsSize = Size;
+ }
+ }
+
+ /// mapDwarfRegsToLLVMRegs - 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,
+ bool isEH) {
+ if (isEH) {
+ EHDwarf2LRegs = Map;
+ EHDwarf2LRegsSize = Size;
+ } else {
+ Dwarf2LRegs = Map;
+ Dwarf2LRegsSize = Size;
+ }
+ }
+
+ /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register
+ /// number mapping. By default the SEH register number is just the same
+ /// as the LLVM register number.
+ /// FIXME: TableGen these numbers. Currently this requires target specific
+ /// initialization code.
+ void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) {
+ L2SEHRegs[LLVMReg] = SEHReg;
+ }
+
+ /// getRARegister - This method should return the register where the return
+ /// address can be found.
+ unsigned getRARegister() const {
+ return RAReg;
+ }
+
+ 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
+ /// pointer to this object.
+ ///
+ const MCRegisterDesc &get(unsigned RegNo) const {
+ return operator[](RegNo);
+ }
+
+ /// getAliasSet - Return the set of registers aliased by the specified
+ /// register, or a null list of there are none. The list returned is zero
+ /// terminated.
+ ///
+ const uint16_t *getAliasSet(unsigned RegNo) const {
+ // The Overlaps set always begins with Reg itself.
+ return RegLists + get(RegNo).Overlaps + 1;
+ }
+
+ /// getOverlaps - Return a list of registers that overlap Reg, including
+ /// itself. This is the same as the alias set except Reg is included in the
+ /// list.
+ /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
+ ///
+ const uint16_t *getOverlaps(unsigned RegNo) const {
+ return RegLists + get(RegNo).Overlaps;
+ }
+
+ /// getSubRegisters - Return the list of registers that are sub-registers of
+ /// the specified register, or a null list of there are none. The list
+ /// returned is zero terminated and sorted according to super-sub register
+ /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
+ ///
+ const uint16_t *getSubRegisters(unsigned RegNo) const {
+ return RegLists + get(RegNo).SubRegs;
+ }
+
+ /// getSubReg - 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 {
+ return *(SubRegIndices + (Reg - 1) * NumSubRegIndices + Idx - 1);
+ }
+
+ /// getMatchingSuperReg - 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 {
+ for (const uint16_t *SRs = getSuperRegisters(Reg); unsigned SR = *SRs;++SRs)
+ if (Reg == getSubReg(SR, SubIdx) && RC->contains(SR))
+ return SR;
+ return 0;
+ }
+
+ /// getSubRegIndex - 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 {
+ for (unsigned I = 1; I <= NumSubRegIndices; ++I)
+ if (getSubReg(RegNo, I) == SubRegNo)
+ return I;
+ return 0;
+ }
+
+ /// getSuperRegisters - Return the list of registers that are super-registers
+ /// of the specified register, or a null list of there are none. The list
+ /// returned is zero terminated and sorted according to super-sub register
+ /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
+ ///
+ const uint16_t *getSuperRegisters(unsigned RegNo) const {
+ return RegLists + get(RegNo).SuperRegs;
+ }
+
+ /// getName - Return the human-readable symbolic target-specific name for the
+ /// specified physical register.
+ const char *getName(unsigned RegNo) const {
+ return get(RegNo).Name;
+ }
+
+ /// getNumRegs - Return the number of registers this target has (useful for
+ /// sizing arrays holding per register information)
+ unsigned getNumRegs() const {
+ return NumRegs;
+ }
+
+ /// getDwarfRegNum - 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 {
+ const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
+ unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
+
+ DwarfLLVMRegPair Key = { RegNum, 0 };
+ const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
+ if (I == M+Size || I->FromReg != RegNum)
+ return -1;
+ return I->ToReg;
+ }
+
+ /// getLLVMRegNum - Map a dwarf register back to a target register.
+ ///
+ int getLLVMRegNum(unsigned RegNum, bool isEH) const {
+ const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
+ unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
+
+ DwarfLLVMRegPair Key = { RegNum, 0 };
+ const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
+ assert(I != M+Size && I->FromReg == RegNum && "Invalid RegNum");
+ return I->ToReg;
+ }
+
+ /// getSEHRegNum - 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 {
+ const DenseMap<unsigned, int>::const_iterator I = L2SEHRegs.find(RegNum);
+ if (I == L2SEHRegs.end()) return (int)RegNum;
+ return I->second;
+ }
+
+ regclass_iterator regclass_begin() const { return Classes; }
+ regclass_iterator regclass_end() const { return Classes+NumClasses; }
+
+ unsigned getNumRegClasses() const {
+ return (unsigned)(regclass_end()-regclass_begin());
+ }
+
+ /// getRegClass - Returns the register class associated with the enumeration
+ /// value. See class MCOperandInfo.
+ const MCRegisterClass getRegClass(unsigned i) const {
+ assert(i < getNumRegClasses() && "Register Class ID out of range");
+ return Classes[i];
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCSection.h b/contrib/llvm/include/llvm/MC/MCSection.h
new file mode 100644
index 000000000000..7da6534b6e88
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSection.h
@@ -0,0 +1,73 @@
+//===- MCSection.h - Machine Code Sections ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSection class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTION_H
+#define LLVM_MC_MCSECTION_H
+
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+ class MCAsmInfo;
+ class raw_ostream;
+
+ /// MCSection - Instances of this class represent a uniqued identifier for a
+ /// section in the current translation unit. The MCContext class uniques and
+ /// creates these.
+ class MCSection {
+ public:
+ enum SectionVariant {
+ SV_COFF = 0,
+ SV_ELF,
+ SV_MachO
+ };
+
+ private:
+ MCSection(const MCSection&); // DO NOT IMPLEMENT
+ void operator=(const MCSection&); // DO NOT IMPLEMENT
+ protected:
+ MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {}
+ SectionVariant Variant;
+ SectionKind Kind;
+ public:
+ virtual ~MCSection();
+
+ SectionKind getKind() const { return Kind; }
+
+ SectionVariant getVariant() const { return Variant; }
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
+ raw_ostream &OS) 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
+ /// from the base of the section, saving a relocation.
+ virtual bool isBaseAddressKnownZero() const {
+ return false;
+ }
+
+ // UseCodeAlign - Return true if a .align directive should use
+ // "optimized nops" to fill instead of 0s.
+ virtual bool UseCodeAlign() const = 0;
+
+ /// 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
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCSectionCOFF.h b/contrib/llvm/include/llvm/MC/MCSectionCOFF.h
new file mode 100644
index 000000000000..7eacde57f48f
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSectionCOFF.h
@@ -0,0 +1,69 @@
+//===- MCSectionCOFF.h - COFF Machine Code Sections -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionCOFF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONCOFF_H
+#define LLVM_MC_MCSECTIONCOFF_H
+
+#include "llvm/MC/MCSection.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// MCSectionCOFF - This represents a section on Windows
+ class MCSectionCOFF : public MCSection {
+ // The memory for this string is stored in the same MCContext as *this.
+ StringRef SectionName;
+
+ /// Characteristics - This is the Characteristics field of a section,
+ // drawn from the enums below.
+ unsigned Characteristics;
+
+ /// Selection - This is the Selection field for the section symbol, if
+ /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
+ int Selection;
+
+ private:
+ friend class MCContext;
+ MCSectionCOFF(StringRef Section, unsigned Characteristics,
+ int Selection, SectionKind K)
+ : MCSection(SV_COFF, K), SectionName(Section),
+ Characteristics(Characteristics), Selection (Selection) {
+ assert ((Characteristics & 0x00F00000) == 0 &&
+ "alignment must not be set upon section creation");
+ }
+ ~MCSectionCOFF();
+
+ public:
+ /// ShouldOmitSectionDirective - Decides whether a '.section' directive
+ /// should be printed before the section name
+ bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+ StringRef getSectionName() const { return SectionName; }
+ unsigned getCharacteristics() const { return Characteristics; }
+ int getSelection () const { return Selection; }
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
+ raw_ostream &OS) const;
+ virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_COFF;
+ }
+ static bool classof(const MCSectionCOFF *) { return true; }
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCSectionELF.h b/contrib/llvm/include/llvm/MC/MCSectionELF.h
new file mode 100644
index 000000000000..7321ca83e897
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSectionELF.h
@@ -0,0 +1,88 @@
+//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionELF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONELF_H
+#define LLVM_MC_MCSECTIONELF_H
+
+#include "llvm/MC/MCSection.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class MCSymbol;
+
+/// MCSectionELF - This represents a section on linux, lots of unix variants
+/// and some bare metal systems.
+class MCSectionELF : public MCSection {
+ /// SectionName - This is the name of the section. The referenced memory is
+ /// owned by TargetLoweringObjectFileELF's ELFUniqueMap.
+ StringRef SectionName;
+
+ /// Type - This is the sh_type field of a section, drawn from the enums below.
+ unsigned Type;
+
+ /// Flags - This is the sh_flags field of a section, drawn from the enums.
+ /// below.
+ unsigned Flags;
+
+ /// EntrySize - The size of each entry in this section. This size only
+ /// makes sense for sections that contain fixed-sized entries. If a
+ /// section does not contain fixed-sized entries 'EntrySize' will be 0.
+ unsigned EntrySize;
+
+ const MCSymbol *Group;
+
+private:
+ friend class MCContext;
+ MCSectionELF(StringRef Section, unsigned type, unsigned flags,
+ SectionKind K, unsigned entrySize, const MCSymbol *group)
+ : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
+ EntrySize(entrySize), Group(group) {}
+ ~MCSectionELF();
+public:
+
+ /// ShouldOmitSectionDirective - Decides whether a '.section' directive
+ /// should be printed before the section name
+ bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
+
+ StringRef getSectionName() const { return SectionName; }
+ unsigned getType() const { return Type; }
+ unsigned getFlags() const { return Flags; }
+ unsigned getEntrySize() const { return EntrySize; }
+ const MCSymbol *getGroup() const { return Group; }
+
+ void PrintSwitchToSection(const MCAsmInfo &MAI,
+ raw_ostream &OS) const;
+ virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
+
+ /// isBaseAddressKnownZero - We know that non-allocatable sections (like
+ /// debug info) have a base of zero.
+ virtual bool isBaseAddressKnownZero() const {
+ return (getFlags() & ELF::SHF_ALLOC) == 0;
+ }
+
+ 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);
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCSectionMachO.h b/contrib/llvm/include/llvm/MC/MCSectionMachO.h
new file mode 100644
index 000000000000..15eb4f4a7685
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSectionMachO.h
@@ -0,0 +1,182 @@
+//===- MCSectionMachO.h - MachO Machine Code Sections -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionMachO class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONMACHO_H
+#define LLVM_MC_MCSECTIONMACHO_H
+
+#include "llvm/MC/MCSection.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// MCSectionMachO - This represents a section on a Mach-O system (used by
+/// Mac OS X). On a Mac system, these are also described in
+/// /usr/include/mach-o/loader.h.
+class MCSectionMachO : public MCSection {
+ char SegmentName[16]; // Not necessarily null terminated!
+ char SectionName[16]; // Not necessarily null terminated!
+
+ /// TypeAndAttributes - This is the SECTION_TYPE and SECTION_ATTRIBUTES
+ /// field of a section, drawn from the enums below.
+ unsigned TypeAndAttributes;
+
+ /// Reserved2 - The 'reserved2' field of a section, used to represent the
+ /// size of stubs, for example.
+ unsigned Reserved2;
+
+ MCSectionMachO(StringRef Segment, StringRef Section,
+ unsigned TAA, unsigned reserved2, SectionKind K);
+ friend class MCContext;
+public:
+
+ /// These are the section type and attributes fields. A MachO section can
+ /// have only one Type, but can have any of the attributes specified.
+ enum {
+ // TypeAndAttributes bitmasks.
+ SECTION_TYPE = 0x000000FFU,
+ SECTION_ATTRIBUTES = 0xFFFFFF00U,
+
+ // Valid section types.
+
+ /// S_REGULAR - Regular section.
+ S_REGULAR = 0x00U,
+ /// S_ZEROFILL - Zero fill on demand section.
+ S_ZEROFILL = 0x01U,
+ /// S_CSTRING_LITERALS - Section with literal C strings.
+ S_CSTRING_LITERALS = 0x02U,
+ /// S_4BYTE_LITERALS - Section with 4 byte literals.
+ S_4BYTE_LITERALS = 0x03U,
+ /// S_8BYTE_LITERALS - Section with 8 byte literals.
+ S_8BYTE_LITERALS = 0x04U,
+ /// S_LITERAL_POINTERS - Section with pointers to literals.
+ S_LITERAL_POINTERS = 0x05U,
+ /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
+ S_NON_LAZY_SYMBOL_POINTERS = 0x06U,
+ /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
+ S_LAZY_SYMBOL_POINTERS = 0x07U,
+ /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
+ /// the Reserved2 field.
+ S_SYMBOL_STUBS = 0x08U,
+ /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
+ /// initialization.
+ S_MOD_INIT_FUNC_POINTERS = 0x09U,
+ /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for
+ /// termination.
+ S_MOD_TERM_FUNC_POINTERS = 0x0AU,
+ /// S_COALESCED - Section contains symbols that are to be coalesced.
+ S_COALESCED = 0x0BU,
+ /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4
+ /// gigabytes).
+ S_GB_ZEROFILL = 0x0CU,
+ /// S_INTERPOSING - Section with only pairs of function pointers for
+ /// interposing.
+ S_INTERPOSING = 0x0DU,
+ /// S_16BYTE_LITERALS - Section with only 16 byte literals.
+ S_16BYTE_LITERALS = 0x0EU,
+ /// S_DTRACE_DOF - Section contains DTrace Object Format.
+ S_DTRACE_DOF = 0x0FU,
+ /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
+ /// lazy loaded dylibs.
+ S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10U,
+ /// S_THREAD_LOCAL_REGULAR - Section with ....
+ S_THREAD_LOCAL_REGULAR = 0x11U,
+ /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
+ S_THREAD_LOCAL_ZEROFILL = 0x12U,
+ /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable structure
+ /// data.
+ S_THREAD_LOCAL_VARIABLES = 0x13U,
+ /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with ....
+ S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14U,
+ /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
+ /// variable initialization pointers to functions.
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15U,
+
+ LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS,
+
+
+ // Valid section attributes.
+
+ /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine
+ /// instructions.
+ S_ATTR_PURE_INSTRUCTIONS = 1U << 31,
+ /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be
+ /// in a ranlib table of contents.
+ S_ATTR_NO_TOC = 1U << 30,
+ /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section
+ /// in files with the MY_DYLDLINK flag.
+ S_ATTR_STRIP_STATIC_SYMS = 1U << 29,
+ /// S_ATTR_NO_DEAD_STRIP - No dead stripping.
+ S_ATTR_NO_DEAD_STRIP = 1U << 28,
+ /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
+ S_ATTR_LIVE_SUPPORT = 1U << 27,
+ /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by
+ /// dyld.
+ S_ATTR_SELF_MODIFYING_CODE = 1U << 26,
+ /// S_ATTR_DEBUG - A debug section.
+ S_ATTR_DEBUG = 1U << 25,
+ /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
+ S_ATTR_SOME_INSTRUCTIONS = 1U << 10,
+ /// S_ATTR_EXT_RELOC - Section has external relocation entries.
+ S_ATTR_EXT_RELOC = 1U << 9,
+ /// S_ATTR_LOC_RELOC - Section has local relocation entries.
+ S_ATTR_LOC_RELOC = 1U << 8
+ };
+
+ StringRef getSegmentName() const {
+ // SegmentName is not necessarily null terminated!
+ if (SegmentName[15])
+ return StringRef(SegmentName, 16);
+ return StringRef(SegmentName);
+ }
+ StringRef getSectionName() const {
+ // SectionName is not necessarily null terminated!
+ if (SectionName[15])
+ return StringRef(SectionName, 16);
+ return StringRef(SectionName);
+ }
+
+ unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
+ unsigned getStubSize() const { return Reserved2; }
+
+ unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; }
+ bool hasAttribute(unsigned Value) const {
+ return (TypeAndAttributes & Value) != 0;
+ }
+
+ /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
+ /// This is a string that can appear after a .section directive in a mach-o
+ /// flavored .s file. If successful, this fills in the specified Out
+ /// parameters and returns an empty string. When an invalid section
+ /// specifier is present, this returns a string indicating the problem.
+ /// If no TAA was parsed, TAA is not altered, and TAAWasSet becomes false.
+ static std::string ParseSectionSpecifier(StringRef Spec, // In.
+ StringRef &Segment, // Out.
+ StringRef &Section, // Out.
+ unsigned &TAA, // Out.
+ bool &TAAParsed, // Out.
+ unsigned &StubSize); // Out.
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
+ raw_ostream &OS) const;
+ virtual bool UseCodeAlign() const;
+ virtual bool isVirtualSection() const;
+
+ static bool classof(const MCSection *S) {
+ return S->getVariant() == SV_MachO;
+ }
+ static bool classof(const MCSectionMachO *) { return true; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCStreamer.h b/contrib/llvm/include/llvm/MC/MCStreamer.h
new file mode 100644
index 000000000000..25956008e021
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCStreamer.h
@@ -0,0 +1,676 @@
+//===- MCStreamer.h - High-level Streaming Machine Code Output --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCStreamer class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSTREAMER_H
+#define LLVM_MC_MCSTREAMER_H
+
+#include "llvm/Support/DataTypes.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"
+
+namespace llvm {
+ class MCAsmBackend;
+ class MCCodeEmitter;
+ class MCContext;
+ class MCExpr;
+ class MCInst;
+ class MCInstPrinter;
+ class MCSection;
+ class MCSymbol;
+ class StringRef;
+ class Twine;
+ class raw_ostream;
+ class formatted_raw_ostream;
+
+ /// MCStreamer - Streaming machine code generation interface. This interface
+ /// is intended to provide a programatic interface that is very similar to the
+ /// level that an assembler .s file provides. It has callbacks to emit bytes,
+ /// handle directives, etc. The implementation of this interface retains
+ /// state to know what the current section is etc.
+ ///
+ /// There are multiple implementations of this interface: one for writing out
+ /// a .s file, and implementations that write out .o files of various formats.
+ ///
+ class MCStreamer {
+ MCContext &Context;
+
+ MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT
+ MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT
+
+ bool EmitEHFrame;
+ bool EmitDebugFrame;
+
+ std::vector<MCDwarfFrameInfo> FrameInfos;
+ MCDwarfFrameInfo *getCurrentFrameInfo();
+ void EnsureValidFrame();
+
+ std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos;
+ MCWin64EHUnwindInfo *CurrentW64UnwindInfo;
+ void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
+ void EnsureValidW64UnwindInfo();
+
+ MCSymbol* LastSymbol;
+
+ /// SectionStack - This is stack of current and previous section
+ /// values saved by PushSection.
+ SmallVector<std::pair<const MCSection *,
+ const MCSection *>, 4> SectionStack;
+
+ unsigned UniqueCodeBeginSuffix;
+ unsigned UniqueDataBeginSuffix;
+
+ protected:
+ /// Indicator of whether the previous data-or-code indicator was for
+ /// code or not. Used to determine when we need to emit a new indicator.
+ enum DataType {
+ Data,
+ Code,
+ JumpTable8,
+ JumpTable16,
+ JumpTable32
+ };
+ DataType RegionIndicator;
+
+
+ MCStreamer(MCContext &Ctx);
+
+ const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
+ const MCSymbol *B);
+
+ const MCExpr *ForceExpAbs(const MCExpr* Expr);
+
+ void RecordProcStart(MCDwarfFrameInfo &Frame);
+ virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
+ void RecordProcEnd(MCDwarfFrameInfo &Frame);
+ virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
+ void EmitFrames(bool usingCFI);
+
+ MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;}
+ void EmitW64Tables();
+
+ public:
+ virtual ~MCStreamer();
+
+ MCContext &getContext() const { return Context; }
+
+ unsigned getNumFrameInfos() {
+ return FrameInfos.size();
+ }
+
+ const MCDwarfFrameInfo &getFrameInfo(unsigned i) {
+ return FrameInfos[i];
+ }
+
+ ArrayRef<MCDwarfFrameInfo> getFrameInfos() {
+ return FrameInfos;
+ }
+
+ unsigned getNumW64UnwindInfos() {
+ return W64UnwindInfos.size();
+ }
+
+ MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) {
+ return *W64UnwindInfos[i];
+ }
+
+ /// @name Assembly File Formatting.
+ /// @{
+
+ /// isVerboseAsm - Return true if this streamer supports verbose assembly
+ /// and if it is enabled.
+ virtual bool isVerboseAsm() const { return false; }
+
+ /// hasRawTextSupport - Return true if this asm streamer supports emitting
+ /// unformatted text to the .s file with EmitRawText.
+ virtual bool hasRawTextSupport() const { return false; }
+
+ /// AddComment - Add a comment that can be emitted to the generated .s
+ /// file if applicable as a QoI issue to make the output of the compiler
+ /// more readable. This only affects the MCAsmStreamer, and only when
+ /// verbose assembly output is enabled.
+ ///
+ /// If the comment includes embedded \n's, they will each get the comment
+ /// prefix as appropriate. The added comment should not end with a \n.
+ virtual void AddComment(const Twine &T) {}
+
+ /// GetCommentOS - Return a raw_ostream that comments can be written to.
+ /// Unlike AddComment, you are required to terminate comments with \n if you
+ /// use this method.
+ virtual raw_ostream &GetCommentOS();
+
+ /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
+ virtual void AddBlankLine() {}
+
+ /// @}
+
+ /// @name Symbol & Section Management
+ /// @{
+
+ /// getCurrentSection - Return the current section that the streamer is
+ /// emitting code to.
+ const MCSection *getCurrentSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().first;
+ return NULL;
+ }
+
+ /// getPreviousSection - Return the previous section that the streamer is
+ /// emitting code to.
+ const MCSection *getPreviousSection() const {
+ if (!SectionStack.empty())
+ return SectionStack.back().second;
+ return NULL;
+ }
+
+ /// ChangeSection - Update streamer for a new active section.
+ ///
+ /// This is called by PopSection and SwitchSection, if the current
+ /// section changes.
+ virtual void ChangeSection(const MCSection *) = 0;
+
+ /// pushSection - Save the current and previous section on the
+ /// section stack.
+ void PushSection() {
+ SectionStack.push_back(std::make_pair(getCurrentSection(),
+ getPreviousSection()));
+ }
+
+ /// popSection - Restore the current and previous section from
+ /// the section stack. Calls ChangeSection as needed.
+ ///
+ /// Returns false if the stack was empty.
+ bool PopSection() {
+ if (SectionStack.size() <= 1)
+ return false;
+ const MCSection *oldSection = SectionStack.pop_back_val().first;
+ const MCSection *curSection = SectionStack.back().first;
+
+ if (oldSection != curSection)
+ ChangeSection(curSection);
+ return true;
+ }
+
+ /// SwitchSection - Set the current section where code is being emitted to
+ /// @p Section. This is required to update CurSection.
+ ///
+ /// This corresponds to assembler directives like .section, .text, etc.
+ void SwitchSection(const MCSection *Section) {
+ assert(Section && "Cannot switch to a null section!");
+ const MCSection *curSection = SectionStack.back().first;
+ SectionStack.back().second = curSection;
+ if (Section != curSection) {
+ SectionStack.back().first = Section;
+ ChangeSection(Section);
+ }
+ }
+
+ /// SwitchSectionNoChange - Set the current section where code is being
+ /// emitted to @p Section. This is required to update CurSection. This
+ /// version does not call ChangeSection.
+ void SwitchSectionNoChange(const MCSection *Section) {
+ assert(Section && "Cannot switch to a null section!");
+ const MCSection *curSection = SectionStack.back().first;
+ SectionStack.back().second = curSection;
+ if (Section != curSection)
+ SectionStack.back().first = Section;
+ }
+
+ /// InitSections - Create the default sections and set the initial one.
+ virtual void InitSections() = 0;
+
+ /// EmitLabel - Emit a label for @p Symbol into the current section.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// foo:
+ ///
+ /// @param Symbol - The symbol to emit. A given symbol should only be
+ /// emitted as a label once, and symbols emitted as a label should never be
+ /// used in an assignment.
+ virtual void EmitLabel(MCSymbol *Symbol);
+
+ /// EmitDataRegion - Emit a label that marks the beginning of a data
+ /// region.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitDataRegion();
+
+ /// EmitJumpTable8Region - Emit a label that marks the beginning of a
+ /// jump table composed of 8-bit offsets.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitJumpTable8Region();
+
+ /// EmitJumpTable16Region - Emit a label that marks the beginning of a
+ /// jump table composed of 16-bit offsets.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitJumpTable16Region();
+
+ /// EmitJumpTable32Region - Emit a label that marks the beginning of a
+ /// jump table composed of 32-bit offsets.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $d.1:
+ virtual void EmitJumpTable32Region();
+
+ /// EmitCodeRegion - Emit a label that marks the beginning of a code
+ /// region.
+ /// On ELF targets, this corresponds to an assembler statement such as:
+ /// $a.1:
+ virtual void EmitCodeRegion();
+
+ /// ForceCodeRegion - Forcibly sets the current region mode to code. Used
+ /// at function entry points.
+ void ForceCodeRegion() { RegionIndicator = Code; }
+
+
+ virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
+ MCSymbol *EHSymbol);
+
+ /// EmitAssemblerFlag - Note in the output the specified @p Flag
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
+
+ /// EmitThumbFunc - Note in the output that the specified @p Func is
+ /// a Thumb mode function (ARM target only).
+ virtual void EmitThumbFunc(MCSymbol *Func) = 0;
+
+ /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// symbol = value
+ ///
+ /// The assignment generates no code, but has the side effect of binding the
+ /// value in the current context. For the assembly streamer, this prints the
+ /// binding into the .s file.
+ ///
+ /// @param Symbol - The symbol being assigned to.
+ /// @param Value - The value for the symbol.
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0;
+
+ /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .weakref alias, symbol
+ ///
+ /// @param Alias - The alias that is being created.
+ /// @param Symbol - The symbol being aliased.
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0;
+
+ /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol,
+ MCSymbolAttr Attribute) = 0;
+
+ /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol.
+ ///
+ /// @param Symbol - The symbol to have its n_desc field set.
+ /// @param DescValue - The value to set into the n_desc field.
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
+
+ /// BeginCOFFSymbolDef - Start emitting COFF symbol definition
+ ///
+ /// @param Symbol - The symbol to have its External & Type fields set.
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0;
+
+ /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
+ ///
+ /// @param StorageClass - The storage class the symbol should have.
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0;
+
+ /// EmitCOFFSymbolType - Emit the type of the symbol.
+ ///
+ /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
+ virtual void EmitCOFFSymbolType(int Type) = 0;
+
+ /// EndCOFFSymbolDef - Marks the end of the symbol definition.
+ virtual void EndCOFFSymbolDef() = 0;
+
+ /// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
+ ///
+ /// @param Symbol - Symbol the section relative realocation should point to.
+ virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
+
+ /// EmitELFSize - Emit an ELF .size directive.
+ ///
+ /// This corresponds to an assembler statement such as:
+ /// .size symbol, expression
+ ///
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
+
+ /// EmitCommonSymbol - Emit a common symbol.
+ ///
+ /// @param Symbol - The common symbol to emit.
+ /// @param Size - The size of the common symbol.
+ /// @param ByteAlignment - The alignment of the symbol if
+ /// non-zero. This must be a power of 2.
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) = 0;
+
+ /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
+ ///
+ /// @param Symbol - The common symbol to emit.
+ /// @param Size - The size of the common symbol.
+ /// @param ByteAlignment - The alignment of the common symbol in bytes.
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) = 0;
+
+ /// EmitZerofill - Emit the zerofill section and an optional symbol.
+ ///
+ /// @param Section - The zerofill section to create and or to put the symbol
+ /// @param Symbol - The zerofill symbol to emit, if non-NULL.
+ /// @param Size - The size of the zerofill symbol.
+ /// @param ByteAlignment - The alignment of the zerofill symbol if
+ /// non-zero. This must be a power of 2 on some targets.
+ virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+ unsigned Size = 0,unsigned ByteAlignment = 0) = 0;
+
+ /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
+ ///
+ /// @param Section - The thread local common section.
+ /// @param Symbol - The thread local common symbol to emit.
+ /// @param Size - The size of the symbol.
+ /// @param ByteAlignment - The alignment of the thread local common symbol
+ /// if non-zero. This must be a power of 2 on some targets.
+ virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0) = 0;
+
+ /// @}
+ /// @name Generating Data
+ /// @{
+
+ /// EmitBytes - Emit the bytes in \arg Data into the output.
+ ///
+ /// This is used to implement assembler directives such as .byte, .ascii,
+ /// etc.
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0;
+
+ /// EmitValue - Emit the expression @p Value into the output as a native
+ /// integer of the given @p Size bytes.
+ ///
+ /// This is used to implement assembler directives such as .word, .quad,
+ /// etc.
+ ///
+ /// @param Value - The value to emit.
+ /// @param Size - The size of the integer (in bytes) to emit. This must
+ /// match a native machine width.
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace) = 0;
+
+ void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0);
+
+ /// EmitIntValue - Special case of EmitValue that avoids the client having
+ /// to pass in a MCExpr for constant integers.
+ virtual void EmitIntValue(uint64_t Value, unsigned Size,
+ unsigned AddrSpace = 0);
+
+ /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO
+ /// this is done by producing
+ /// foo = value
+ /// .long foo
+ void EmitAbsValue(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace = 0);
+
+ virtual void EmitULEB128Value(const MCExpr *Value) = 0;
+
+ virtual void EmitSLEB128Value(const MCExpr *Value) = 0;
+
+ /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
+ /// client having to pass in a MCExpr for constant integers.
+ void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0,
+ unsigned Padding = 0);
+
+ /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
+ /// client having to pass in a MCExpr for constant integers.
+ void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
+
+ /// EmitSymbolValue - Special case of EmitValue that avoids the client
+ /// having to pass in a MCExpr for MCSymbols.
+ void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ unsigned AddrSpace = 0);
+
+ /// EmitGPRel64Value - Emit the expression @p Value into the output as a
+ /// gprel64 (64-bit GP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .gpdword on
+ /// targets that support them.
+ virtual void EmitGPRel64Value(const MCExpr *Value);
+
+ /// EmitGPRel32Value - Emit the expression @p Value into the output as a
+ /// gprel32 (32-bit GP relative) value.
+ ///
+ /// This is used to implement assembler directives such as .gprel32 on
+ /// targets that support them.
+ virtual void EmitGPRel32Value(const MCExpr *Value);
+
+ /// EmitFill - Emit NumBytes bytes worth of the value specified by
+ /// FillValue. This implements directives such as '.space'.
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace);
+
+ /// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
+ /// function that just wraps EmitFill.
+ void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
+ EmitFill(NumBytes, 0, AddrSpace);
+ }
+
+
+ /// EmitValueToAlignment - Emit some number of copies of @p Value until
+ /// the byte alignment @p ByteAlignment is reached.
+ ///
+ /// If the number of bytes need to emit for the alignment is not a multiple
+ /// of @p ValueSize, then the contents of the emitted fill bytes is
+ /// undefined.
+ ///
+ /// This used to implement the .align assembler directive.
+ ///
+ /// @param ByteAlignment - The alignment to reach. This must be a power of
+ /// two on some targets.
+ /// @param Value - The value to use when filling bytes.
+ /// @param ValueSize - The size of the integer (in bytes) to emit for
+ /// @p Value. This must match a native machine width.
+ /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// the alignment cannot be reached in this many bytes, no bytes are
+ /// emitted.
+ virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) = 0;
+
+ /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
+ /// is reached.
+ ///
+ /// This used to align code where the alignment bytes may be executed. This
+ /// can emit different bytes for different sizes to optimize execution.
+ ///
+ /// @param ByteAlignment - The alignment to reach. This must be a power of
+ /// two on some targets.
+ /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
+ /// the alignment cannot be reached in this many bytes, no bytes are
+ /// emitted.
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) = 0;
+
+ /// EmitValueToOffset - Emit some number of copies of @p Value until the
+ /// byte offset @p Offset is reached.
+ ///
+ /// This is used to implement assembler directives such as .org.
+ ///
+ /// @param Offset - The offset to reach. This may be an expression, but the
+ /// expression must be associated with the current section.
+ /// @param Value - The value to use when filling bytes.
+ /// @return false on success, true if the offset was invalid.
+ virtual bool EmitValueToOffset(const MCExpr *Offset,
+ unsigned char Value = 0) = 0;
+
+ /// @}
+
+ /// EmitFileDirective - Switch to a new logical file. This is used to
+ /// implement the '.file "foo.c"' assembler directive.
+ virtual void EmitFileDirective(StringRef Filename) = 0;
+
+ /// EmitDwarfFileDirective - Associate a filename with a specified logical
+ /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
+ /// directive.
+ virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+ StringRef Filename);
+
+ /// EmitDwarfLocDirective - This implements the DWARF2
+ // '.loc fileno lineno ...' assembler directive.
+ virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa,
+ unsigned Discriminator,
+ StringRef FileName);
+
+ virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
+ const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize) = 0;
+
+ virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label) {
+ }
+
+ void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label,
+ int PointerSize);
+
+ virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding);
+ virtual void EmitCFISections(bool EH, bool Debug);
+ void EmitCFIStartProc();
+ void EmitCFIEndProc();
+ virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
+ virtual void EmitCFIDefCfaOffset(int64_t Offset);
+ virtual void EmitCFIDefCfaRegister(int64_t Register);
+ virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
+ virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
+ virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+ virtual void EmitCFIRememberState();
+ virtual void EmitCFIRestoreState();
+ virtual void EmitCFISameValue(int64_t Register);
+ virtual void EmitCFIRestore(int64_t Register);
+ virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
+ virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
+ virtual void EmitCFIEscape(StringRef Values);
+ virtual void EmitCFISignalFrame();
+
+ virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
+ virtual void EmitWin64EHEndProc();
+ virtual void EmitWin64EHStartChained();
+ virtual void EmitWin64EHEndChained();
+ virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
+ bool Except);
+ virtual void EmitWin64EHHandlerData();
+ virtual void EmitWin64EHPushReg(unsigned Register);
+ virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
+ virtual void EmitWin64EHAllocStack(unsigned Size);
+ virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
+ virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
+ virtual void EmitWin64EHPushFrame(bool Code);
+ virtual void EmitWin64EHEndProlog();
+
+ /// EmitInstruction - Emit the given @p Instruction into the current
+ /// section.
+ virtual void EmitInstruction(const MCInst &Inst) = 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.
+ virtual void EmitRawText(StringRef String);
+ void EmitRawText(const Twine &String);
+
+ /// ARM-related methods.
+ /// FIXME: Eventually we should have some "target MC streamer" and move
+ /// these methods there.
+ virtual void EmitFnStart();
+ virtual void EmitFnEnd();
+ virtual void EmitCantUnwind();
+ virtual void EmitPersonality(const MCSymbol *Personality);
+ virtual void EmitHandlerData();
+ virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
+ virtual void EmitPad(int64_t Offset);
+ virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
+ bool isVector);
+
+ /// FinishImpl - Streamer specific finalization.
+ virtual void FinishImpl() = 0;
+ /// Finish - Finish emission of machine code.
+ void Finish();
+ };
+
+ /// createNullStreamer - Create a dummy machine code streamer, which does
+ /// nothing. This is useful for timing the assembler front end.
+ MCStreamer *createNullStreamer(MCContext &Ctx);
+
+ /// createAsmStreamer - Create a machine code streamer which will print out
+ /// assembly for the native target, suitable for compiling with a native
+ /// assembler.
+ ///
+ /// \param InstPrint - If given, the instruction printer to use. If not given
+ /// the MCInst representation will be printed. This method takes ownership of
+ /// 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.
+ ///
+ /// \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.
+ ///
+ /// \param ShowInst - Whether to show the MCInst representation inline with
+ /// the assembly.
+ ///
+ /// \param DecodeLSDA - If true, emit comments that translates the LSDA into a
+ /// human readable format. Only usable with CFI.
+ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm,
+ bool useLoc,
+ bool useCFI,
+ bool useDwarfDirectory,
+ MCInstPrinter *InstPrint = 0,
+ MCCodeEmitter *CE = 0,
+ MCAsmBackend *TAB = 0,
+ bool ShowInst = false);
+
+ /// createMachOStreamer - Create a machine code streamer which will generate
+ /// Mach-O format object files.
+ ///
+ /// Takes ownership of \arg TAB and \arg CE.
+ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll = false);
+
+ /// createWinCOFFStreamer - Create a machine code streamer which will
+ /// generate Microsoft COFF format object files.
+ ///
+ /// Takes ownership of \arg TAB and \arg CE.
+ MCStreamer *createWinCOFFStreamer(MCContext &Ctx,
+ MCAsmBackend &TAB,
+ MCCodeEmitter &CE, raw_ostream &OS,
+ bool RelaxAll = false);
+
+ /// createELFStreamer - Create a machine code streamer which will generate
+ /// ELF format object files.
+ MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll, bool NoExecStack);
+
+ /// 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.
+ MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE);
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
new file mode 100644
index 000000000000..3b53f205cd55
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSubtargetInfo.h
@@ -0,0 +1,79 @@
+//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSUBTARGET_H
+#define LLVM_MC_MCSUBTARGET_H
+
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/MC/MCInstrItineraries.h"
+#include <string>
+
+namespace llvm {
+
+class StringRef;
+
+//===----------------------------------------------------------------------===//
+///
+/// MCSubtargetInfo - Generic base class for all target subtargets.
+///
+class MCSubtargetInfo {
+ std::string TargetTriple; // Target triple
+ const SubtargetFeatureKV *ProcFeatures; // Processor feature list
+ const SubtargetFeatureKV *ProcDesc; // Processor descriptions
+ const SubtargetInfoKV *ProcItins; // Scheduling itineraries
+ const InstrStage *Stages; // Instruction stages
+ const unsigned *OperandCycles; // Operand cycles
+ const unsigned *ForwardingPathes; // Forwarding pathes
+ unsigned NumFeatures; // Number of processor features
+ unsigned NumProcs; // Number of processors
+ uint64_t FeatureBits; // Feature bits for current CPU + FS
+
+public:
+ void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
+ const SubtargetFeatureKV *PF,
+ const SubtargetFeatureKV *PD,
+ const SubtargetInfoKV *PI, const InstrStage *IS,
+ const unsigned *OC, const unsigned *FP,
+ unsigned NF, unsigned NP);
+
+ /// getTargetTriple - Return the target triple string.
+ StringRef getTargetTriple() const {
+ return TargetTriple;
+ }
+
+ /// getFeatureBits - Return the feature bits.
+ ///
+ uint64_t getFeatureBits() const {
+ return FeatureBits;
+ }
+
+ /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
+ /// feature string), recompute and return feature bits.
+ uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS);
+
+ /// ToggleFeature - Toggle a feature and returns the re-computed feature
+ /// bits. This version does not change the implied bits.
+ uint64_t ToggleFeature(uint64_t FB);
+
+ /// ToggleFeature - Toggle a feature and returns the re-computed feature
+ /// bits. This version will also change all implied bits.
+ uint64_t ToggleFeature(StringRef FS);
+
+ /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
+ ///
+ InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCSymbol.h b/contrib/llvm/include/llvm/MC/MCSymbol.h
new file mode 100644
index 000000000000..0583ce56820b
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCSymbol.h
@@ -0,0 +1,164 @@
+//===- MCSymbol.h - Machine Code Symbols ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCSymbol class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSYMBOL_H
+#define LLVM_MC_MCSYMBOL_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+ class MCExpr;
+ class MCSection;
+ class MCContext;
+ class raw_ostream;
+
+ /// MCSymbol - Instances of this class represent a symbol name in the MC file,
+ /// and MCSymbols are created and unique'd by the MCContext class. MCSymbols
+ /// should only be constructed with valid names for the object file.
+ ///
+ /// If the symbol is defined/emitted into the current translation unit, the
+ /// Section member is set to indicate what section it lives in. Otherwise, if
+ /// it is a reference to an external entity, it has a null section.
+ class MCSymbol {
+ // Special sentinal value for the absolute pseudo section.
+ //
+ // FIXME: Use a PointerInt wrapper for this?
+ static const MCSection *AbsolutePseudoSection;
+
+ /// Name - The name of the symbol. The referred-to string data is actually
+ /// held by the StringMap that lives in MCContext.
+ StringRef Name;
+
+ /// Section - The section the symbol is defined in. This is null for
+ /// undefined symbols, and the special AbsolutePseudoSection value for
+ /// absolute symbols.
+ const MCSection *Section;
+
+ /// Value - If non-null, the value for a variable symbol.
+ const MCExpr *Value;
+
+ /// IsTemporary - True if this is an assembler temporary label, which
+ /// typically does not survive in the .o file's symbol table. Usually
+ /// "Lfoo" or ".foo".
+ unsigned IsTemporary : 1;
+
+ /// IsUsed - True if this symbol has been used.
+ mutable unsigned IsUsed : 1;
+
+ private: // MCContext creates and uniques these.
+ friend class MCExpr;
+ friend class MCContext;
+ MCSymbol(StringRef name, bool isTemporary)
+ : Name(name), Section(0), Value(0),
+ IsTemporary(isTemporary), IsUsed(false) {}
+
+ MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
+ void operator=(const MCSymbol&); // DO NOT IMPLEMENT
+ public:
+ /// getName - Get the symbol name.
+ StringRef getName() const { return Name; }
+
+ /// @name Accessors
+ /// @{
+
+ /// isTemporary - Check if this is an assembler temporary symbol.
+ bool isTemporary() const { return IsTemporary; }
+
+ /// isUsed - Check if this is used.
+ bool isUsed() const { return IsUsed; }
+ void setUsed(bool Value) const { IsUsed = Value; }
+
+ /// @}
+ /// @name Associated Sections
+ /// @{
+
+ /// isDefined - Check if this symbol is defined (i.e., it has an address).
+ ///
+ /// Defined symbols are either absolute or in some section.
+ bool isDefined() const {
+ return Section != 0;
+ }
+
+ /// isInSection - Check if this symbol is defined in some section (i.e., it
+ /// is defined but not absolute).
+ bool isInSection() const {
+ return isDefined() && !isAbsolute();
+ }
+
+ /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
+ bool isUndefined() const {
+ return !isDefined();
+ }
+
+ /// isAbsolute - Check if this is an absolute symbol.
+ bool isAbsolute() const {
+ return Section == AbsolutePseudoSection;
+ }
+
+ /// getSection - Get the section associated with a defined, non-absolute
+ /// symbol.
+ const MCSection &getSection() const {
+ assert(isInSection() && "Invalid accessor!");
+ return *Section;
+ }
+
+ /// setSection - Mark the symbol as defined in the section \arg S.
+ void setSection(const MCSection &S) { Section = &S; }
+
+ /// setUndefined - Mark the symbol as undefined.
+ void setUndefined() {
+ Section = 0;
+ }
+
+ /// setAbsolute - Mark the symbol as absolute.
+ void setAbsolute() { Section = AbsolutePseudoSection; }
+
+ /// @}
+ /// @name Variable Symbols
+ /// @{
+
+ /// isVariable - Check if this is a variable symbol.
+ bool isVariable() const {
+ return Value != 0;
+ }
+
+ /// getValue() - Get the value for variable symbols.
+ const MCExpr *getVariableValue() const {
+ assert(isVariable() && "Invalid accessor!");
+ IsUsed = true;
+ return Value;
+ }
+
+ // AliasedSymbol() - If this is an alias (a = b), return the symbol
+ // we ultimately point to. For a non alias, this just returns the symbol
+ // itself.
+ const MCSymbol &AliasedSymbol() const;
+
+ void setVariableValue(const MCExpr *Value);
+
+ /// @}
+
+ /// print - Print the value to the stream \arg OS.
+ void print(raw_ostream &OS) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
+ }
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h b/contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h
new file mode 100644
index 000000000000..acb3d4d6144c
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCTargetAsmLexer.h
@@ -0,0 +1,89 @@
+//===-- 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 &); // DO NOT IMPLEMENT
+ void operator=(const MCTargetAsmLexer &); // DO NOT IMPLEMENT
+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/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h b/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h
new file mode 100644
index 000000000000..4e3fd0d3a9ec
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCTargetAsmParser.h
@@ -0,0 +1,103 @@
+//===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- 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_TARGETPARSER_H
+#define LLVM_MC_TARGETPARSER_H
+
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+
+namespace llvm {
+class MCStreamer;
+class StringRef;
+class SMLoc;
+class AsmToken;
+class MCParsedAsmOperand;
+class MCInst;
+template <typename T> class SmallVectorImpl;
+
+/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
+class MCTargetAsmParser : public MCAsmParserExtension {
+public:
+ enum MatchResultTy {
+ Match_ConversionFail,
+ Match_InvalidOperand,
+ Match_MissingFeature,
+ Match_MnemonicFail,
+ Match_Success,
+ FIRST_TARGET_MATCH_RESULT_TY
+ };
+
+private:
+ MCTargetAsmParser(const MCTargetAsmParser &); // DO NOT IMPLEMENT
+ void operator=(const MCTargetAsmParser &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ MCTargetAsmParser();
+
+ /// AvailableFeatures - The current set of available features.
+ unsigned AvailableFeatures;
+
+public:
+ virtual ~MCTargetAsmParser();
+
+ unsigned getAvailableFeatures() const { return AvailableFeatures; }
+ void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+
+ virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
+ SMLoc &EndLoc) = 0;
+
+ /// ParseInstruction - Parse one assembly instruction.
+ ///
+ /// The parser is positioned following the instruction name. The target
+ /// specific instruction parser should parse the entire instruction and
+ /// construct the appropriate MCInst, or emit an error. On success, the entire
+ /// line should be parsed up to and including the end-of-statement token. On
+ /// failure, the parser is not required to read to the end of the line.
+ //
+ /// \param Name - The instruction name.
+ /// \param NameLoc - The source location of the name.
+ /// \param Operands [out] - The list of parsed operands, this returns
+ /// ownership of them to the caller.
+ /// \return True on failure.
+ virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
+
+ /// ParseDirective - Parse a target specific assembler directive
+ ///
+ /// The parser is positioned following the directive name. The target
+ /// specific directive parser should parse the entire directive doing or
+ /// recording any target specific work, or return true and do nothing if the
+ /// directive is not target specific. If the directive is specific for
+ /// the target, the entire line is parsed up to and including the
+ /// end-of-statement token and false is returned.
+ ///
+ /// \param DirectiveID - the identifier token of the directive.
+ virtual bool ParseDirective(AsmToken DirectiveID) = 0;
+
+ /// MatchAndEmitInstruction - Recognize a series of operands of a parsed
+ /// instruction as an actual MCInst and emit it to the specified MCStreamer.
+ /// 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
+ MatchAndEmitInstruction(SMLoc IDLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCStreamer &Out) = 0;
+
+ /// checkTargetMatchPredicate - Validate the instruction match against
+ /// any complex target predicates not expressible via match classes.
+ virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
+ return Match_Success;
+ }
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCValue.h b/contrib/llvm/include/llvm/MC/MCValue.h
new file mode 100644
index 000000000000..8352ed183f09
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCValue.h
@@ -0,0 +1,77 @@
+//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MCValue class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCVALUE_H
+#define LLVM_MC_MCVALUE_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/MC/MCSymbol.h"
+#include <cassert>
+
+namespace llvm {
+class MCAsmInfo;
+class MCSymbol;
+class MCSymbolRefExpr;
+class raw_ostream;
+
+/// MCValue - This represents an "assembler immediate". In its most general
+/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports
+/// relocations of this general form, but we need to represent this anyway.
+///
+/// In the general form, SymbolB can only be defined if SymbolA is, and both
+/// must be in the same (non-external) section. The latter constraint is not
+/// enforced, since a symbol's section may not be known at construction.
+///
+/// Note that this class must remain a simple POD value class, because we need
+/// it to live in unions etc.
+class MCValue {
+ const MCSymbolRefExpr *SymA, *SymB;
+ int64_t Cst;
+public:
+
+ int64_t getConstant() const { return Cst; }
+ const MCSymbolRefExpr *getSymA() const { return SymA; }
+ const MCSymbolRefExpr *getSymB() const { return SymB; }
+
+ /// 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.
+ void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
+
+ /// dump - Print the value to stderr.
+ void dump() const;
+
+ static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0,
+ int64_t Val = 0) {
+ MCValue R;
+ assert((!SymB || SymA) && "Invalid relocatable MCValue!");
+ R.Cst = Val;
+ R.SymA = SymA;
+ R.SymB = SymB;
+ return R;
+ }
+
+ static MCValue get(int64_t Val) {
+ MCValue R;
+ R.Cst = Val;
+ R.SymA = 0;
+ R.SymB = 0;
+ return R;
+ }
+
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCWin64EH.h b/contrib/llvm/include/llvm/MC/MCWin64EH.h
new file mode 100644
index 000000000000..eb4665a2e994
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCWin64EH.h
@@ -0,0 +1,93 @@
+//===- MCWin64EH.h - Machine Code Win64 EH support --------------*- 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 declarations to support the Win64 Exception Handling
+// scheme in MC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWIN64EH_H
+#define LLVM_MC_MCWIN64EH_H
+
+#include "llvm/Support/Win64EH.h"
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+ class StringRef;
+ class MCStreamer;
+ class MCSymbol;
+
+ class MCWin64EHInstruction {
+ public:
+ typedef Win64EH::UnwindOpcodes OpType;
+ private:
+ OpType Operation;
+ MCSymbol *Label;
+ unsigned Offset;
+ unsigned Register;
+ public:
+ MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg)
+ : Operation(Op), Label(L), Offset(0), Register(Reg) {
+ assert(Op == Win64EH::UOP_PushNonVol);
+ }
+ MCWin64EHInstruction(MCSymbol *L, unsigned Size)
+ : Operation(Size>128 ? Win64EH::UOP_AllocLarge : Win64EH::UOP_AllocSmall),
+ Label(L), Offset(Size) { }
+ MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off)
+ : Operation(Op), Label(L), Offset(Off), Register(Reg) {
+ assert(Op == Win64EH::UOP_SetFPReg ||
+ Op == Win64EH::UOP_SaveNonVol ||
+ Op == Win64EH::UOP_SaveNonVolBig ||
+ Op == Win64EH::UOP_SaveXMM128 ||
+ Op == Win64EH::UOP_SaveXMM128Big);
+ }
+ MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code)
+ : Operation(Op), Label(L), Offset(Code ? 1 : 0) {
+ assert(Op == Win64EH::UOP_PushMachFrame);
+ }
+ OpType getOperation() const { return Operation; }
+ MCSymbol *getLabel() const { return Label; }
+ unsigned getOffset() const { return Offset; }
+ unsigned getSize() const { return Offset; }
+ unsigned getRegister() const { return Register; }
+ bool isPushCodeFrame() const { return Offset == 1; }
+ };
+
+ struct MCWin64EHUnwindInfo {
+ MCWin64EHUnwindInfo() : Begin(0), End(0), ExceptionHandler(0),
+ Function(0), PrologEnd(0), Symbol(0),
+ HandlesUnwind(false), HandlesExceptions(false),
+ LastFrameInst(-1), ChainedParent(0),
+ Instructions() {}
+ MCSymbol *Begin;
+ MCSymbol *End;
+ const MCSymbol *ExceptionHandler;
+ const MCSymbol *Function;
+ MCSymbol *PrologEnd;
+ MCSymbol *Symbol;
+ bool HandlesUnwind;
+ bool HandlesExceptions;
+ int LastFrameInst;
+ MCWin64EHUnwindInfo *ChainedParent;
+ std::vector<MCWin64EHInstruction> Instructions;
+ };
+
+ class MCWin64EHUnwindEmitter {
+ public:
+ static StringRef GetSectionSuffix(const MCSymbol *func);
+ //
+ // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
+ //
+ static void Emit(MCStreamer &streamer);
+ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info);
+ };
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h b/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
new file mode 100644
index 000000000000..7a0b1ffaf0a0
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -0,0 +1,36 @@
+//===-- llvm/MC/MCWinCOFFObjectWriter.h - Win COFF Object Writer *- 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_MCWINCOFFOBJECTWRITER_H
+#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
+
+namespace llvm {
+ class MCWinCOFFObjectTargetWriter {
+ const unsigned Machine;
+
+ protected:
+ MCWinCOFFObjectTargetWriter(unsigned Machine_);
+
+ public:
+ virtual ~MCWinCOFFObjectTargetWriter() {}
+
+ unsigned getMachine() const { return Machine; }
+ virtual unsigned getRelocType(unsigned FixupKind) const = 0;
+ };
+
+ /// \brief Construct a new Win COFF writer instance.
+ ///
+ /// \param MOTW - The target specific WinCOFF writer subclass.
+ /// \param OS - The stream to write to.
+ /// \returns The constructed object writer.
+ MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW,
+ raw_ostream &OS);
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/MachineLocation.h b/contrib/llvm/include/llvm/MC/MachineLocation.h
new file mode 100644
index 000000000000..8ddfdbcece49
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/MachineLocation.h
@@ -0,0 +1,98 @@
+//===-- llvm/MC/MachineLocation.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// The MachineLocation class is used to represent a simple location in a machine
+// frame. Locations will be one of two forms; a register or an address formed
+// from a base address plus an offset. Register indirection can be specified by
+// using an offset of zero.
+//
+// The MachineMove class is used to represent abstract move operations in the
+// prolog/epilog of a compiled function. A collection of these objects can be
+// used by a debug consumer to track the location of values when unwinding stack
+// frames.
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_MC_MACHINELOCATION_H
+#define LLVM_MC_MACHINELOCATION_H
+
+namespace llvm {
+ class MCSymbol;
+
+class MachineLocation {
+private:
+ bool IsRegister; // True if location is a register.
+ unsigned Register; // gcc/gdb register number.
+ int Offset; // Displacement if not register.
+public:
+ enum {
+ // The target register number for an abstract frame pointer. The value is
+ // an arbitrary value that doesn't collide with any real target register.
+ VirtualFP = ~0U
+ };
+ MachineLocation()
+ : IsRegister(false), Register(0), Offset(0) {}
+ explicit MachineLocation(unsigned R)
+ : IsRegister(true), Register(R), Offset(0) {}
+ MachineLocation(unsigned R, int O)
+ : IsRegister(false), Register(R), Offset(O) {}
+
+ bool operator==(const MachineLocation &Other) const {
+ return IsRegister == Other.IsRegister && Register == Other.Register &&
+ Offset == Other.Offset;
+ }
+
+ // Accessors
+ bool isReg() const { return IsRegister; }
+ unsigned getReg() const { return Register; }
+ int getOffset() const { return Offset; }
+ void setIsRegister(bool Is) { IsRegister = Is; }
+ void setRegister(unsigned R) { Register = R; }
+ void setOffset(int O) { Offset = O; }
+ void set(unsigned R) {
+ IsRegister = true;
+ Register = R;
+ Offset = 0;
+ }
+ void set(unsigned R, int O) {
+ IsRegister = false;
+ Register = R;
+ Offset = O;
+ }
+
+#ifndef NDEBUG
+ void dump();
+#endif
+};
+
+/// MachineMove - This class represents the save or restore of a callee saved
+/// register that exception or debug info needs to know about.
+class MachineMove {
+private:
+ /// Label - Symbol for post-instruction address when result of move takes
+ /// effect.
+ MCSymbol *Label;
+
+ // Move to & from location.
+ MachineLocation Destination, Source;
+public:
+ MachineMove() : Label(0) {}
+
+ MachineMove(MCSymbol *label, const MachineLocation &D,
+ const MachineLocation &S)
+ : Label(label), Destination(D), Source(S) {}
+
+ // Accessors
+ MCSymbol *getLabel() const { return Label; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/SectionKind.h b/contrib/llvm/include/llvm/MC/SectionKind.h
new file mode 100644
index 000000000000..85a91c6b1698
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/SectionKind.h
@@ -0,0 +1,240 @@
+//===-- llvm/Target/TargetLoweringObjectFile.h - Object Info ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SECTIONKIND_H
+#define LLVM_MC_SECTIONKIND_H
+
+namespace llvm {
+
+/// SectionKind - This is a simple POD value that classifies the properties of
+/// a section. A section is classified into the deepest possible
+/// classification, and then the target maps them onto their sections based on
+/// what capabilities they have.
+///
+/// The comments below describe these as if they were an inheritance hierarchy
+/// in order to explain the predicates below.
+///
+class SectionKind {
+ enum Kind {
+ /// Metadata - Debug info sections or other metadata.
+ Metadata,
+
+ /// Text - Text section, used for functions and other executable code.
+ Text,
+
+ /// ReadOnly - Data that is never written to at program runtime by the
+ /// program or the dynamic linker. Things in the top-level readonly
+ /// SectionKind are not mergeable.
+ ReadOnly,
+
+ /// MergableCString - Any null-terminated string which allows merging.
+ /// These values are known to end in a nul value of the specified size,
+ /// not otherwise contain a nul value, and be mergable. This allows the
+ /// linker to unique the strings if it so desires.
+
+ /// Mergeable1ByteCString - 1 byte mergable, null terminated, string.
+ Mergeable1ByteCString,
+
+ /// Mergeable2ByteCString - 2 byte mergable, null terminated, string.
+ Mergeable2ByteCString,
+
+ /// Mergeable4ByteCString - 4 byte mergable, null terminated, string.
+ Mergeable4ByteCString,
+
+ /// MergeableConst - These are sections for merging fixed-length
+ /// constants together. For example, this can be used to unique
+ /// constant pool entries etc.
+ MergeableConst,
+
+ /// MergeableConst4 - This is a section used by 4-byte constants,
+ /// for example, floats.
+ MergeableConst4,
+
+ /// MergeableConst8 - This is a section used by 8-byte constants,
+ /// for example, doubles.
+ MergeableConst8,
+
+ /// MergeableConst16 - This is a section used by 16-byte constants,
+ /// for example, vectors.
+ MergeableConst16,
+
+ /// Writeable - This is the base of all segments that need to be written
+ /// to during program runtime.
+
+ /// ThreadLocal - This is the base of all TLS segments. All TLS
+ /// objects must be writeable, otherwise there is no reason for them to
+ /// be thread local!
+
+ /// ThreadBSS - Zero-initialized TLS data objects.
+ ThreadBSS,
+
+ /// ThreadData - Initialized TLS data objects.
+ ThreadData,
+
+ /// GlobalWriteableData - Writeable data that is global (not thread
+ /// local).
+
+ /// BSS - Zero initialized writeable data.
+ BSS,
+
+ /// BSSLocal - This is BSS (zero initialized and writable) data
+ /// which has local linkage.
+ BSSLocal,
+
+ /// BSSExtern - This is BSS data with normal external linkage.
+ BSSExtern,
+
+ /// Common - Data with common linkage. These represent tentative
+ /// definitions, which always have a zero initializer and are never
+ /// marked 'constant'.
+ Common,
+
+ /// DataRel - This is the most general form of data that is written
+ /// to by the program, it can have random relocations to arbitrary
+ /// globals.
+ DataRel,
+
+ /// DataRelLocal - This is writeable data that has a non-zero
+ /// initializer and has relocations in it, but all of the
+ /// relocations are known to be within the final linked image
+ /// the global is linked into.
+ DataRelLocal,
+
+ /// DataNoRel - This is writeable data that has a non-zero
+ /// initializer, but whose initializer is known to have no
+ /// relocations.
+ DataNoRel,
+
+ /// ReadOnlyWithRel - These are global variables that are never
+ /// written to by the program, but that have relocations, so they
+ /// must be stuck in a writeable section so that the dynamic linker
+ /// can write to them. If it chooses to, the dynamic linker can
+ /// mark the pages these globals end up on as read-only after it is
+ /// done with its relocation phase.
+ ReadOnlyWithRel,
+
+ /// ReadOnlyWithRelLocal - This is data that is readonly by the
+ /// program, but must be writeable so that the dynamic linker
+ /// can perform relocations in it. This is used when we know
+ /// that all the relocations are to globals in this final
+ /// linked image.
+ ReadOnlyWithRelLocal
+
+ } K : 8;
+public:
+
+ bool isMetadata() const { return K == Metadata; }
+ bool isText() const { return K == Text; }
+
+ bool isReadOnly() const {
+ return K == ReadOnly || isMergeableCString() ||
+ isMergeableConst();
+ }
+
+ bool isMergeableCString() const {
+ return K == Mergeable1ByteCString || K == Mergeable2ByteCString ||
+ K == Mergeable4ByteCString;
+ }
+ bool isMergeable1ByteCString() const { return K == Mergeable1ByteCString; }
+ bool isMergeable2ByteCString() const { return K == Mergeable2ByteCString; }
+ bool isMergeable4ByteCString() const { return K == Mergeable4ByteCString; }
+
+ bool isMergeableConst() const {
+ return K == MergeableConst || K == MergeableConst4 ||
+ K == MergeableConst8 || K == MergeableConst16;
+ }
+ bool isMergeableConst4() const { return K == MergeableConst4; }
+ bool isMergeableConst8() const { return K == MergeableConst8; }
+ bool isMergeableConst16() const { return K == MergeableConst16; }
+
+ bool isWriteable() const {
+ return isThreadLocal() || isGlobalWriteableData();
+ }
+
+ bool isThreadLocal() const {
+ return K == ThreadData || K == ThreadBSS;
+ }
+
+ bool isThreadBSS() const { return K == ThreadBSS; }
+ bool isThreadData() const { return K == ThreadData; }
+
+ bool isGlobalWriteableData() const {
+ return isBSS() || isCommon() || isDataRel() || isReadOnlyWithRel();
+ }
+
+ bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; }
+ bool isBSSLocal() const { return K == BSSLocal; }
+ bool isBSSExtern() const { return K == BSSExtern; }
+
+ bool isCommon() const { return K == Common; }
+
+ bool isDataRel() const {
+ return K == DataRel || K == DataRelLocal || K == DataNoRel;
+ }
+
+ bool isDataRelLocal() const {
+ return K == DataRelLocal || K == DataNoRel;
+ }
+
+ bool isDataNoRel() const { return K == DataNoRel; }
+
+ bool isReadOnlyWithRel() const {
+ return K == ReadOnlyWithRel || K == ReadOnlyWithRelLocal;
+ }
+
+ bool isReadOnlyWithRelLocal() const {
+ return K == ReadOnlyWithRelLocal;
+ }
+private:
+ static SectionKind get(Kind K) {
+ SectionKind Res;
+ Res.K = K;
+ return Res;
+ }
+public:
+
+ static SectionKind getMetadata() { return get(Metadata); }
+ static SectionKind getText() { return get(Text); }
+ static SectionKind getReadOnly() { return get(ReadOnly); }
+ static SectionKind getMergeable1ByteCString() {
+ return get(Mergeable1ByteCString);
+ }
+ static SectionKind getMergeable2ByteCString() {
+ return get(Mergeable2ByteCString);
+ }
+ static SectionKind getMergeable4ByteCString() {
+ return get(Mergeable4ByteCString);
+ }
+ static SectionKind getMergeableConst() { return get(MergeableConst); }
+ static SectionKind getMergeableConst4() { return get(MergeableConst4); }
+ static SectionKind getMergeableConst8() { return get(MergeableConst8); }
+ static SectionKind getMergeableConst16() { return get(MergeableConst16); }
+ static SectionKind getThreadBSS() { return get(ThreadBSS); }
+ static SectionKind getThreadData() { return get(ThreadData); }
+ static SectionKind getBSS() { return get(BSS); }
+ static SectionKind getBSSLocal() { return get(BSSLocal); }
+ static SectionKind getBSSExtern() { return get(BSSExtern); }
+ static SectionKind getCommon() { return get(Common); }
+ static SectionKind getDataRel() { return get(DataRel); }
+ static SectionKind getDataRelLocal() { return get(DataRelLocal); }
+ static SectionKind getDataNoRel() { return get(DataNoRel); }
+ static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
+ static SectionKind getReadOnlyWithRelLocal(){
+ return get(ReadOnlyWithRelLocal);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/MC/SubtargetFeature.h b/contrib/llvm/include/llvm/MC/SubtargetFeature.h
new file mode 100644
index 000000000000..1a7dc927da49
--- /dev/null
+++ b/contrib/llvm/include/llvm/MC/SubtargetFeature.h
@@ -0,0 +1,115 @@
+//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- 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 and manages user or tool specified CPU characteristics.
+// The intent is to be able to package specific features that should or should
+// not be used on a specific target processor. A tool, such as llc, could, as
+// as example, gather chip info from the command line, a long with features
+// that should be used on that chip.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_SUBTARGETFEATURE_H
+#define LLVM_MC_SUBTARGETFEATURE_H
+
+#include <vector>
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class raw_ostream;
+ class StringRef;
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatureKV - Used to provide key value pairs for feature and
+/// CPU bit flags.
+//
+struct SubtargetFeatureKV {
+ const char *Key; // K-V key string
+ const char *Desc; // Help descriptor
+ uint64_t Value; // K-V integer value
+ uint64_t Implies; // K-V bit mask
+
+ // Compare routine for std binary search
+ bool operator<(const SubtargetFeatureKV &S) const {
+ return strcmp(Key, S.Key) < 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
+/// pointers.
+//
+struct SubtargetInfoKV {
+ const char *Key; // K-V key string
+ void *Value; // K-V pointer value
+
+ // Compare routine for std binary search
+ bool operator<(const SubtargetInfoKV &S) const {
+ return strcmp(Key, S.Key) < 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatures - Manages the enabling and disabling of subtarget
+/// specific features. Features are encoded as a string of the form
+/// "cpu,+attr1,+attr2,-attr3,...,+attrN"
+/// A comma separates each feature from the next (all lowercase.)
+/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
+/// value is "generic" then the CPU subtype should be generic for the target.
+/// Each of the remaining features is prefixed with + or - indicating whether
+/// that feature should be enabled or disabled contrary to the cpu
+/// specification.
+///
+
+class SubtargetFeatures {
+ std::vector<std::string> Features; // Subtarget features as a vector
+public:
+ explicit SubtargetFeatures(const StringRef Initial = "");
+
+ /// Features string accessors.
+ std::string getString() const;
+
+ /// Adding Features.
+ void AddFeature(const StringRef String, bool IsEnabled = true);
+
+ /// ToggleFeature - Toggle a feature and returns the newly updated feature
+ /// bits.
+ uint64_t ToggleFeature(uint64_t Bits, const StringRef String,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize);
+
+ /// Get feature bits of a CPU.
+ uint64_t getFeatureBits(const StringRef CPU,
+ const SubtargetFeatureKV *CPUTable,
+ size_t CPUTableSize,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize);
+
+ /// Get scheduling itinerary of a CPU.
+ void *getItinerary(const StringRef CPU,
+ const SubtargetInfoKV *Table, size_t TableSize);
+
+ /// Print feature string.
+ void print(raw_ostream &OS) const;
+
+ // Dump feature info.
+ void dump() const;
+
+ /// Retrieve a formatted string of the default features for the specified
+ /// target triple.
+ void getDefaultSubtargetFeatures(const Triple& Triple);
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Metadata.h b/contrib/llvm/include/llvm/Metadata.h
new file mode 100644
index 000000000000..73579861ec41
--- /dev/null
+++ b/contrib/llvm/include/llvm/Metadata.h
@@ -0,0 +1,239 @@
+//===-- llvm/Metadata.h - Metadata definitions ------------------*- 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 contains the declarations for metadata subclasses.
+/// They represent the different flavors of metadata that live in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+class Constant;
+class Instruction;
+class LLVMContext;
+class Module;
+template <typename T> class SmallVectorImpl;
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+
+//===----------------------------------------------------------------------===//
+/// MDString - a single uniqued string.
+/// These are used to efficiently contain a byte sequence for metadata.
+/// MDString is always unnamed.
+class MDString : public Value {
+ virtual void anchor();
+ MDString(const MDString &); // DO NOT IMPLEMENT
+
+ explicit MDString(LLVMContext &C);
+public:
+ static MDString *get(LLVMContext &Context, StringRef Str);
+ static MDString *get(LLVMContext &Context, const char *Str) {
+ return get(Context, Str ? StringRef(Str) : StringRef());
+ }
+
+ StringRef getString() const { return getName(); }
+
+ unsigned getLength() const { return (unsigned)getName().size(); }
+
+ typedef StringRef::iterator iterator;
+
+ /// begin() - Pointer to the first byte of the string.
+ iterator begin() const { return getName().begin(); }
+
+ /// end() - Pointer to one byte past the end of the string.
+ 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;
+ }
+};
+
+
+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
+ friend class MDNodeOperand;
+ friend class LLVMContextImpl;
+ friend struct FoldingSetTrait<MDNode>;
+
+ /// Hash - If the MDNode is uniqued cache the hash to speed up lookup.
+ unsigned Hash;
+
+ /// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the
+ /// end of this MDNode.
+ unsigned NumOperands;
+
+ // Subclass data enums.
+ enum {
+ /// FunctionLocalBit - This bit is set if this MDNode is function local.
+ /// This is true when it (potentially transitively) contains a reference to
+ /// something in a function, like an argument, basicblock, or instruction.
+ FunctionLocalBit = 1 << 0,
+
+ /// NotUniquedBit - This is set on MDNodes that are not uniqued because they
+ /// have a null operand.
+ NotUniquedBit = 1 << 1,
+
+ /// DestroyFlag - This bit is set by destroy() so the destructor can assert
+ /// that the node isn't being destroyed with a plain 'delete'.
+ DestroyFlag = 1 << 2
+ };
+
+ // FunctionLocal enums.
+ enum FunctionLocalness {
+ FL_Unknown = -1,
+ FL_No = 0,
+ FL_Yes = 1
+ };
+
+ /// replaceOperand - Replace each instance of F from the operand list of this
+ /// node with T.
+ void replaceOperand(MDNodeOperand *Op, Value *NewVal);
+ ~MDNode();
+
+ MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);
+
+ static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,
+ FunctionLocalness FL, bool Insert = true);
+public:
+ // Constructors and destructors.
+ static MDNode *get(LLVMContext &Context, ArrayRef<Value*> Vals);
+ // getWhenValsUnresolved - Construct MDNode determining function-localness
+ // from isFunctionLocal argument, not by analyzing Vals.
+ static MDNode *getWhenValsUnresolved(LLVMContext &Context,
+ ArrayRef<Value*> Vals,
+ bool isFunctionLocal);
+
+ static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals);
+
+ /// getTemporary - Return a temporary MDNode, for use in constructing
+ /// cyclic MDNode structures. A temporary MDNode is not uniqued,
+ /// may be RAUW'd, and must be manually deleted with deleteTemporary.
+ static MDNode *getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals);
+
+ /// deleteTemporary - Deallocate a node created by getTemporary. The
+ /// node must not have any users.
+ static void deleteTemporary(MDNode *N);
+
+ /// replaceOperandWith - Replace a specific operand.
+ void replaceOperandWith(unsigned i, Value *NewVal);
+
+ /// getOperand - Return specified operand.
+ Value *getOperand(unsigned i) const;
+
+ /// getNumOperands - Return number of MDNode operands.
+ unsigned getNumOperands() const { return NumOperands; }
+
+ /// isFunctionLocal - Return whether MDNode is local to a function.
+ bool isFunctionLocal() const {
+ return (getSubclassDataFromValue() & FunctionLocalBit) != 0;
+ }
+
+ // getFunction - If this metadata is function-local and recursively has a
+ // function-local operand, return the first such operand's parent function.
+ // Otherwise, return null. getFunction() should not be used for performance-
+ // critical code because it recursively visits all the MDNode's operands.
+ const Function *getFunction() const;
+
+ /// Profile - calculate a unique identifier for this MDNode to collapse
+ /// duplicates
+ 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;
+ }
+private:
+ // destroy - Delete this node. Only when there are no uses.
+ void destroy();
+
+ bool isNotUniqued() const {
+ return (getSubclassDataFromValue() & NotUniquedBit) != 0;
+ }
+ void setIsNotUniqued();
+
+ // Shadow Value::setValueSubclassData with a private forwarding method so that
+ // any future subclasses cannot accidentally use it.
+ void setValueSubclassData(unsigned short D) {
+ Value::setValueSubclassData(D);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// NamedMDNode - a tuple of MDNodes. Despite its name, a NamedMDNode isn't
+/// itself an MDNode. NamedMDNodes belong to modules, have names, and contain
+/// lists of MDNodes.
+class NamedMDNode : public ilist_node<NamedMDNode> {
+ friend class SymbolTableListTraits<NamedMDNode, Module>;
+ friend struct ilist_traits<NamedMDNode>;
+ friend class LLVMContextImpl;
+ friend class Module;
+ NamedMDNode(const NamedMDNode &); // DO NOT IMPLEMENT
+
+ std::string Name;
+ Module *Parent;
+ void *Operands; // SmallVector<TrackingVH<MDNode>, 4>
+
+ void setParent(Module *M) { Parent = M; }
+
+ explicit NamedMDNode(const Twine &N);
+
+public:
+ /// eraseFromParent - Drop all references and remove the node from parent
+ /// module.
+ void eraseFromParent();
+
+ /// dropAllReferences - Remove all uses and clear node vector.
+ void dropAllReferences();
+
+ /// ~NamedMDNode - Destroy NamedMDNode.
+ ~NamedMDNode();
+
+ /// getParent - Get the module that holds this named metadata collection.
+ inline Module *getParent() { return Parent; }
+ inline const Module *getParent() const { return Parent; }
+
+ /// getOperand - Return specified operand.
+ MDNode *getOperand(unsigned i) const;
+
+ /// getNumOperands - Return the number of NamedMDNode operands.
+ unsigned getNumOperands() const;
+
+ /// addOperand - Add metadata operand.
+ void addOperand(MDNode *M);
+
+ /// getName - Return a constant reference to this named metadata's name.
+ StringRef getName() const;
+
+ /// print - Implement operator<< on NamedMDNode.
+ void print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW = 0) const;
+
+ /// dump() - Allow printing of NamedMDNodes from the debugger.
+ void dump() const;
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Module.h b/contrib/llvm/include/llvm/Module.h
new file mode 100644
index 000000000000..b9c98814f159
--- /dev/null
+++ b/contrib/llvm/include/llvm/Module.h
@@ -0,0 +1,602 @@
+//===-- llvm/Module.h - C++ class to represent a VM module ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// Module.h This file contains the declarations for the Module class.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class FunctionType;
+class GVMaterializer;
+class LLVMContext;
+class StructType;
+template<typename T> struct DenseMapInfo;
+template<typename KeyT, typename ValueT, typename KeyInfoT> class DenseMap;
+
+template<> struct ilist_traits<Function>
+ : public SymbolTableListTraits<Function, Module> {
+
+ // createSentinel is used to get hold of the node that marks the end of the
+ // list... (same trick used here as in ilist_traits<Instruction>)
+ Function *createSentinel() const {
+ return static_cast<Function*>(&Sentinel);
+ }
+ static void destroySentinel(Function*) {}
+
+ Function *provideInitialHead() const { return createSentinel(); }
+ Function *ensureHead(Function*) const { return createSentinel(); }
+ static void noteHead(Function*, Function*) {}
+
+private:
+ mutable ilist_node<Function> Sentinel;
+};
+
+template<> struct ilist_traits<GlobalVariable>
+ : public SymbolTableListTraits<GlobalVariable, Module> {
+ // createSentinel is used to create a node that marks the end of the list.
+ GlobalVariable *createSentinel() const {
+ return static_cast<GlobalVariable*>(&Sentinel);
+ }
+ static void destroySentinel(GlobalVariable*) {}
+
+ GlobalVariable *provideInitialHead() const { return createSentinel(); }
+ GlobalVariable *ensureHead(GlobalVariable*) const { return createSentinel(); }
+ static void noteHead(GlobalVariable*, GlobalVariable*) {}
+private:
+ mutable ilist_node<GlobalVariable> Sentinel;
+};
+
+template<> struct ilist_traits<GlobalAlias>
+ : public SymbolTableListTraits<GlobalAlias, Module> {
+ // createSentinel is used to create a node that marks the end of the list.
+ GlobalAlias *createSentinel() const {
+ return static_cast<GlobalAlias*>(&Sentinel);
+ }
+ static void destroySentinel(GlobalAlias*) {}
+
+ GlobalAlias *provideInitialHead() const { return createSentinel(); }
+ GlobalAlias *ensureHead(GlobalAlias*) const { return createSentinel(); }
+ static void noteHead(GlobalAlias*, GlobalAlias*) {}
+private:
+ mutable ilist_node<GlobalAlias> Sentinel;
+};
+
+template<> struct ilist_traits<NamedMDNode>
+ : public ilist_default_traits<NamedMDNode> {
+ // createSentinel is used to get hold of a node that marks the end of
+ // the list...
+ NamedMDNode *createSentinel() const {
+ return static_cast<NamedMDNode*>(&Sentinel);
+ }
+ static void destroySentinel(NamedMDNode*) {}
+
+ NamedMDNode *provideInitialHead() const { return createSentinel(); }
+ NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); }
+ static void noteHead(NamedMDNode*, NamedMDNode*) {}
+ void addNodeToList(NamedMDNode *) {}
+ void removeNodeFromList(NamedMDNode *) {}
+private:
+ mutable ilist_node<NamedMDNode> Sentinel;
+};
+
+/// A Module instance is used to store all the information related to an
+/// LLVM module. Modules are the top level container of all other LLVM
+/// Intermediate Representation (IR) objects. Each module directly contains a
+/// list of globals variables, a list of functions, a list of libraries (or
+/// other modules) this module depends on, a symbol table, and various data
+/// about the target's characteristics.
+///
+/// A module maintains a GlobalValRefMap object that is used to hold all
+/// constant references to global variables in the module. When a global
+/// variable is destroyed, it should have no entries in the GlobalValueRefMap.
+/// @brief The main container class for the LLVM Intermediate Representation.
+class Module {
+/// @name Types And Enumerations
+/// @{
+public:
+ /// The type for the list of global variables.
+ typedef iplist<GlobalVariable> GlobalListType;
+ /// The type for the list of functions.
+ typedef iplist<Function> FunctionListType;
+ /// The type for the list of aliases.
+ typedef iplist<GlobalAlias> AliasListType;
+ /// 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.
+ typedef GlobalListType::const_iterator const_global_iterator;
+
+ /// The Function iterators.
+ typedef FunctionListType::iterator iterator;
+ /// The Function constant iterator
+ typedef FunctionListType::const_iterator const_iterator;
+
+ /// The Global Alias iterators.
+ typedef AliasListType::iterator alias_iterator;
+ /// The Global Alias constant iterator
+ typedef AliasListType::const_iterator const_alias_iterator;
+
+ /// The named metadata iterators.
+ 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 };
+
+ /// An enumeration for describing the size of a pointer on the target machine.
+ enum PointerSize { AnyPointerSize, Pointer32, Pointer64 };
+
+ /// An enumeration for the supported behaviors of module flags. The following
+ /// module flags behavior values are supported:
+ ///
+ /// Value Behavior
+ /// ----- --------
+ /// 1 Error
+ /// Emits an error if two values disagree.
+ ///
+ /// 2 Warning
+ /// Emits a warning if two values disagree.
+ ///
+ /// 3 Require
+ /// Emits an error when the specified value is not present
+ /// or doesn't have the specified value. It is an error for
+ /// two (or more) llvm.module.flags with the same ID to have
+ /// the Require behavior but different values. There may be
+ /// multiple Require flags per ID.
+ ///
+ /// 4 Override
+ /// Uses the specified value if the two values disagree. It
+ /// is an error for two (or more) llvm.module.flags with the
+ /// same ID to have the Override behavior but different
+ /// values.
+ enum ModFlagBehavior { Error = 1, Warning = 2, Require = 3, Override = 4 };
+
+ struct ModuleFlagEntry {
+ ModFlagBehavior Behavior;
+ MDString *Key;
+ Value *Val;
+ ModuleFlagEntry(ModFlagBehavior B, MDString *K, Value *V)
+ : Behavior(B), Key(K), Val(V) {}
+ };
+
+/// @}
+/// @name Member Variables
+/// @{
+private:
+ LLVMContext &Context; ///< The LLVMContext from which types and
+ ///< constants are allocated.
+ 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
+ OwningPtr<GVMaterializer> Materializer; ///< Used to materialize GlobalValues
+ std::string ModuleID; ///< Human readable identifier for the module
+ std::string TargetTriple; ///< Platform target triple Module compiled on
+ std::string DataLayout; ///< Target data description
+ void *NamedMDSymTab; ///< NamedMDNode names.
+
+ friend class Constant;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+ /// The Module constructor. Note that there is no default constructor. You
+ /// must provide a name for the module upon construction.
+ explicit Module(StringRef ModuleID, LLVMContext& C);
+ /// The module destructor. This will dropAllReferences.
+ ~Module();
+
+/// @}
+/// @name Module Level Accessors
+/// @{
+
+ /// Get the module identifier which is, essentially, the name of the module.
+ /// @returns the module identifier as a string
+ const std::string &getModuleIdentifier() const { return ModuleID; }
+
+ /// Get the data layout string for the module's target platform. This encodes
+ /// the type sizes and alignments expected by this module.
+ /// @returns the data layout as a string
+ const std::string &getDataLayout() const { return DataLayout; }
+
+ /// Get the target triple which is a string describing the target host.
+ /// @returns a string containing the target triple.
+ const std::string &getTargetTriple() const { return TargetTriple; }
+
+ /// Get the target endian information.
+ /// @returns Endianess - an enumeration for the endianess of the target
+ Endianness getEndianness() const;
+
+ /// Get the target pointer size.
+ /// @returns PointerSize - an enumeration for the size of the target's pointer
+ PointerSize getPointerSize() const;
+
+ /// Get the global data context.
+ /// @returns LLVMContext - a container for LLVM's global information
+ LLVMContext &getContext() const { return Context; }
+
+ /// Get any module-scope inline assembly blocks.
+ /// @returns a string containing the module-scope inline assembly blocks.
+ const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; }
+
+/// @}
+/// @name Module Level Mutators
+/// @{
+
+ /// Set the module identifier.
+ void setModuleIdentifier(StringRef ID) { ModuleID = ID; }
+
+ /// Set the data layout
+ void setDataLayout(StringRef DL) { DataLayout = DL; }
+
+ /// Set the target triple.
+ void setTargetTriple(StringRef T) { TargetTriple = T; }
+
+ /// Set the module-scope inline assembly blocks.
+ void setModuleInlineAsm(StringRef Asm) {
+ GlobalScopeAsm = Asm;
+ if (!GlobalScopeAsm.empty() &&
+ GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
+ GlobalScopeAsm += '\n';
+ }
+
+ /// Append to the module-scope inline assembly blocks, automatically inserting
+ /// a separating newline if necessary.
+ void appendModuleInlineAsm(StringRef Asm) {
+ GlobalScopeAsm += Asm;
+ if (!GlobalScopeAsm.empty() &&
+ GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n')
+ GlobalScopeAsm += '\n';
+ }
+
+/// @}
+/// @name Generic Value Accessors
+/// @{
+
+ /// getNamedValue - Return the global value in the module with
+ /// the specified name, of arbitrary type. This method returns null
+ /// if a global with the specified name is not found.
+ GlobalValue *getNamedValue(StringRef Name) const;
+
+ /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
+ /// This ID is uniqued across modules in the current LLVMContext.
+ unsigned getMDKindID(StringRef Name) const;
+
+ /// getMDKindNames - Populate client supplied SmallVector with the name for
+ /// custom metadata IDs registered in this LLVMContext.
+ void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
+
+
+ typedef DenseMap<StructType*, unsigned, DenseMapInfo<StructType*> >
+ NumeredTypesMapTy;
+
+ /// findUsedStructTypes - Walk the entire module and find all of the
+ /// struct types that are in use, returning them in a vector.
+ void findUsedStructTypes(std::vector<StructType*> &StructTypes) const;
+
+ /// getTypeByName - Return the type with the specified name, or null if there
+ /// is none by that name.
+ StructType *getTypeByName(StringRef Name) const;
+
+/// @}
+/// @name Function Accessors
+/// @{
+
+ /// getOrInsertFunction - Look up the specified function in the module symbol
+ /// table. Four possibilities:
+ /// 1. If it does not exist, add a prototype for the function and return it.
+ /// 2. If it exists, and has a local linkage, the existing function is
+ /// renamed and a new one is inserted.
+ /// 3. Otherwise, if the existing function has the correct prototype, return
+ /// the existing function.
+ /// 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);
+
+ Constant *getOrInsertFunction(StringRef Name, FunctionType *T);
+
+ /// getOrInsertFunction - Look up the specified function in the module symbol
+ /// table. If it does not exist, add a prototype for the function and return
+ /// it. This function guarantees to return a constant of pointer to the
+ /// specified function type or a ConstantExpr BitCast of that type if the
+ /// named function has a different type. This version of the method takes a
+ /// null terminated list of function arguments, which makes it easier for
+ /// clients to use.
+ Constant *getOrInsertFunction(StringRef Name,
+ AttrListPtr AttributeList,
+ Type *RetTy, ...) END_WITH_NULL;
+
+ /// getOrInsertFunction - Same as above, but without the attributes.
+ Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...)
+ END_WITH_NULL;
+
+ Constant *getOrInsertTargetIntrinsic(StringRef Name,
+ FunctionType *Ty,
+ AttrListPtr AttributeList);
+
+ /// getFunction - Look up the specified function in the module symbol table.
+ /// If it does not exist, return null.
+ Function *getFunction(StringRef Name) const;
+
+/// @}
+/// @name Global Variable Accessors
+/// @{
+
+ /// getGlobalVariable - Look up the specified global variable in the module
+ /// symbol table. If it does not exist, return null. If AllowInternal is set
+ /// to true, this function will return types that have InternalLinkage. By
+ /// default, these types are not returned.
+ GlobalVariable *getGlobalVariable(StringRef Name,
+ bool AllowInternal = false) const;
+
+ /// getNamedGlobal - Return the global variable in the module with the
+ /// specified name, of arbitrary type. This method returns null if a global
+ /// with the specified name is not found.
+ GlobalVariable *getNamedGlobal(StringRef Name) const {
+ return getGlobalVariable(Name, true);
+ }
+
+ /// getOrInsertGlobal - Look up the specified global in the module symbol
+ /// table.
+ /// 1. If it does not exist, add a declaration of the global and return it.
+ /// 2. Else, the global exists but has the wrong type: return the function
+ /// with a constantexpr cast to the right type.
+ /// 3. Finally, if the existing global is the correct declaration, return
+ /// the existing global.
+ Constant *getOrInsertGlobal(StringRef Name, Type *Ty);
+
+/// @}
+/// @name Global Alias Accessors
+/// @{
+
+ /// getNamedAlias - Return the global alias in the module with the
+ /// specified name, of arbitrary type. This method returns null if a global
+ /// with the specified name is not found.
+ GlobalAlias *getNamedAlias(StringRef Name) const;
+
+/// @}
+/// @name Named Metadata Accessors
+/// @{
+
+ /// getNamedMetadata - Return the NamedMDNode in the module with the
+ /// specified name. This method returns null if a NamedMDNode with the
+ /// specified name is not found.
+ NamedMDNode *getNamedMetadata(const Twine &Name) const;
+
+ /// getOrInsertNamedMetadata - Return the named MDNode in the module
+ /// with the specified name. This method returns a new NamedMDNode if a
+ /// NamedMDNode with the specified name is not found.
+ NamedMDNode *getOrInsertNamedMetadata(StringRef Name);
+
+ /// eraseNamedMetadata - Remove the given NamedMDNode from this module
+ /// and delete it.
+ void eraseNamedMetadata(NamedMDNode *NMD);
+
+/// @}
+/// @name Module Flags Accessors
+/// @{
+
+ /// getModuleFlagsMetadata - Returns the module flags in the provided vector.
+ void getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const;
+
+ /// getModuleFlagsMetadata - Returns the NamedMDNode in the module that
+ /// represents module-level flags. This method returns null if there are no
+ /// module-level flags.
+ NamedMDNode *getModuleFlagsMetadata() const;
+
+ /// getOrInsertModuleFlagsMetadata - Returns the NamedMDNode in the module
+ /// that represents module-level flags. If module-level flags aren't found,
+ /// it creates the named metadata that contains them.
+ NamedMDNode *getOrInsertModuleFlagsMetadata();
+
+ /// addModuleFlag - Add a module-level flag to the module-level flags
+ /// metadata. It will create the module-level flags named metadata if it
+ /// doesn't already exist.
+ void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Value *Val);
+ void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val);
+ void addModuleFlag(MDNode *Node);
+
+/// @}
+/// @name Materialization
+/// @{
+
+ /// setMaterializer - Sets the GVMaterializer to GVM. This module must not
+ /// yet have a Materializer. To reset the materializer for a module that
+ /// already has one, call MaterializeAllPermanently first. Destroying this
+ /// module will destroy its materializer without materializing any more
+ /// GlobalValues. Without destroying the Module, there is no way to detach or
+ /// destroy a materializer without materializing all the GVs it controls, to
+ /// avoid leaving orphan unmaterialized GVs.
+ void setMaterializer(GVMaterializer *GVM);
+ /// getMaterializer - Retrieves the GVMaterializer, if any, for this Module.
+ GVMaterializer *getMaterializer() const { return Materializer.get(); }
+
+ /// isMaterializable - True if the definition of GV has yet to be materialized
+ /// from the GVMaterializer.
+ bool isMaterializable(const GlobalValue *GV) const;
+ /// isDematerializable - Returns true if this GV was loaded from this Module's
+ /// GVMaterializer and the GVMaterializer knows how to dematerialize the GV.
+ bool isDematerializable(const GlobalValue *GV) const;
+
+ /// Materialize - Make sure the GlobalValue is fully read. If the module is
+ /// corrupt, this returns true and fills in the optional string with
+ /// information about the problem. If successful, this returns false.
+ bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0);
+ /// Dematerialize - If the GlobalValue is read in, and if the GVMaterializer
+ /// supports it, release the memory for the function, and set it up to be
+ /// materialized lazily. If !isDematerializable(), this method is a noop.
+ void Dematerialize(GlobalValue *GV);
+
+ /// MaterializeAll - Make sure all GlobalValues in this Module are fully read.
+ /// If the module is corrupt, this returns true and fills in the optional
+ /// string with information about the problem. If successful, this returns
+ /// false.
+ bool MaterializeAll(std::string *ErrInfo = 0);
+
+ /// MaterializeAllPermanently - Make sure all GlobalValues in this Module are
+ /// fully read and clear the Materializer. If the module is corrupt, this
+ /// returns true, fills in the optional string with information about the
+ /// problem, and DOES NOT clear the old Materializer. If successful, this
+ /// returns false.
+ bool MaterializeAllPermanently(std::string *ErrInfo = 0);
+
+/// @}
+/// @name Direct access to the globals list, functions list, and symbol table
+/// @{
+
+ /// Get the Module's list of global variables (constant).
+ const GlobalListType &getGlobalList() const { return GlobalList; }
+ /// Get the Module's list of global variables.
+ GlobalListType &getGlobalList() { return GlobalList; }
+ static iplist<GlobalVariable> Module::*getSublistAccess(GlobalVariable*) {
+ return &Module::GlobalList;
+ }
+ /// Get the Module's list of functions (constant).
+ const FunctionListType &getFunctionList() const { return FunctionList; }
+ /// Get the Module's list of functions.
+ FunctionListType &getFunctionList() { return FunctionList; }
+ static iplist<Function> Module::*getSublistAccess(Function*) {
+ return &Module::FunctionList;
+ }
+ /// Get the Module's list of aliases (constant).
+ const AliasListType &getAliasList() const { return AliasList; }
+ /// Get the Module's list of aliases.
+ AliasListType &getAliasList() { return AliasList; }
+ static iplist<GlobalAlias> Module::*getSublistAccess(GlobalAlias*) {
+ return &Module::AliasList;
+ }
+ /// Get the symbol table of global variable and function identifiers
+ const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
+ /// Get the Module's symbol table of global variable and function identifiers.
+ ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
+
+/// @}
+/// @name Global Variable Iteration
+/// @{
+
+ global_iterator global_begin() { return GlobalList.begin(); }
+ const_global_iterator global_begin() const { return GlobalList.begin(); }
+ global_iterator global_end () { return GlobalList.end(); }
+ const_global_iterator global_end () const { return GlobalList.end(); }
+ bool global_empty() const { return GlobalList.empty(); }
+
+/// @}
+/// @name Function Iteration
+/// @{
+
+ iterator begin() { return FunctionList.begin(); }
+ const_iterator begin() const { return FunctionList.begin(); }
+ iterator end () { return FunctionList.end(); }
+ const_iterator end () const { return FunctionList.end(); }
+ size_t size() const { return FunctionList.size(); }
+ 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
+/// @{
+
+ alias_iterator alias_begin() { return AliasList.begin(); }
+ const_alias_iterator alias_begin() const { return AliasList.begin(); }
+ alias_iterator alias_end () { return AliasList.end(); }
+ const_alias_iterator alias_end () const { return AliasList.end(); }
+ size_t alias_size () const { return AliasList.size(); }
+ bool alias_empty() const { return AliasList.empty(); }
+
+
+/// @}
+/// @name Named Metadata Iteration
+/// @{
+
+ named_metadata_iterator named_metadata_begin() { return NamedMDList.begin(); }
+ const_named_metadata_iterator named_metadata_begin() const {
+ return NamedMDList.begin();
+ }
+
+ named_metadata_iterator named_metadata_end() { return NamedMDList.end(); }
+ const_named_metadata_iterator named_metadata_end() const {
+ return NamedMDList.end();
+ }
+
+ size_t named_metadata_size() const { return NamedMDList.size(); }
+ bool named_metadata_empty() const { return NamedMDList.empty(); }
+
+
+/// @}
+/// @name Utility functions for printing and dumping Module objects
+/// @{
+
+ /// Print the module to an output stream with an optional
+ /// AssemblyAnnotationWriter.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const;
+
+ /// Dump the module to stderr (for debugging).
+ void dump() const;
+
+ /// This function causes all the subinstructions to "let go" of all references
+ /// that they are maintaining. This allows one to 'delete' a whole class at
+ /// a time, even though there may be circular references... first all
+ /// references are dropped, and all use counts go to zero. Then everything
+ /// is delete'd for real. Note that no operations are valid on an object
+ /// that has "dropped all references", except operator delete.
+ void dropAllReferences();
+/// @}
+};
+
+/// An raw_ostream inserter for modules.
+inline raw_ostream &operator<<(raw_ostream &O, const Module &M) {
+ M.print(O, 0);
+ return O;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/Archive.h b/contrib/llvm/include/llvm/Object/Archive.h
new file mode 100644
index 000000000000..358b27a416cd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/Archive.h
@@ -0,0 +1,145 @@
+//===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ar archive file format class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ARCHIVE_H
+#define LLVM_OBJECT_ARCHIVE_H
+
+#include "llvm/Object/Binary.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+namespace object {
+
+class Archive : public Binary {
+ virtual void anchor();
+public:
+ class Child {
+ const Archive *Parent;
+ StringRef Data;
+
+ public:
+ Child(const Archive *p, StringRef d) : Parent(p), Data(d) {}
+
+ bool operator ==(const Child &other) const {
+ return (Parent == other.Parent) && (Data.begin() == other.Data.begin());
+ }
+
+ bool operator <(const Child &other) const {
+ return Data.begin() < other.Data.begin();
+ }
+
+ Child getNext() const;
+ error_code getName(StringRef &Result) const;
+ int getLastModified() const;
+ int getUID() const;
+ int getGID() const;
+ int getAccessMode() const;
+ ///! Return the size of the archive member without the header or padding.
+ uint64_t getSize() const;
+
+ MemoryBuffer *getBuffer() const;
+ error_code getAsBinary(OwningPtr<Binary> &Result) const;
+ };
+
+ class child_iterator {
+ Child child;
+ public:
+ child_iterator() : child(Child(0, StringRef())) {}
+ child_iterator(const Child &c) : child(c) {}
+ const Child* operator->() const {
+ return &child;
+ }
+
+ bool operator==(const child_iterator &other) const {
+ return child == other.child;
+ }
+
+ bool operator!=(const child_iterator &other) const {
+ return !(*this == other);
+ }
+
+ bool operator <(const child_iterator &other) const {
+ return child < other.child;
+ }
+
+ child_iterator& operator++() { // Preincrement
+ child = child.getNext();
+ return *this;
+ }
+ };
+
+ class Symbol {
+ const Archive *Parent;
+ uint32_t SymbolIndex;
+ uint32_t StringIndex; // Extra index to the string.
+
+ public:
+ bool operator ==(const Symbol &other) const {
+ return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
+ }
+
+ Symbol(const Archive *p, uint32_t symi, uint32_t stri)
+ : Parent(p)
+ , SymbolIndex(symi)
+ , StringIndex(stri) {}
+ error_code getName(StringRef &Result) const;
+ error_code getMember(child_iterator &Result) const;
+ Symbol getNext() const;
+ };
+
+ class symbol_iterator {
+ Symbol symbol;
+ public:
+ symbol_iterator(const Symbol &s) : symbol(s) {}
+ const Symbol *operator->() const {
+ return &symbol;
+ }
+
+ bool operator==(const symbol_iterator &other) const {
+ return symbol == other.symbol;
+ }
+
+ bool operator!=(const symbol_iterator &other) const {
+ return !(*this == other);
+ }
+
+ symbol_iterator& operator++() { // Preincrement
+ symbol = symbol.getNext();
+ return *this;
+ }
+ };
+
+ Archive(MemoryBuffer *source, error_code &ec);
+
+ child_iterator begin_children(bool skip_internal = true) const;
+ child_iterator end_children() const;
+
+ symbol_iterator begin_symbols() const;
+ 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();
+ }
+
+private:
+ child_iterator SymbolTable;
+ child_iterator StringTable;
+};
+
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/Binary.h b/contrib/llvm/include/llvm/Object/Binary.h
new file mode 100644
index 000000000000..77a08d597c4d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/Binary.h
@@ -0,0 +1,104 @@
+//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Binary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_BINARY_H
+#define LLVM_OBJECT_BINARY_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Object/Error.h"
+
+namespace llvm {
+
+class MemoryBuffer;
+class StringRef;
+
+namespace object {
+
+class Binary {
+private:
+ Binary(); // = delete
+ Binary(const Binary &other); // = delete
+
+ unsigned int TypeID;
+
+protected:
+ MemoryBuffer *Data;
+
+ Binary(unsigned int Type, MemoryBuffer *Source);
+
+ enum {
+ ID_Archive,
+ // Object and children.
+ ID_StartObjects,
+ ID_COFF,
+ ID_ELF32L, // ELF 32-bit, little endian
+ ID_ELF32B, // ELF 32-bit, big endian
+ ID_ELF64L, // ELF 64-bit, little endian
+ ID_ELF64B, // ELF 64-bit, big endian
+ ID_MachO,
+ ID_EndObjects
+ };
+
+ static inline unsigned int getELFType(bool isLittleEndian, bool is64Bits) {
+ if (isLittleEndian)
+ return is64Bits ? ID_ELF64L : ID_ELF32L;
+ else
+ return is64Bits ? ID_ELF64B : ID_ELF32B;
+ }
+
+public:
+ virtual ~Binary();
+
+ StringRef getData() const;
+ StringRef getFileName() const;
+
+ // Cast methods.
+ unsigned int getType() const { return TypeID; }
+ static inline bool classof(const Binary *v) { return true; }
+
+ // Convenience methods
+ bool isObject() const {
+ return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
+ }
+
+ bool isArchive() const {
+ return TypeID == ID_Archive;
+ }
+
+ bool isELF() const {
+ return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
+ }
+
+ bool isMachO() const {
+ return TypeID == ID_MachO;
+ }
+
+ bool isCOFF() const {
+ return TypeID == ID_COFF;
+ }
+};
+
+/// @brief Create a Binary from Source, autodetecting the file type.
+///
+/// @param Source The data to create the Binary from. Ownership is transfered
+/// to Result if successful. If an error is returned, Source is destroyed
+/// by createBinary before returning.
+/// @param Result A pointer to the resulting Binary if no error occured.
+error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result);
+
+error_code createBinary(StringRef Path, OwningPtr<Binary> &Result);
+
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/COFF.h b/contrib/llvm/include/llvm/Object/COFF.h
new file mode 100644
index 000000000000..68b5ca1bc781
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/COFF.h
@@ -0,0 +1,200 @@
+//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the COFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_H
+#define LLVM_OBJECT_COFF_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+ template <typename T>
+ class ArrayRef;
+
+namespace object {
+
+struct coff_file_header {
+ support::ulittle16_t Machine;
+ support::ulittle16_t NumberOfSections;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t PointerToSymbolTable;
+ support::ulittle32_t NumberOfSymbols;
+ support::ulittle16_t SizeOfOptionalHeader;
+ support::ulittle16_t Characteristics;
+};
+
+struct coff_symbol {
+ struct StringTableOffset {
+ support::ulittle32_t Zeroes;
+ support::ulittle32_t Offset;
+ };
+
+ union {
+ char ShortName[8];
+ StringTableOffset Offset;
+ } Name;
+
+ support::ulittle32_t Value;
+ support::little16_t SectionNumber;
+
+ support::ulittle16_t Type;
+
+ support::ulittle8_t StorageClass;
+ support::ulittle8_t NumberOfAuxSymbols;
+
+ uint8_t getBaseType() const {
+ return Type & 0x0F;
+ }
+
+ uint8_t getComplexType() const {
+ return (Type & 0xF0) >> 4;
+ }
+};
+
+struct coff_section {
+ char Name[8];
+ support::ulittle32_t VirtualSize;
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SizeOfRawData;
+ support::ulittle32_t PointerToRawData;
+ support::ulittle32_t PointerToRelocations;
+ support::ulittle32_t PointerToLinenumbers;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t Characteristics;
+};
+
+struct coff_relocation {
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SymbolTableIndex;
+ support::ulittle16_t Type;
+};
+
+struct coff_aux_section_definition {
+ support::ulittle32_t Length;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t Number;
+ support::ulittle8_t Selection;
+ char Unused[3];
+};
+
+class COFFObjectFile : public ObjectFile {
+private:
+ const coff_file_header *Header;
+ const coff_section *SectionTable;
+ const coff_symbol *SymbolTable;
+ const char *StringTable;
+ uint32_t StringTableSize;
+
+ error_code getString(uint32_t offset, StringRef &Res) const;
+
+ const coff_symbol *toSymb(DataRefImpl Symb) const;
+ const coff_section *toSec(DataRefImpl Sec) const;
+ const coff_relocation *toRel(DataRefImpl Rel) const;
+
+protected:
+ virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
+ virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
+ virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
+ virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
+ virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
+ virtual error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const;
+
+ virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
+ virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
+ 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 isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const;
+ virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const;
+ virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
+ virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
+
+ virtual error_code getRelocationNext(DataRefImpl Rel,
+ RelocationRef &Res) const;
+ virtual error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationSymbol(DataRefImpl Rel,
+ SymbolRef &Res) const;
+ virtual error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const;
+ virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
+ int64_t &Res) const;
+ virtual error_code getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const;
+
+ virtual error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Result) const;
+ virtual error_code getLibraryPath(DataRefImpl LibData,
+ StringRef &Result) const;
+
+public:
+ COFFObjectFile(MemoryBuffer *Object, error_code &ec);
+ virtual symbol_iterator begin_symbols() const;
+ virtual symbol_iterator end_symbols() const;
+ virtual symbol_iterator begin_dynamic_symbols() const;
+ virtual symbol_iterator end_dynamic_symbols() const;
+ virtual library_iterator begin_libraries_needed() const;
+ virtual library_iterator end_libraries_needed() const;
+ virtual section_iterator begin_sections() const;
+ virtual section_iterator end_sections() const;
+
+ virtual uint8_t getBytesInAddress() const;
+ virtual StringRef getFileFormatName() const;
+ virtual unsigned getArch() const;
+ virtual StringRef getLoadName() const;
+
+ error_code getHeader(const coff_file_header *&Res) const;
+ error_code getSection(int32_t index, const coff_section *&Res) const;
+ error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
+ template <typename T>
+ error_code getAuxSymbol(uint32_t index, const T *&Res) const {
+ const coff_symbol *s;
+ error_code ec = getSymbol(index, s);
+ Res = reinterpret_cast<const T*>(s);
+ return ec;
+ }
+ error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
+ error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
+ error_code getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const;
+
+ static inline bool classof(const Binary *v) {
+ return v->isCOFF();
+ }
+ static inline bool classof(const COFFObjectFile *v) { return true; }
+};
+
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/ELF.h b/contrib/llvm/include/llvm/Object/ELF.h
new file mode 100644
index 000000000000..e493f5bd9296
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/ELF.h
@@ -0,0 +1,2218 @@
+//===- ELF.h - ELF object file implementation -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ELFObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELF_H
+#define LLVM_OBJECT_ELF_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"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+namespace llvm {
+namespace object {
+
+// Subclasses of ELFObjectFile may need this for template instantiation
+inline std::pair<unsigned char, unsigned char>
+getElfArchType(MemoryBuffer *Object) {
+ if (Object->getBufferSize() < ELF::EI_NIDENT)
+ return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE);
+ return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS]
+ , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
+}
+
+// Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
+template<support::endianness target_endianness>
+struct ELFDataTypeTypedefHelperCommon {
+ typedef support::detail::packed_endian_specific_integral
+ <uint16_t, target_endianness, support::aligned> Elf_Half;
+ typedef support::detail::packed_endian_specific_integral
+ <uint32_t, target_endianness, support::aligned> Elf_Word;
+ typedef support::detail::packed_endian_specific_integral
+ <int32_t, target_endianness, support::aligned> Elf_Sword;
+ typedef support::detail::packed_endian_specific_integral
+ <uint64_t, target_endianness, support::aligned> Elf_Xword;
+ typedef support::detail::packed_endian_specific_integral
+ <int64_t, target_endianness, support::aligned> Elf_Sxword;
+};
+
+template<support::endianness target_endianness, bool is64Bits>
+struct ELFDataTypeTypedefHelper;
+
+/// ELF 32bit types.
+template<support::endianness target_endianness>
+struct ELFDataTypeTypedefHelper<target_endianness, false>
+ : ELFDataTypeTypedefHelperCommon<target_endianness> {
+ typedef uint32_t value_type;
+ typedef support::detail::packed_endian_specific_integral
+ <value_type, target_endianness, support::aligned> Elf_Addr;
+ typedef support::detail::packed_endian_specific_integral
+ <value_type, target_endianness, support::aligned> Elf_Off;
+};
+
+/// ELF 64bit types.
+template<support::endianness target_endianness>
+struct ELFDataTypeTypedefHelper<target_endianness, true>
+ : ELFDataTypeTypedefHelperCommon<target_endianness>{
+ typedef uint64_t value_type;
+ typedef support::detail::packed_endian_specific_integral
+ <value_type, target_endianness, support::aligned> Elf_Addr;
+ typedef support::detail::packed_endian_specific_integral
+ <value_type, target_endianness, support::aligned> 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;
+
+ // Section header.
+template<support::endianness target_endianness, 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)
+ Elf_Word sh_name; // Section name (index into string table)
+ Elf_Word sh_type; // Section type (SHT_*)
+ Elf_Word sh_flags; // Section flags (SHF_*)
+ Elf_Addr sh_addr; // Address where section is to be loaded
+ Elf_Off sh_offset; // File offset of section data, in bytes
+ Elf_Word sh_size; // Size of section, in bytes
+ Elf_Word sh_link; // Section type-specific header table index link
+ Elf_Word sh_info; // Section type-specific extra information
+ Elf_Word sh_addralign;// Section address alignment
+ 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)
+ Elf_Word sh_name; // Section name (index into string table)
+ Elf_Word sh_type; // Section type (SHT_*)
+ Elf_Xword sh_flags; // Section flags (SHF_*)
+ Elf_Addr sh_addr; // Address where section is to be loaded
+ Elf_Off sh_offset; // File offset of section data, in bytes
+ Elf_Xword sh_size; // Size of section, in bytes
+ Elf_Word sh_link; // Section type-specific header table index link
+ Elf_Word sh_info; // Section type-specific extra information
+ Elf_Xword sh_addralign;// Section address alignment
+ 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;
+
+ /// @brief Get the number of entities this section contains if it has any.
+ unsigned getEntityCount() const {
+ if (sh_entsize == 0)
+ return 0;
+ return sh_size / sh_entsize;
+ }
+};
+
+template<support::endianness target_endianness, 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)
+ 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
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ 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)
+ 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
+ Elf_Half st_shndx; // Which section (header table index) it's defined in
+ Elf_Addr st_value; // Value or address associated with the symbol
+ 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;
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding() const { return st_info >> 4; }
+ unsigned char getType() const { return st_info & 0x0f; }
+ void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+ void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+ void setBindingAndType(unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+};
+
+/// 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>
+struct Elf_Versym_Impl {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
+};
+
+template<support::endianness target_endianness, 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>
+struct Elf_Verdef_Impl {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+ typedef Elf_Verdaux_Impl<target_endianness, 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
+ Elf_Half vd_cnt; // Number of Verdaux entries
+ Elf_Word vd_hash; // Hash of name
+ Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes)
+ Elf_Word vd_next; // Offset to the next Verdef entry (in bytes)
+
+ /// Get the first Verdaux entry for this Verdef.
+ const Elf_Verdaux *getAux() const {
+ return reinterpret_cast<const Elf_Verdaux*>((const char*)this + vd_aux);
+ }
+};
+
+/// Elf_Verdaux: This is the structure of auxilary 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>
+struct Elf_Verdaux_Impl {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, 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>
+struct Elf_Verneed_Impl {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, 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)
+ Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes)
+ Elf_Word vn_next; // Offset to next Verneed entry (in bytes)
+};
+
+/// 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>
+struct Elf_Vernaux_Impl {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, 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
+ Elf_Word vna_name; // Dependency name
+ Elf_Word vna_next; // Offset to next Vernaux entry (in bytes)
+};
+
+/// 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>
+struct Elf_Dyn_Base;
+
+template<support::endianness target_endianness>
+struct Elf_Dyn_Base<target_endianness, false> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+ Elf_Sword d_tag;
+ union {
+ Elf_Word d_val;
+ Elf_Addr d_ptr;
+ } d_un;
+};
+
+template<support::endianness target_endianness>
+struct Elf_Dyn_Base<target_endianness, true> {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+ Elf_Sxword d_tag;
+ union {
+ Elf_Xword d_val;
+ Elf_Addr d_ptr;
+ } d_un;
+};
+
+/// 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;
+ 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>
+class ELFObjectFile;
+
+// DynRefImpl: Reference to an entry in the dynamic table
+// This is an ELF-specific interface.
+template<support::endianness target_endianness, bool is64Bits>
+class DynRefImpl {
+ typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn;
+ typedef ELFObjectFile<target_endianness, is64Bits> OwningType;
+
+ DataRefImpl DynPimpl;
+ const OwningType *OwningObject;
+
+public:
+ DynRefImpl() : OwningObject(NULL) { }
+
+ DynRefImpl(DataRefImpl DynP, const OwningType *Owner);
+
+ bool operator==(const DynRefImpl &Other) const;
+ bool operator <(const DynRefImpl &Other) const;
+
+ error_code getNext(DynRefImpl &Result) const;
+ int64_t getTag() const;
+ uint64_t getVal() const;
+ uint64_t getPtr() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+};
+
+// Elf_Rel: Elf Relocation
+template<support::endianness target_endianness, 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)
+ 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)
+ 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)
+ 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)
+ 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>
+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)
+
+ // 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);
+ }
+ 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);
+ }
+};
+
+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)
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ uint32_t getSymbol() const { return (r_info >> 8); }
+ unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); }
+ void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(uint32_t s, unsigned char t) {
+ r_info = (s << 8) + t;
+ }
+};
+
+
+template<support::endianness target_endianness, bool is64Bits>
+class ELFObjectFile : public ObjectFile {
+ LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
+
+ 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;
+ typedef content_iterator<DynRef> dyn_iterator;
+
+protected:
+ struct Elf_Ehdr {
+ 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_*)
+ Elf_Word e_version; // Must be equal to 1
+ Elf_Addr e_entry; // Address to jump to in order to start program
+ Elf_Off e_phoff; // Program header table's file offset, in bytes
+ Elf_Off e_shoff; // Section header table's file offset, in bytes
+ Elf_Word e_flags; // Processor-specific flags
+ Elf_Half e_ehsize; // Size of ELF header, in bytes
+ Elf_Half e_phentsize;// Size of an entry in the program header table
+ Elf_Half e_phnum; // Number of entries in the program header table
+ Elf_Half e_shentsize;// Size of an entry in the section header table
+ Elf_Half e_shnum; // Number of entries in the section header table
+ Elf_Half e_shstrndx; // Section header table index of section name
+ // string table
+ bool checkMagic() const {
+ return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
+ }
+ unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
+ unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
+ };
+ // This flag is used for classof, to distinguish ELFObjectFile from
+ // its subclass. If more subclasses will be created, this flag will
+ // have to become an enum.
+ bool isDyldELFObject;
+
+private:
+ typedef SmallVector<const Elf_Shdr*, 1> Sections_t;
+ typedef DenseMap<unsigned, unsigned> IndexMap_t;
+ typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
+
+ const Elf_Ehdr *Header;
+ const Elf_Shdr *SectionHeaderTable;
+ const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
+ const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
+ const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table.
+
+ // SymbolTableSections[0] always points to the dynamic string table section
+ // header, or NULL if there is no dynamic string table.
+ Sections_t SymbolTableSections;
+ IndexMap_t SymbolTableSectionsIndexMap;
+ DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
+
+ const Elf_Shdr *dot_dynamic_sec; // .dynamic
+ const Elf_Shdr *dot_gnu_version_sec; // .gnu.version
+ const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
+ const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
+
+ // Pointer to SONAME entry in dynamic string table
+ // This is set the first time getLoadName is called.
+ mutable const char *dt_soname;
+
+ // 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> {
+ public:
+ // If the integer is 0, this is an Elf_Verdef*.
+ // If the integer is 1, this is an Elf_Vernaux*.
+ VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { }
+ VersionMapEntry(const Elf_Verdef *verdef)
+ : PointerIntPair<const void*, 1>(verdef, 0) { }
+ VersionMapEntry(const Elf_Vernaux *vernaux)
+ : PointerIntPair<const void*, 1>(vernaux, 1) { }
+ bool isNull() const { return getPointer() == NULL; }
+ bool isVerdef() const { return !isNull() && getInt() == 0; }
+ bool isVernaux() const { return !isNull() && getInt() == 1; }
+ const Elf_Verdef *getVerdef() const {
+ return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL;
+ }
+ const Elf_Vernaux *getVernaux() const {
+ return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL;
+ }
+ };
+ mutable SmallVector<VersionMapEntry, 16> VersionMap;
+ void LoadVersionDefs(const Elf_Shdr *sec) const;
+ void LoadVersionNeeds(const Elf_Shdr *ec) const;
+ void LoadVersionMap() const;
+
+ /// @brief Map sections to an array of relocation sections that reference
+ /// them sorted by section index.
+ RelocMap_t SectionRelocMap;
+
+ /// @brief Get the relocation section that contains \a Rel.
+ const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
+ return getSection(Rel.w.b);
+ }
+
+ bool isRelocationHasAddend(DataRefImpl Rel) const;
+ template<typename T>
+ const T *getEntry(uint16_t Section, uint32_t Entry) const;
+ template<typename T>
+ const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
+ const Elf_Shdr *getSection(DataRefImpl index) const;
+ const Elf_Shdr *getSection(uint32_t index) const;
+ const Elf_Rel *getRel(DataRefImpl Rel) const;
+ const Elf_Rela *getRela(DataRefImpl Rela) const;
+ const char *getString(uint32_t section, uint32_t offset) const;
+ const char *getString(const Elf_Shdr *section, uint32_t offset) const;
+ error_code getSymbolName(const Elf_Shdr *section,
+ const Elf_Sym *Symb,
+ StringRef &Res) const;
+ error_code getSymbolVersion(const Elf_Shdr *section,
+ const Elf_Sym *Symb,
+ StringRef &Version,
+ bool &IsDefault) const;
+ void VerifyStrTab(const Elf_Shdr *sh) const;
+
+protected:
+ const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
+ void validateSymbol(DataRefImpl Symb) const;
+
+public:
+ const Elf_Dyn *getDyn(DataRefImpl DynData) const;
+ error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
+ bool &IsDefault) const;
+protected:
+ virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
+ virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
+ virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
+ virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
+ virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
+ virtual error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const;
+
+ friend class DynRefImpl<target_endianness, is64Bits>;
+ virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const;
+
+ virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
+ virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const;
+
+ virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
+ virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionRequiredForExecution(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 sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const;
+ virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
+ virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
+
+ virtual error_code getRelocationNext(DataRefImpl Rel,
+ RelocationRef &Res) const;
+ virtual error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationSymbol(DataRefImpl Rel,
+ SymbolRef &Res) const;
+ virtual error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const;
+ virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
+ int64_t &Res) const;
+ virtual error_code getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const;
+
+public:
+ ELFObjectFile(MemoryBuffer *Object, error_code &ec);
+ virtual symbol_iterator begin_symbols() const;
+ virtual symbol_iterator end_symbols() const;
+
+ virtual symbol_iterator begin_dynamic_symbols() const;
+ virtual symbol_iterator end_dynamic_symbols() const;
+
+ virtual section_iterator begin_sections() const;
+ virtual section_iterator end_sections() const;
+
+ virtual library_iterator begin_libraries_needed() const;
+ virtual library_iterator end_libraries_needed() const;
+
+ virtual dyn_iterator begin_dynamic_table() const;
+ virtual dyn_iterator end_dynamic_table() const;
+
+ virtual uint8_t getBytesInAddress() const;
+ virtual StringRef getFileFormatName() const;
+ virtual StringRef getObjectType() const { return "ELF"; }
+ virtual unsigned getArch() const;
+ virtual StringRef getLoadName() const;
+
+ uint64_t getNumSections() const;
+ uint64_t getStringTableIndex() const;
+ ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
+ const Elf_Shdr *getSection(const Elf_Sym *symb) const;
+
+ // Methods for type inquiry through isa, cast, and dyn_cast
+ bool isDyldType() const { return isDyldELFObject; }
+ static inline bool classof(const Binary *v) {
+ 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>::
+ 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
+ const char *sec_start = (const char*)base() + sec->sh_offset;
+ const char *sec_end = sec_start + vd_size;
+ // The first Verdef entry is at the start of the section.
+ const char *p = sec_start;
+ for (unsigned i = 0; i < vd_count; i++) {
+ if (p + sizeof(Elf_Verdef) > sec_end)
+ report_fatal_error("Section ended unexpectedly while scanning "
+ "version definitions.");
+ const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p);
+ if (vd->vd_version != ELF::VER_DEF_CURRENT)
+ report_fatal_error("Unexpected verdef version");
+ size_t index = vd->vd_ndx & ELF::VERSYM_VERSION;
+ if (index >= VersionMap.size())
+ VersionMap.resize(index+1);
+ VersionMap[index] = VersionMapEntry(vd);
+ p += vd->vd_next;
+ }
+}
+
+// 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>::
+ 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
+ const char *sec_start = (const char*)base() + sec->sh_offset;
+ const char *sec_end = sec_start + vn_size;
+ // The first Verneed entry is at the start of the section.
+ const char *p = sec_start;
+ for (unsigned i = 0; i < vn_count; i++) {
+ if (p + sizeof(Elf_Verneed) > sec_end)
+ report_fatal_error("Section ended unexpectedly while scanning "
+ "version needed records.");
+ const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p);
+ if (vn->vn_version != ELF::VER_NEED_CURRENT)
+ report_fatal_error("Unexpected verneed version");
+ // Iterate through the Vernaux entries
+ const char *paux = p + vn->vn_aux;
+ for (unsigned j = 0; j < vn->vn_cnt; j++) {
+ if (paux + sizeof(Elf_Vernaux) > sec_end)
+ report_fatal_error("Section ended unexpected while scanning auxiliary "
+ "version needed records.");
+ const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux);
+ size_t index = vna->vna_other & ELF::VERSYM_VERSION;
+ if (index >= VersionMap.size())
+ VersionMap.resize(index+1);
+ VersionMap[index] = VersionMapEntry(vna);
+ paux += vna->vna_next;
+ }
+ p += vn->vn_next;
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+void ELFObjectFile<target_endianness, 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;
+
+ // Has the VersionMap already been loaded?
+ if (VersionMap.size() > 0)
+ return;
+
+ // The first two version indexes are reserved.
+ // Index 0 is LOCAL, index 1 is GLOBAL.
+ VersionMap.push_back(VersionMapEntry());
+ VersionMap.push_back(VersionMapEntry());
+
+ if (dot_gnu_version_d_sec)
+ LoadVersionDefs(dot_gnu_version_d_sec);
+
+ if (dot_gnu_version_r_sec)
+ LoadVersionNeeds(dot_gnu_version_r_sec);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+void ELFObjectFile<target_endianness, is64Bits>
+ ::validateSymbol(DataRefImpl Symb) const {
+ const Elf_Sym *symb = getSymbol(Symb);
+ const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
+ // FIXME: We really need to do proper error handling in the case of an invalid
+ // input file. Because we don't use exceptions, I think we'll just pass
+ // an error object around.
+ if (!( symb
+ && SymbolTableSection
+ && symb >= (const Elf_Sym*)(base()
+ + SymbolTableSection->sh_offset)
+ && symb < (const Elf_Sym*)(base()
+ + SymbolTableSection->sh_offset
+ + SymbolTableSection->sh_size)))
+ // FIXME: Proper error handling.
+ report_fatal_error("Symb must point to a valid symbol!");
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolNext(DataRefImpl Symb,
+ SymbolRef &Result) const {
+ validateSymbol(Symb);
+ const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
+
+ ++Symb.d.a;
+ // Check to see if we are at the end of this symbol table.
+ if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
+ // We are at the end. If there are other symbol tables, jump to them.
+ // If the symbol table is .dynsym, we are iterating dynamic symbols,
+ // and there is only one table of these.
+ if (Symb.d.b != 0) {
+ ++Symb.d.b;
+ Symb.d.a = 1; // The 0th symbol in ELF is fake.
+ }
+ // Otherwise return the terminator.
+ if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) {
+ Symb.d.a = std::numeric_limits<uint32_t>::max();
+ Symb.d.b = std::numeric_limits<uint32_t>::max();
+ }
+ }
+
+ Result = SymbolRef(Symb, this);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolName(DataRefImpl Symb,
+ StringRef &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolVersion(SymbolRef SymRef,
+ StringRef &Version,
+ bool &IsDefault) const {
+ DataRefImpl Symb = SymRef.getRawDataRefImpl();
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ return getSymbolVersion(SymbolTableSections[Symb.d.b], symb,
+ Version, IsDefault);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+ELF::Elf64_Word ELFObjectFile<target_endianness, 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>
+ ::getSection(const Elf_Sym *symb) const {
+ if (symb->st_shndx == ELF::SHN_XINDEX)
+ return getSection(ExtendedSymbolTable.lookup(symb));
+ if (symb->st_shndx >= ELF::SHN_LORESERVE)
+ return 0;
+ return getSection(symb->st_shndx);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolFileOffset(DataRefImpl Symb,
+ uint64_t &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ const Elf_Shdr *Section;
+ switch (getSymbolTableIndex(symb)) {
+ case ELF::SHN_COMMON:
+ // Unintialized symbols have no offset in the object file
+ case ELF::SHN_UNDEF:
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ case ELF::SHN_ABS:
+ Result = symb->st_value;
+ return object_error::success;
+ default: Section = getSection(symb);
+ }
+
+ switch (symb->getType()) {
+ case ELF::STT_SECTION:
+ Result = Section ? Section->sh_addr : UnknownAddressOrSize;
+ return object_error::success;
+ case ELF::STT_FUNC:
+ case ELF::STT_OBJECT:
+ case ELF::STT_NOTYPE:
+ Result = symb->st_value +
+ (Section ? Section->sh_offset : 0);
+ return object_error::success;
+ default:
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ const Elf_Shdr *Section;
+ switch (getSymbolTableIndex(symb)) {
+ case ELF::SHN_COMMON:
+ case ELF::SHN_UNDEF:
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ case ELF::SHN_ABS:
+ Result = symb->st_value;
+ return object_error::success;
+ default: Section = getSection(symb);
+ }
+
+ switch (symb->getType()) {
+ case ELF::STT_SECTION:
+ Result = Section ? Section->sh_addr : UnknownAddressOrSize;
+ return object_error::success;
+ case ELF::STT_FUNC:
+ case ELF::STT_OBJECT:
+ case ELF::STT_NOTYPE:
+ Result = symb->st_value + (Section ? Section->sh_addr : 0);
+ return object_error::success;
+ default:
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolSize(DataRefImpl Symb,
+ uint64_t &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ if (symb->st_size == 0)
+ Result = UnknownAddressOrSize;
+ Result = symb->st_size;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolNMTypeChar(DataRefImpl Symb,
+ char &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ const Elf_Shdr *Section = getSection(symb);
+
+ char ret = '?';
+
+ if (Section) {
+ switch (Section->sh_type) {
+ case ELF::SHT_PROGBITS:
+ case ELF::SHT_DYNAMIC:
+ switch (Section->sh_flags) {
+ case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
+ ret = 't'; break;
+ case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
+ ret = 'd'; break;
+ case ELF::SHF_ALLOC:
+ case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
+ case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
+ ret = 'r'; break;
+ }
+ break;
+ case ELF::SHT_NOBITS: ret = 'b';
+ }
+ }
+
+ switch (getSymbolTableIndex(symb)) {
+ case ELF::SHN_UNDEF:
+ if (ret == '?')
+ ret = 'U';
+ break;
+ case ELF::SHN_ABS: ret = 'a'; break;
+ case ELF::SHN_COMMON: ret = 'c'; break;
+ }
+
+ switch (symb->getBinding()) {
+ case ELF::STB_GLOBAL: ret = ::toupper(ret); break;
+ case ELF::STB_WEAK:
+ if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
+ ret = 'w';
+ else
+ if (symb->getType() == ELF::STT_OBJECT)
+ ret = 'V';
+ else
+ ret = 'W';
+ }
+
+ if (ret == '?' && symb->getType() == ELF::STT_SECTION) {
+ StringRef name;
+ if (error_code ec = getSymbolName(Symb, name))
+ return ec;
+ Result = StringSwitch<char>(name)
+ .StartsWith(".debug", 'N')
+ .StartsWith(".note", 'n')
+ .Default('?');
+ return object_error::success;
+ }
+
+ Result = ret;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+
+ switch (symb->getType()) {
+ case ELF::STT_NOTYPE:
+ Result = SymbolRef::ST_Unknown;
+ break;
+ case ELF::STT_SECTION:
+ Result = SymbolRef::ST_Debug;
+ break;
+ case ELF::STT_FILE:
+ Result = SymbolRef::ST_File;
+ break;
+ case ELF::STT_FUNC:
+ Result = SymbolRef::ST_Function;
+ break;
+ case ELF::STT_OBJECT:
+ case ELF::STT_COMMON:
+ case ELF::STT_TLS:
+ Result = SymbolRef::ST_Data;
+ break;
+ default:
+ Result = SymbolRef::ST_Other;
+ break;
+ }
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolFlags(DataRefImpl Symb,
+ uint32_t &Result) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+
+ Result = SymbolRef::SF_None;
+
+ if (symb->getBinding() != ELF::STB_LOCAL)
+ Result |= SymbolRef::SF_Global;
+
+ if (symb->getBinding() == ELF::STB_WEAK)
+ Result |= SymbolRef::SF_Weak;
+
+ if (symb->st_shndx == ELF::SHN_ABS)
+ Result |= SymbolRef::SF_Absolute;
+
+ if (symb->getType() == ELF::STT_FILE ||
+ symb->getType() == ELF::STT_SECTION)
+ Result |= SymbolRef::SF_FormatSpecific;
+
+ if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF)
+ Result |= SymbolRef::SF_Undefined;
+
+ if (symb->getType() == ELF::STT_COMMON ||
+ getSymbolTableIndex(symb) == ELF::SHN_COMMON)
+ Result |= SymbolRef::SF_Common;
+
+ if (symb->getType() == ELF::STT_TLS)
+ Result |= SymbolRef::SF_ThreadLocal;
+
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const {
+ validateSymbol(Symb);
+ const Elf_Sym *symb = getSymbol(Symb);
+ const Elf_Shdr *sec = getSection(symb);
+ if (!sec)
+ Res = end_sections();
+ else {
+ DataRefImpl Sec;
+ Sec.p = reinterpret_cast<intptr_t>(sec);
+ Res = section_iterator(SectionRef(Sec, this));
+ }
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
+ const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
+ sec += Header->e_shentsize;
+ Sec.p = reinterpret_cast<intptr_t>(sec);
+ Result = SectionRef(Sec, this);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionName(DataRefImpl Sec,
+ StringRef &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionAddress(DataRefImpl Sec,
+ uint64_t &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ Result = sec->sh_addr;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionSize(DataRefImpl Sec,
+ uint64_t &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ Result = sec->sh_size;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionContents(DataRefImpl Sec,
+ StringRef &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ const char *start = (const char*)base() + sec->sh_offset;
+ Result = StringRef(start, sec->sh_size);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ Result = sec->sh_addralign;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::isSectionText(DataRefImpl Sec,
+ bool &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (sec->sh_flags & ELF::SHF_EXECINSTR)
+ Result = true;
+ else
+ Result = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::isSectionData(DataRefImpl Sec,
+ bool &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
+ && sec->sh_type == ELF::SHT_PROGBITS)
+ Result = true;
+ else
+ Result = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::isSectionBSS(DataRefImpl Sec,
+ bool &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
+ && sec->sh_type == ELF::SHT_NOBITS)
+ Result = true;
+ else
+ Result = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (sec->sh_flags & ELF::SHF_ALLOC)
+ Result = true;
+ else
+ Result = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::isSectionVirtual(DataRefImpl Sec,
+ bool &Result) const {
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ if (sec->sh_type == ELF::SHT_NOBITS)
+ Result = true;
+ else
+ Result = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, 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 = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const {
+ // FIXME: Unimplemented.
+ Result = false;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+relocation_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionRelBegin(DataRefImpl Sec) const {
+ DataRefImpl RelData;
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
+ if (sec != 0 && ittr != SectionRelocMap.end()) {
+ RelData.w.a = getSection(ittr->second[0])->sh_info;
+ RelData.w.b = ittr->second[0];
+ RelData.w.c = 0;
+ }
+ return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+relocation_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::getSectionRelEnd(DataRefImpl Sec) const {
+ DataRefImpl RelData;
+ const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
+ if (sec != 0 && ittr != SectionRelocMap.end()) {
+ // Get the index of the last relocation section for this section.
+ std::size_t relocsecindex = ittr->second[ittr->second.size() - 1];
+ const Elf_Shdr *relocsec = getSection(relocsecindex);
+ RelData.w.a = relocsec->sh_info;
+ RelData.w.b = relocsecindex;
+ RelData.w.c = relocsec->sh_size / relocsec->sh_entsize;
+ }
+ return relocation_iterator(RelocationRef(RelData, this));
+}
+
+// Relocations
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationNext(DataRefImpl Rel,
+ RelocationRef &Result) const {
+ ++Rel.w.c;
+ const Elf_Shdr *relocsec = getSection(Rel.w.b);
+ if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
+ // We have reached the end of the relocations for this section. See if there
+ // is another relocation section.
+ typename RelocMap_t::mapped_type relocseclist =
+ SectionRelocMap.lookup(getSection(Rel.w.a));
+
+ // Do a binary search for the current reloc section index (which must be
+ // present). Then get the next one.
+ typename RelocMap_t::mapped_type::const_iterator loc =
+ std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b);
+ ++loc;
+
+ // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel
+ // to the end iterator.
+ if (loc != relocseclist.end()) {
+ Rel.w.b = *loc;
+ Rel.w.a = 0;
+ }
+ }
+ Result = RelocationRef(Rel, this);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationSymbol(DataRefImpl Rel,
+ SymbolRef &Result) const {
+ uint32_t symbolIdx;
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ switch (sec->sh_type) {
+ default :
+ report_fatal_error("Invalid section type in Rel!");
+ case ELF::SHT_REL : {
+ symbolIdx = getRel(Rel)->getSymbol();
+ break;
+ }
+ case ELF::SHT_RELA : {
+ symbolIdx = getRela(Rel)->getSymbol();
+ break;
+ }
+ }
+ DataRefImpl SymbolData;
+ IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link);
+ if (it == SymbolTableSectionsIndexMap.end())
+ report_fatal_error("Relocation symbol table not found!");
+ SymbolData.d.a = symbolIdx;
+ SymbolData.d.b = it->second;
+ Result = SymbolRef(SymbolData, this);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Result) const {
+ uint64_t offset;
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ switch (sec->sh_type) {
+ default :
+ report_fatal_error("Invalid section type in Rel!");
+ case ELF::SHT_REL : {
+ offset = getRel(Rel)->r_offset;
+ break;
+ }
+ case ELF::SHT_RELA : {
+ offset = getRela(Rel)->r_offset;
+ break;
+ }
+ }
+
+ Result = offset;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Result) const {
+ uint64_t offset;
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ switch (sec->sh_type) {
+ default :
+ report_fatal_error("Invalid section type in Rel!");
+ case ELF::SHT_REL : {
+ offset = getRel(Rel)->r_offset;
+ break;
+ }
+ case ELF::SHT_RELA : {
+ offset = getRela(Rel)->r_offset;
+ break;
+ }
+ }
+
+ Result = offset - sec->sh_addr;
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationType(DataRefImpl Rel,
+ uint64_t &Result) const {
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ switch (sec->sh_type) {
+ default :
+ report_fatal_error("Invalid section type in Rel!");
+ case ELF::SHT_REL : {
+ Result = getRel(Rel)->getType();
+ break;
+ }
+ case ELF::SHT_RELA : {
+ Result = getRela(Rel)->getType();
+ break;
+ }
+ }
+ return object_error::success;
+}
+
+#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>
+ ::getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const {
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ uint8_t type;
+ StringRef res;
+ switch (sec->sh_type) {
+ default :
+ return object_error::parse_failed;
+ case ELF::SHT_REL : {
+ type = getRel(Rel)->getType();
+ break;
+ }
+ case ELF::SHT_RELA : {
+ type = getRela(Rel)->getType();
+ break;
+ }
+ }
+ switch (Header->e_machine) {
+ case ELF::EM_X86_64:
+ switch (type) {
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC);
+ default:
+ res = "Unknown";
+ }
+ break;
+ case ELF::EM_386:
+ switch (type) {
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE);
+ default:
+ res = "Unknown";
+ }
+ break;
+ default:
+ res = "Unknown";
+ }
+ Result.append(res.begin(), res.end());
+ return object_error::success;
+}
+
+#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationAdditionalInfo(DataRefImpl Rel,
+ int64_t &Result) const {
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ switch (sec->sh_type) {
+ default :
+ report_fatal_error("Invalid section type in Rel!");
+ case ELF::SHT_REL : {
+ Result = 0;
+ return object_error::success;
+ }
+ case ELF::SHT_RELA : {
+ Result = getRela(Rel)->r_addend;
+ return object_error::success;
+ }
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const {
+ const Elf_Shdr *sec = getSection(Rel.w.b);
+ uint8_t type;
+ StringRef res;
+ int64_t addend = 0;
+ uint16_t symbol_index = 0;
+ switch (sec->sh_type) {
+ default :
+ return object_error::parse_failed;
+ case ELF::SHT_REL : {
+ type = getRel(Rel)->getType();
+ symbol_index = getRel(Rel)->getSymbol();
+ // TODO: Read implicit addend from section data.
+ break;
+ }
+ case ELF::SHT_RELA : {
+ type = getRela(Rel)->getType();
+ symbol_index = getRela(Rel)->getSymbol();
+ addend = getRela(Rel)->r_addend;
+ break;
+ }
+ }
+ const Elf_Sym *symb = getEntry<Elf_Sym>(sec->sh_link, symbol_index);
+ StringRef symname;
+ if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname))
+ return ec;
+ switch (Header->e_machine) {
+ case ELF::EM_X86_64:
+ switch (type) {
+ case ELF::R_X86_64_32S:
+ res = symname;
+ break;
+ case ELF::R_X86_64_PC32: {
+ std::string fmtbuf;
+ raw_string_ostream fmt(fmtbuf);
+ fmt << symname << (addend < 0 ? "" : "+") << addend << "-P";
+ fmt.flush();
+ Result.append(fmtbuf.begin(), fmtbuf.end());
+ }
+ break;
+ default:
+ res = "Unknown";
+ }
+ break;
+ default:
+ res = "Unknown";
+ }
+ if (Result.empty())
+ Result.append(res.begin(), res.end());
+ return object_error::success;
+}
+
+// Verify that the last byte in the string table in a null.
+template<support::endianness target_endianness, bool is64Bits>
+void ELFObjectFile<target_endianness, is64Bits>
+ ::VerifyStrTab(const Elf_Shdr *sh) const {
+ const char *strtab = (const char*)base() + sh->sh_offset;
+ if (strtab[sh->sh_size - 1] != 0)
+ // FIXME: Proper error handling.
+ 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)
+ : ObjectFile(getELFType(target_endianness == support::little, is64Bits),
+ Object, ec)
+ , isDyldELFObject(false)
+ , SectionHeaderTable(0)
+ , dot_shstrtab_sec(0)
+ , dot_strtab_sec(0)
+ , dot_dynstr_sec(0)
+ , dot_dynamic_sec(0)
+ , dot_gnu_version_sec(0)
+ , dot_gnu_version_r_sec(0)
+ , dot_gnu_version_d_sec(0)
+ , dt_soname(0)
+ {
+
+ const uint64_t FileSize = Data->getBufferSize();
+
+ if (sizeof(Elf_Ehdr) > FileSize)
+ // FIXME: Proper error handling.
+ report_fatal_error("File too short!");
+
+ Header = reinterpret_cast<const Elf_Ehdr *>(base());
+
+ if (Header->e_shoff == 0)
+ return;
+
+ const uint64_t SectionTableOffset = Header->e_shoff;
+
+ if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
+ // FIXME: Proper error handling.
+ report_fatal_error("Section header table goes past end of file!");
+
+ // The getNumSections() call below depends on SectionHeaderTable being set.
+ SectionHeaderTable =
+ reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
+ const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
+
+ if (SectionTableOffset + SectionTableSize > FileSize)
+ // FIXME: Proper error handling.
+ report_fatal_error("Section table goes past end of file!");
+
+ // To find the symbol tables we walk the section table to find SHT_SYMTAB.
+ const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
+ const Elf_Shdr* sh = SectionHeaderTable;
+
+ // Reserve SymbolTableSections[0] for .dynsym
+ SymbolTableSections.push_back(NULL);
+
+ for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
+ switch (sh->sh_type) {
+ case ELF::SHT_SYMTAB_SHNDX: {
+ if (SymbolTableSectionHeaderIndex)
+ // FIXME: Proper error handling.
+ report_fatal_error("More than one .symtab_shndx!");
+ SymbolTableSectionHeaderIndex = sh;
+ break;
+ }
+ case ELF::SHT_SYMTAB: {
+ SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
+ SymbolTableSections.push_back(sh);
+ break;
+ }
+ case ELF::SHT_DYNSYM: {
+ if (SymbolTableSections[0] != NULL)
+ // FIXME: Proper error handling.
+ report_fatal_error("More than one .dynsym!");
+ SymbolTableSectionsIndexMap[i] = 0;
+ SymbolTableSections[0] = sh;
+ break;
+ }
+ case ELF::SHT_REL:
+ case ELF::SHT_RELA: {
+ SectionRelocMap[getSection(sh->sh_info)].push_back(i);
+ break;
+ }
+ case ELF::SHT_DYNAMIC: {
+ if (dot_dynamic_sec != NULL)
+ // FIXME: Proper error handling.
+ report_fatal_error("More than one .dynamic!");
+ dot_dynamic_sec = sh;
+ break;
+ }
+ case ELF::SHT_GNU_versym: {
+ if (dot_gnu_version_sec != NULL)
+ // FIXME: Proper error handling.
+ report_fatal_error("More than one .gnu.version section!");
+ dot_gnu_version_sec = sh;
+ break;
+ }
+ case ELF::SHT_GNU_verdef: {
+ if (dot_gnu_version_d_sec != NULL)
+ // FIXME: Proper error handling.
+ report_fatal_error("More than one .gnu.version_d section!");
+ dot_gnu_version_d_sec = sh;
+ break;
+ }
+ case ELF::SHT_GNU_verneed: {
+ if (dot_gnu_version_r_sec != NULL)
+ // FIXME: Proper error handling.
+ report_fatal_error("More than one .gnu.version_r section!");
+ dot_gnu_version_r_sec = sh;
+ break;
+ }
+ }
+ ++sh;
+ }
+
+ // Sort section relocation lists by index.
+ for (typename RelocMap_t::iterator i = SectionRelocMap.begin(),
+ e = SectionRelocMap.end(); i != e; ++i) {
+ std::sort(i->second.begin(), i->second.end());
+ }
+
+ // Get string table sections.
+ dot_shstrtab_sec = getSection(getStringTableIndex());
+ if (dot_shstrtab_sec) {
+ // Verify that the last byte in the string table in a null.
+ VerifyStrTab(dot_shstrtab_sec);
+ }
+
+ // Merge this into the above loop.
+ for (const char *i = reinterpret_cast<const char *>(SectionHeaderTable),
+ *e = i + getNumSections() * Header->e_shentsize;
+ i != e; i += Header->e_shentsize) {
+ const Elf_Shdr *sh = reinterpret_cast<const Elf_Shdr*>(i);
+ if (sh->sh_type == ELF::SHT_STRTAB) {
+ StringRef SectionName(getString(dot_shstrtab_sec, sh->sh_name));
+ if (SectionName == ".strtab") {
+ if (dot_strtab_sec != 0)
+ // FIXME: Proper error handling.
+ report_fatal_error("Already found section named .strtab!");
+ dot_strtab_sec = sh;
+ VerifyStrTab(dot_strtab_sec);
+ } else if (SectionName == ".dynstr") {
+ if (dot_dynstr_sec != 0)
+ // FIXME: Proper error handling.
+ report_fatal_error("Already found section named .dynstr!");
+ dot_dynstr_sec = sh;
+ VerifyStrTab(dot_dynstr_sec);
+ }
+ }
+ }
+
+ // Build symbol name side-mapping if there is one.
+ if (SymbolTableSectionHeaderIndex) {
+ const Elf_Word *ShndxTable = reinterpret_cast<const Elf_Word*>(base() +
+ SymbolTableSectionHeaderIndex->sh_offset);
+ error_code ec;
+ for (symbol_iterator si = begin_symbols(),
+ se = end_symbols(); si != se; si.increment(ec)) {
+ if (ec)
+ report_fatal_error("Fewer extended symbol table entries than symbols!");
+ if (*ShndxTable != ELF::SHN_UNDEF)
+ ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable;
+ ++ShndxTable;
+ }
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::begin_symbols() const {
+ DataRefImpl SymbolData;
+ if (SymbolTableSections.size() <= 1) {
+ SymbolData.d.a = std::numeric_limits<uint32_t>::max();
+ SymbolData.d.b = std::numeric_limits<uint32_t>::max();
+ } else {
+ SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
+ SymbolData.d.b = 1; // The 0th table is .dynsym
+ }
+ return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::end_symbols() const {
+ DataRefImpl SymbolData;
+ SymbolData.d.a = std::numeric_limits<uint32_t>::max();
+ SymbolData.d.b = std::numeric_limits<uint32_t>::max();
+ return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::begin_dynamic_symbols() const {
+ DataRefImpl SymbolData;
+ if (SymbolTableSections[0] == NULL) {
+ SymbolData.d.a = std::numeric_limits<uint32_t>::max();
+ SymbolData.d.b = std::numeric_limits<uint32_t>::max();
+ } else {
+ SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
+ SymbolData.d.b = 0; // The 0th table is .dynsym
+ }
+ return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+symbol_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::end_dynamic_symbols() const {
+ DataRefImpl SymbolData;
+ SymbolData.d.a = std::numeric_limits<uint32_t>::max();
+ SymbolData.d.b = std::numeric_limits<uint32_t>::max();
+ return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+section_iterator ELFObjectFile<target_endianness, 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>
+ ::end_sections() const {
+ DataRefImpl ret;
+ ret.p = reinterpret_cast<intptr_t>(base()
+ + Header->e_shoff
+ + (Header->e_shentsize*getNumSections()));
+ 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 {
+ DataRefImpl DynData;
+ if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) {
+ DynData.d.a = std::numeric_limits<uint32_t>::max();
+ } else {
+ DynData.d.a = 0;
+ }
+ return dyn_iterator(DynRef(DynData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator
+ELFObjectFile<target_endianness, 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>
+ ::getDynNext(DataRefImpl DynData,
+ DynRef &Result) const {
+ ++DynData.d.a;
+
+ // Check to see if we are at the end of .dynamic
+ if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) {
+ // We are at the end. Return the terminator.
+ DynData.d.a = std::numeric_limits<uint32_t>::max();
+ }
+
+ Result = DynRef(DynData, this);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+StringRef
+ELFObjectFile<target_endianness, is64Bits>::getLoadName() const {
+ if (!dt_soname) {
+ // Find the DT_SONAME entry
+ dyn_iterator it = begin_dynamic_table();
+ dyn_iterator ie = end_dynamic_table();
+ error_code ec;
+ while (it != ie) {
+ if (it->getTag() == ELF::DT_SONAME)
+ break;
+ it.increment(ec);
+ if (ec)
+ report_fatal_error("dynamic table iteration failed");
+ }
+ if (it != ie) {
+ if (dot_dynstr_sec == NULL)
+ report_fatal_error("Dynamic string table is missing");
+ dt_soname = getString(dot_dynstr_sec, it->getVal());
+ } else {
+ dt_soname = "";
+ }
+ }
+ return dt_soname;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+library_iterator ELFObjectFile<target_endianness, is64Bits>
+ ::begin_libraries_needed() const {
+ // Find the first DT_NEEDED entry
+ dyn_iterator i = begin_dynamic_table();
+ dyn_iterator e = end_dynamic_table();
+ error_code ec;
+ while (i != e) {
+ if (i->getTag() == ELF::DT_NEEDED)
+ break;
+ i.increment(ec);
+ if (ec)
+ report_fatal_error("dynamic table iteration failed");
+ }
+ // Use the same DataRefImpl format as DynRef.
+ return library_iterator(LibraryRef(i->getRawDataRefImpl(), this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const {
+ // Use the same DataRefImpl format as DynRef.
+ dyn_iterator i = dyn_iterator(DynRef(Data, this));
+ dyn_iterator e = end_dynamic_table();
+
+ // Skip the current dynamic table entry.
+ error_code ec;
+ if (i != e) {
+ i.increment(ec);
+ // TODO: proper error handling
+ if (ec)
+ report_fatal_error("dynamic table iteration failed");
+ }
+
+ // Find the next DT_NEEDED entry.
+ while (i != e) {
+ if (i->getTag() == ELF::DT_NEEDED)
+ break;
+ i.increment(ec);
+ if (ec)
+ report_fatal_error("dynamic table iteration failed");
+ }
+ Result = LibraryRef(i->getRawDataRefImpl(), this);
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getLibraryPath(DataRefImpl Data, StringRef &Res) const {
+ dyn_iterator i = dyn_iterator(DynRef(Data, this));
+ if (i == end_dynamic_table())
+ report_fatal_error("getLibraryPath() called on iterator end");
+
+ if (i->getTag() != ELF::DT_NEEDED)
+ report_fatal_error("Invalid library_iterator");
+
+ // This uses .dynstr to lookup the name of the DT_NEEDED entry.
+ // THis works as long as DT_STRTAB == .dynstr. This is true most of
+ // the time, but the specification allows exceptions.
+ // TODO: This should really use DT_STRTAB instead. Doing this requires
+ // reading the program headers.
+ if (dot_dynstr_sec == NULL)
+ report_fatal_error("Dynamic string table is missing");
+ Res = getString(dot_dynstr_sec, i->getVal());
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+library_iterator ELFObjectFile<target_endianness, 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 {
+ return is64Bits ? 8 : 4;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+StringRef ELFObjectFile<target_endianness, is64Bits>
+ ::getFileFormatName() const {
+ switch(Header->e_ident[ELF::EI_CLASS]) {
+ case ELF::ELFCLASS32:
+ switch(Header->e_machine) {
+ case ELF::EM_386:
+ return "ELF32-i386";
+ case ELF::EM_X86_64:
+ return "ELF32-x86-64";
+ case ELF::EM_ARM:
+ return "ELF32-arm";
+ default:
+ return "ELF32-unknown";
+ }
+ case ELF::ELFCLASS64:
+ switch(Header->e_machine) {
+ case ELF::EM_386:
+ return "ELF64-i386";
+ case ELF::EM_X86_64:
+ return "ELF64-x86-64";
+ default:
+ return "ELF64-unknown";
+ }
+ default:
+ // FIXME: Proper error handling.
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
+ switch(Header->e_machine) {
+ case ELF::EM_386:
+ return Triple::x86;
+ case ELF::EM_X86_64:
+ return Triple::x86_64;
+ case ELF::EM_ARM:
+ return Triple::arm;
+ default:
+ return Triple::UnknownArch;
+ }
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
+ assert(Header && "Header not initialized!");
+ if (Header->e_shnum == ELF::SHN_UNDEF) {
+ assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
+ return SectionHeaderTable->sh_size;
+ }
+ return Header->e_shnum;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+uint64_t
+ELFObjectFile<target_endianness, is64Bits>::getStringTableIndex() const {
+ if (Header->e_shnum == ELF::SHN_UNDEF) {
+ if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
+ return SectionHeaderTable->sh_link;
+ if (Header->e_shstrndx >= getNumSections())
+ return 0;
+ }
+ return Header->e_shstrndx;
+}
+
+
+template<support::endianness target_endianness, bool is64Bits>
+template<typename T>
+inline const T *
+ELFObjectFile<target_endianness, is64Bits>::getEntry(uint16_t Section,
+ uint32_t Entry) const {
+ return getEntry<T>(getSection(Section), Entry);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+template<typename T>
+inline const T *
+ELFObjectFile<target_endianness, 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 {
+ 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 {
+ 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 {
+ 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 {
+ 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 {
+ 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.
+ report_fatal_error("Invalid symbol table section!");
+ 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 {
+ if (index == 0)
+ return 0;
+ if (!SectionHeaderTable || index >= getNumSections())
+ // FIXME: Proper error handling.
+ report_fatal_error("Invalid section index!");
+
+ return reinterpret_cast<const Elf_Shdr *>(
+ reinterpret_cast<const char *>(SectionHeaderTable)
+ + (index * Header->e_shentsize));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+const char *ELFObjectFile<target_endianness, 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>
+ ::getString(const Elf_Shdr *section,
+ ELF::Elf32_Word offset) const {
+ assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
+ if (offset >= section->sh_size)
+ // FIXME: Proper error handling.
+ report_fatal_error("Symbol name offset outside of string table!");
+ return (const char *)base() + section->sh_offset + offset;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolName(const Elf_Shdr *section,
+ const Elf_Sym *symb,
+ StringRef &Result) const {
+ if (symb->st_name == 0) {
+ const Elf_Shdr *section = getSection(symb);
+ if (!section)
+ Result = "";
+ else
+ Result = getString(dot_shstrtab_sec, section->sh_name);
+ return object_error::success;
+ }
+
+ if (section == SymbolTableSections[0]) {
+ // Symbol is in .dynsym, use .dynstr string table
+ Result = getString(dot_dynstr_sec, symb->st_name);
+ } else {
+ // Use the default symbol table name section.
+ Result = getString(dot_strtab_sec, symb->st_name);
+ }
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+ ::getSymbolVersion(const Elf_Shdr *section,
+ const Elf_Sym *symb,
+ StringRef &Version,
+ bool &IsDefault) const {
+ // Handle non-dynamic symbols.
+ if (section != SymbolTableSections[0]) {
+ // Non-dynamic symbols can have versions in their names
+ // A name of the form 'foo@V1' indicates version 'V1', non-default.
+ // A name of the form 'foo@@V2' indicates version 'V2', default version.
+ StringRef Name;
+ error_code ec = getSymbolName(section, symb, Name);
+ if (ec != object_error::success)
+ return ec;
+ size_t atpos = Name.find('@');
+ if (atpos == StringRef::npos) {
+ Version = "";
+ IsDefault = false;
+ return object_error::success;
+ }
+ ++atpos;
+ if (atpos < Name.size() && Name[atpos] == '@') {
+ IsDefault = true;
+ ++atpos;
+ } else {
+ IsDefault = false;
+ }
+ Version = Name.substr(atpos);
+ return object_error::success;
+ }
+
+ // This is a dynamic symbol. Look in the GNU symbol version table.
+ if (dot_gnu_version_sec == NULL) {
+ // No version table.
+ Version = "";
+ IsDefault = false;
+ return object_error::success;
+ }
+
+ // Determine the position in the symbol table of this entry.
+ const char *sec_start = (const char*)base() + section->sh_offset;
+ size_t entry_index = ((const char*)symb - sec_start)/section->sh_entsize;
+
+ // Get the corresponding version index entry
+ const Elf_Versym *vs = getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index);
+ size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
+
+ // Special markers for unversioned symbols.
+ if (version_index == ELF::VER_NDX_LOCAL ||
+ version_index == ELF::VER_NDX_GLOBAL) {
+ Version = "";
+ IsDefault = false;
+ return object_error::success;
+ }
+
+ // Lookup this symbol in the version table
+ LoadVersionMap();
+ if (version_index >= VersionMap.size() || VersionMap[version_index].isNull())
+ report_fatal_error("Symbol has version index without corresponding "
+ "define or reference entry");
+ const VersionMapEntry &entry = VersionMap[version_index];
+
+ // Get the version name string
+ size_t name_offset;
+ if (entry.isVerdef()) {
+ // The first Verdaux entry holds the name.
+ name_offset = entry.getVerdef()->getAux()->vda_name;
+ } else {
+ name_offset = entry.getVernaux()->vna_name;
+ }
+ Version = getString(dot_dynstr_sec, name_offset);
+
+ // Set IsDefault
+ if (entry.isVerdef()) {
+ IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN);
+ } else {
+ IsDefault = false;
+ }
+
+ return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline DynRefImpl<target_endianness, is64Bits>
+ ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner)
+ : DynPimpl(DynP)
+ , OwningObject(Owner) {}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline bool DynRefImpl<target_endianness, is64Bits>
+ ::operator==(const DynRefImpl &Other) const {
+ return DynPimpl == Other.DynPimpl;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline bool DynRefImpl<target_endianness, is64Bits>
+ ::operator <(const DynRefImpl &Other) const {
+ return DynPimpl < Other.DynPimpl;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline error_code DynRefImpl<target_endianness, is64Bits>
+ ::getNext(DynRefImpl &Result) const {
+ return OwningObject->getDynNext(DynPimpl, Result);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline int64_t DynRefImpl<target_endianness, is64Bits>
+ ::getTag() const {
+ return OwningObject->getDyn(DynPimpl)->d_tag;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline uint64_t DynRefImpl<target_endianness, 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>
+ ::getPtr() const {
+ return OwningObject->getDyn(DynPimpl)->d_un.d_ptr;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline DataRefImpl DynRefImpl<target_endianness, is64Bits>
+ ::getRawDataRefImpl() const {
+ return DynPimpl;
+}
+
+/// This is a generic interface for retrieving GNU symbol version
+/// information from an ELFObjectFile.
+static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
+ const SymbolRef &Sym,
+ StringRef &Version,
+ bool &IsDefault) {
+ // Little-endian 32-bit
+ if (const ELFObjectFile<support::little, false> *ELFObj =
+ dyn_cast<ELFObjectFile<support::little, 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))
+ return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
+
+ // Little-endian 64-bit
+ if (const ELFObjectFile<support::little, true> *ELFObj =
+ dyn_cast<ELFObjectFile<support::little, 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))
+ return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
+
+ llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
+}
+
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/Error.h b/contrib/llvm/include/llvm/Object/Error.h
new file mode 100644
index 000000000000..fbaf71c17b8e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/Error.h
@@ -0,0 +1,50 @@
+//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This declares a new error_category for the Object library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ERROR_H
+#define LLVM_OBJECT_ERROR_H
+
+#include "llvm/Support/system_error.h"
+
+namespace llvm {
+namespace object {
+
+const error_category &object_category();
+
+struct object_error {
+enum _ {
+ success = 0,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof
+};
+ _ v_;
+
+ object_error(_ v) : v_(v) {}
+ explicit object_error(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+};
+
+inline error_code make_error_code(object_error e) {
+ return error_code(static_cast<int>(e), object_category());
+}
+
+} // end namespace object.
+
+template <> struct is_error_code_enum<object::object_error> : true_type { };
+
+template <> struct is_error_code_enum<object::object_error::_> : true_type { };
+
+} // end namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/MachO.h b/contrib/llvm/include/llvm/Object/MachO.h
new file mode 100644
index 000000000000..0b73f9483164
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/MachO.h
@@ -0,0 +1,133 @@
+//===- MachO.h - MachO object file implementation ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MachOObjectFile class, which binds the MachOObject
+// class to the generic ObjectFile wrapper.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHO_H
+#define LLVM_OBJECT_MACHO_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/MachOObject.h"
+#include "llvm/Support/MachO.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+namespace object {
+
+typedef MachOObject::LoadCommandInfo LoadCommandInfo;
+
+class MachOObjectFile : public ObjectFile {
+public:
+ MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec);
+
+ virtual symbol_iterator begin_symbols() const;
+ virtual symbol_iterator end_symbols() const;
+ virtual symbol_iterator begin_dynamic_symbols() const;
+ virtual symbol_iterator end_dynamic_symbols() const;
+ virtual library_iterator begin_libraries_needed() const;
+ virtual library_iterator end_libraries_needed() const;
+ virtual section_iterator begin_sections() const;
+ virtual section_iterator end_sections() const;
+
+ virtual uint8_t getBytesInAddress() const;
+ virtual StringRef getFileFormatName() const;
+ virtual unsigned getArch() const;
+ virtual StringRef getLoadName() const;
+
+ MachOObject *getObject() { return MachOObj; }
+
+ 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;
+ virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
+ virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
+ virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
+ virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
+ virtual error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const;
+
+ virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
+ virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
+ virtual error_code isSectionRequiredForExecution(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 sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S,
+ bool &Result) const;
+ virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
+ virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
+
+ virtual error_code getRelocationNext(DataRefImpl Rel,
+ RelocationRef &Res) const;
+ virtual error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationSymbol(DataRefImpl Rel,
+ SymbolRef &Res) const;
+ virtual error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const;
+ virtual error_code getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const;
+ virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
+ int64_t &Res) const;
+ virtual error_code getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const;
+ virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
+
+ virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
+ virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
+
+private:
+ MachOObject *MachOObj;
+ mutable uint32_t RegisteredStringTable;
+ typedef SmallVector<DataRefImpl, 1> SectionList;
+ SectionList Sections;
+
+
+ void moveToNextSection(DataRefImpl &DRI) const;
+ void getSymbolTableEntry(DataRefImpl DRI,
+ InMemoryStruct<macho::SymbolTableEntry> &Res) const;
+ void getSymbol64TableEntry(DataRefImpl DRI,
+ InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
+ void moveToNextSymbol(DataRefImpl &DRI) const;
+ void getSection(DataRefImpl DRI, InMemoryStruct<macho::Section> &Res) const;
+ void getSection64(DataRefImpl DRI,
+ InMemoryStruct<macho::Section64> &Res) const;
+ void getRelocation(DataRefImpl Rel,
+ InMemoryStruct<macho::RelocationEntry> &Res) const;
+ std::size_t getSectionIndex(DataRefImpl Sec) const;
+
+ void printRelocationTargetName(InMemoryStruct<macho::RelocationEntry>& RE,
+ raw_string_ostream &fmt) const;
+};
+
+}
+}
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Object/MachOFormat.h b/contrib/llvm/include/llvm/Object/MachOFormat.h
new file mode 100644
index 000000000000..089cde92a0a3
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/MachOFormat.h
@@ -0,0 +1,377 @@
+//===- MachOFormat.h - Mach-O Format Structures And Constants ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares various structures and constants which are platform
+// independent and can be shared by any client which wishes to interact with
+// Mach object files.
+//
+// The definitions here are purposely chosen to match the LLVM style as opposed
+// to following the platform specific definition of the format.
+//
+// On a Mach system, see the <mach-o/...> includes for more information, in
+// particular <mach-o/loader.h>.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOFORMAT_H
+#define LLVM_OBJECT_MACHOFORMAT_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+namespace object {
+
+/// General Mach platform information.
+namespace mach {
+ /// @name CPU Type and Subtype Information
+ /// {
+
+ /// \brief Capability bits used in CPU type encoding.
+ enum CPUTypeFlagsMask {
+ CTFM_ArchMask = 0xFF000000,
+ CTFM_ArchABI64 = 0x01000000
+ };
+
+ /// \brief Machine type IDs used in CPU type encoding.
+ enum CPUTypeMachine {
+ CTM_i386 = 7,
+ CTM_x86_64 = CTM_i386 | CTFM_ArchABI64,
+ CTM_ARM = 12,
+ CTM_SPARC = 14,
+ CTM_PowerPC = 18,
+ CTM_PowerPC64 = CTM_PowerPC | CTFM_ArchABI64
+ };
+
+ /// \brief Capability bits used in CPU subtype encoding.
+ enum CPUSubtypeFlagsMask {
+ CSFM_SubtypeMask = 0xFF000000,
+ CSFM_SubtypeLib64 = 0x80000000
+ };
+
+ /// \brief ARM Machine Subtypes.
+ enum CPUSubtypeARM {
+ CSARM_ALL = 0,
+ CSARM_V4T = 5,
+ CSARM_V6 = 6,
+ CSARM_V5TEJ = 7,
+ CSARM_XSCALE = 8,
+ CSARM_V7 = 9
+ };
+
+ /// \brief PowerPC Machine Subtypes.
+ enum CPUSubtypePowerPC {
+ CSPPC_ALL = 0
+ };
+
+ /// \brief SPARC Machine Subtypes.
+ enum CPUSubtypeSPARC {
+ CSSPARC_ALL = 0
+ };
+
+ /// \brief x86 Machine Subtypes.
+ enum CPUSubtypeX86 {
+ CSX86_ALL = 3
+ };
+
+ /// @}
+
+} // end namespace mach
+
+/// Format information for Mach object files.
+namespace macho {
+ /// \brief Constants for structure sizes.
+ enum StructureSizes {
+ Header32Size = 28,
+ Header64Size = 32,
+ SegmentLoadCommand32Size = 56,
+ SegmentLoadCommand64Size = 72,
+ Section32Size = 68,
+ Section64Size = 80,
+ SymtabLoadCommandSize = 24,
+ DysymtabLoadCommandSize = 80,
+ Nlist32Size = 12,
+ Nlist64Size = 16,
+ RelocationInfoSize = 8
+ };
+
+ /// \brief Constants for header magic field.
+ enum HeaderMagic {
+ HM_Object32 = 0xFEEDFACE, ///< 32-bit mach object file
+ HM_Object64 = 0xFEEDFACF, ///< 64-bit mach object file
+ HM_Universal = 0xCAFEBABE ///< Universal object file
+ };
+
+ /// \brief Header common to all Mach object files.
+ struct Header {
+ uint32_t Magic;
+ uint32_t CPUType;
+ uint32_t CPUSubtype;
+ uint32_t FileType;
+ uint32_t NumLoadCommands;
+ uint32_t SizeOfLoadCommands;
+ uint32_t Flags;
+ };
+
+ /// \brief Extended header for 64-bit object files.
+ struct Header64Ext {
+ uint32_t Reserved;
+ };
+
+ // See <mach-o/loader.h>.
+ enum HeaderFileType {
+ HFT_Object = 0x1
+ };
+
+ enum HeaderFlags {
+ HF_SubsectionsViaSymbols = 0x2000
+ };
+
+ enum LoadCommandType {
+ LCT_Segment = 0x1,
+ LCT_Symtab = 0x2,
+ LCT_Dysymtab = 0xb,
+ LCT_Segment64 = 0x19,
+ LCT_UUID = 0x1b,
+ LCT_CodeSignature = 0x1d,
+ LCT_SegmentSplitInfo = 0x1e,
+ LCT_FunctionStarts = 0x26
+ };
+
+ /// \brief Load command structure.
+ struct LoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ };
+
+ /// @name Load Command Structures
+ /// @{
+
+ struct SegmentLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ char Name[16];
+ uint32_t VMAddress;
+ uint32_t VMSize;
+ uint32_t FileOffset;
+ uint32_t FileSize;
+ uint32_t MaxVMProtection;
+ uint32_t InitialVMProtection;
+ uint32_t NumSections;
+ uint32_t Flags;
+ };
+
+ struct Segment64LoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ char Name[16];
+ uint64_t VMAddress;
+ uint64_t VMSize;
+ uint64_t FileOffset;
+ uint64_t FileSize;
+ uint32_t MaxVMProtection;
+ uint32_t InitialVMProtection;
+ uint32_t NumSections;
+ uint32_t Flags;
+ };
+
+ struct SymtabLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ uint32_t SymbolTableOffset;
+ uint32_t NumSymbolTableEntries;
+ uint32_t StringTableOffset;
+ uint32_t StringTableSize;
+ };
+
+ struct DysymtabLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+
+ uint32_t LocalSymbolsIndex;
+ uint32_t NumLocalSymbols;
+
+ uint32_t ExternalSymbolsIndex;
+ uint32_t NumExternalSymbols;
+
+ uint32_t UndefinedSymbolsIndex;
+ uint32_t NumUndefinedSymbols;
+
+ uint32_t TOCOffset;
+ uint32_t NumTOCEntries;
+
+ uint32_t ModuleTableOffset;
+ uint32_t NumModuleTableEntries;
+
+ uint32_t ReferenceSymbolTableOffset;
+ uint32_t NumReferencedSymbolTableEntries;
+
+ uint32_t IndirectSymbolTableOffset;
+ uint32_t NumIndirectSymbolTableEntries;
+
+ uint32_t ExternalRelocationTableOffset;
+ uint32_t NumExternalRelocationTableEntries;
+
+ uint32_t LocalRelocationTableOffset;
+ uint32_t NumLocalRelocationTableEntries;
+ };
+
+ struct LinkeditDataLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ uint32_t DataOffset;
+ uint32_t DataSize;
+ };
+
+ /// @}
+ /// @name Section Data
+ /// @{
+
+ struct Section {
+ char Name[16];
+ char SegmentName[16];
+ uint32_t Address;
+ uint32_t Size;
+ uint32_t Offset;
+ uint32_t Align;
+ uint32_t RelocationTableOffset;
+ uint32_t NumRelocationTableEntries;
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ };
+ struct Section64 {
+ char Name[16];
+ char SegmentName[16];
+ uint64_t Address;
+ uint64_t Size;
+ uint32_t Offset;
+ uint32_t Align;
+ uint32_t RelocationTableOffset;
+ uint32_t NumRelocationTableEntries;
+ uint32_t Flags;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ uint32_t Reserved3;
+ };
+
+ /// @}
+ /// @name Symbol Table Entries
+ /// @{
+
+ struct SymbolTableEntry {
+ uint32_t StringIndex;
+ uint8_t Type;
+ uint8_t SectionIndex;
+ uint16_t Flags;
+ uint32_t Value;
+ };
+ struct Symbol64TableEntry {
+ uint32_t StringIndex;
+ uint8_t Type;
+ uint8_t SectionIndex;
+ uint16_t Flags;
+ uint64_t Value;
+ };
+
+ /// @}
+ /// @name Indirect Symbol Table
+ /// @{
+
+ struct IndirectSymbolTableEntry {
+ uint32_t Index;
+ };
+
+ /// @}
+ /// @name Relocation Data
+ /// @{
+
+ struct RelocationEntry {
+ uint32_t Word0;
+ uint32_t Word1;
+ };
+
+ /// @}
+
+ // See <mach-o/nlist.h>.
+ enum SymbolTypeType {
+ STT_Undefined = 0x00,
+ STT_Absolute = 0x02,
+ STT_Section = 0x0e
+ };
+
+ enum SymbolTypeFlags {
+ // If any of these bits are set, then the entry is a stab entry number (see
+ // <mach-o/stab.h>. Otherwise the other masks apply.
+ STF_StabsEntryMask = 0xe0,
+
+ STF_TypeMask = 0x0e,
+ STF_External = 0x01,
+ STF_PrivateExtern = 0x10
+ };
+
+ /// IndirectSymbolFlags - Flags for encoding special values in the indirect
+ /// symbol entry.
+ enum IndirectSymbolFlags {
+ ISF_Local = 0x80000000,
+ ISF_Absolute = 0x40000000
+ };
+
+ /// RelocationFlags - Special flags for addresses.
+ enum RelocationFlags {
+ RF_Scattered = 0x80000000
+ };
+
+ /// Common relocation info types.
+ enum RelocationInfoType {
+ RIT_Vanilla = 0,
+ RIT_Pair = 1,
+ RIT_Difference = 2
+ };
+
+ /// Generic relocation info types, which are shared by some (but not all)
+ /// platforms.
+ enum RelocationInfoType_Generic {
+ RIT_Generic_PreboundLazyPointer = 3,
+ RIT_Generic_LocalDifference = 4,
+ RIT_Generic_TLV = 5
+ };
+
+ /// X86_64 uses its own relocation types.
+ enum RelocationInfoTypeX86_64 {
+ // Note that x86_64 doesn't even share the common relocation types.
+ RIT_X86_64_Unsigned = 0,
+ RIT_X86_64_Signed = 1,
+ RIT_X86_64_Branch = 2,
+ RIT_X86_64_GOTLoad = 3,
+ RIT_X86_64_GOT = 4,
+ RIT_X86_64_Subtractor = 5,
+ RIT_X86_64_Signed1 = 6,
+ RIT_X86_64_Signed2 = 7,
+ RIT_X86_64_Signed4 = 8,
+ RIT_X86_64_TLV = 9
+ };
+
+ /// ARM uses its own relocation types.
+ enum RelocationInfoTypeARM {
+ RIT_ARM_LocalDifference = 3,
+ RIT_ARM_PreboundLazyPointer = 4,
+ RIT_ARM_Branch24Bit = 5,
+ RIT_ARM_ThumbBranch22Bit = 6,
+ RIT_ARM_ThumbBranch32Bit = 7,
+ RIT_ARM_Half = 8,
+ RIT_ARM_HalfDifference = 9
+
+ };
+
+} // end namespace macho
+
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/MachOObject.h b/contrib/llvm/include/llvm/Object/MachOObject.h
new file mode 100644
index 000000000000..056040274319
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/MachOObject.h
@@ -0,0 +1,204 @@
+//===- MachOObject.h - Mach-O Object File Wrapper ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class MemoryBuffer;
+class raw_ostream;
+
+namespace object {
+
+/// \brief Wrapper object for manipulating Mach-O object files.
+///
+/// This class is designed to implement a full-featured, efficient, portable,
+/// and robust Mach-O interface to Mach-O object files. It does not attempt to
+/// smooth over rough edges in the Mach-O format or generalize access to object
+/// independent features.
+///
+/// The class is designed around accessing the Mach-O object which is expected
+/// to be fully loaded into memory.
+///
+/// This class is *not* suitable for concurrent use. For efficient operation,
+/// the class uses APIs which rely on the ability to cache the results of
+/// certain calls in internal objects which are not safe for concurrent
+/// access. This allows the API to be zero-copy on the common paths.
+//
+// FIXME: It would be cool if we supported a "paged" MemoryBuffer
+// implementation. This would allow us to implement a more sensible version of
+// MemoryObject which can work like a MemoryBuffer, but be more efficient for
+// objects which are in the current address space.
+class MachOObject {
+public:
+ struct LoadCommandInfo {
+ /// The load command information.
+ macho::LoadCommand Command;
+
+ /// The offset to the start of the load command in memory.
+ uint64_t Offset;
+ };
+
+private:
+ OwningPtr<MemoryBuffer> Buffer;
+
+ /// Whether the object is little endian.
+ bool IsLittleEndian;
+ /// Whether the object is 64-bit.
+ bool Is64Bit;
+ /// Whether the object is swapped endianness from the host.
+ bool IsSwappedEndian;
+ /// Whether the string table has been registered.
+ bool HasStringTable;
+
+ /// The cached information on the load commands.
+ LoadCommandInfo *LoadCommands;
+ mutable unsigned NumLoadedCommands;
+
+ /// The cached copy of the header.
+ macho::Header Header;
+ macho::Header64Ext Header64Ext;
+
+ /// Cache string table information.
+ StringRef StringTable;
+
+private:
+ MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
+
+public:
+ ~MachOObject();
+
+ /// \brief Load a Mach-O object from a MemoryBuffer object.
+ ///
+ /// \param Buffer - The buffer to load the object from. This routine takes
+ /// exclusive ownership of the buffer (which is passed to the returned object
+ /// on success).
+ /// \param ErrorStr [out] - If given, will be set to a user readable error
+ /// message on failure.
+ /// \returns The loaded object, or null on error.
+ static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
+ std::string *ErrorStr = 0);
+
+ /// @name File Information
+ /// @{
+
+ bool isLittleEndian() const { return IsLittleEndian; }
+ bool isSwappedEndian() const { return IsSwappedEndian; }
+ bool is64Bit() const { return Is64Bit; }
+
+ unsigned getHeaderSize() const {
+ return Is64Bit ? macho::Header64Size : macho::Header32Size;
+ }
+
+ StringRef getData(size_t Offset, size_t Size) const;
+
+ /// @}
+ /// @name String Table Data
+ /// @{
+
+ StringRef getStringTableData() const {
+ assert(HasStringTable && "String table has not been registered!");
+ return StringTable;
+ }
+
+ StringRef getStringAtIndex(unsigned Index) const {
+ size_t End = getStringTableData().find('\0', Index);
+ return getStringTableData().slice(Index, End);
+ }
+
+ void RegisterStringTable(macho::SymtabLoadCommand &SLC);
+
+ /// @}
+ /// @name Object Header Access
+ /// @{
+
+ const macho::Header &getHeader() const { return Header; }
+ const macho::Header64Ext &getHeader64Ext() const {
+ assert(is64Bit() && "Invalid access!");
+ return Header64Ext;
+ }
+
+ /// @}
+ /// @name Object Structure Access
+ /// @{
+
+ /// \brief Retrieve the information for the given load command.
+ const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
+
+ void ReadSegmentLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
+ void ReadSegment64LoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
+ void ReadSymtabLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
+ void ReadDysymtabLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
+ void ReadLinkeditDataLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
+ void ReadIndirectSymbolTableEntry(
+ const macho::DysymtabLoadCommand &DLC,
+ unsigned Index,
+ InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
+ void ReadSection(
+ const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section> &Res) const;
+ void ReadSection64(
+ const LoadCommandInfo &LCI,
+ unsigned Index,
+ InMemoryStruct<macho::Section64> &Res) const;
+ void ReadRelocationEntry(
+ uint64_t RelocationTableOffset, unsigned Index,
+ InMemoryStruct<macho::RelocationEntry> &Res) const;
+ void ReadSymbolTableEntry(
+ uint64_t SymbolTableOffset, unsigned Index,
+ InMemoryStruct<macho::SymbolTableEntry> &Res) const;
+ void ReadSymbol64TableEntry(
+ uint64_t SymbolTableOffset, unsigned Index,
+ InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
+ void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+
+ /// @}
+
+ /// @name Object Dump Facilities
+ /// @{
+ /// dump - Support for debugging, callable in GDB: V->dump()
+ //
+ void dump() const;
+ void dumpHeader() const;
+
+ /// print - Implement operator<< on Value.
+ ///
+ void print(raw_ostream &O) const;
+ void printHeader(raw_ostream &O) const;
+
+ /// @}
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
+ V.print(OS);
+ return OS;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Object/ObjectFile.h b/contrib/llvm/include/llvm/Object/ObjectFile.h
new file mode 100644
index 000000000000..4dd7fb581308
--- /dev/null
+++ b/contrib/llvm/include/llvm/Object/ObjectFile.h
@@ -0,0 +1,597 @@
+//===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares a file format independent ObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_OBJECT_FILE_H
+#define LLVM_OBJECT_OBJECT_FILE_H
+
+#include "llvm/Object/Binary.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstring>
+#include <vector>
+
+namespace llvm {
+namespace object {
+
+class ObjectFile;
+
+union DataRefImpl {
+ struct {
+ // ELF needs this for relocations. This entire union should probably be a
+ // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
+ uint16_t a, b;
+ uint32_t c;
+ } w;
+ struct {
+ uint32_t a, b;
+ } d;
+ uintptr_t p;
+ DataRefImpl() {
+ std::memset(this, 0, sizeof(DataRefImpl));
+ }
+};
+
+template<class content_type>
+class content_iterator {
+ content_type Current;
+public:
+ content_iterator(content_type symb)
+ : Current(symb) {}
+
+ const content_type* operator->() const {
+ return &Current;
+ }
+
+ const content_type &operator*() const {
+ return Current;
+ }
+
+ bool operator==(const content_iterator &other) const {
+ return Current == other.Current;
+ }
+
+ bool operator!=(const content_iterator &other) const {
+ return !(*this == other);
+ }
+
+ content_iterator& increment(error_code &err) {
+ content_type next;
+ if (error_code ec = Current.getNext(next))
+ err = ec;
+ else
+ Current = next;
+ return *this;
+ }
+};
+
+static 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;
+}
+
+static 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;
+}
+
+class SymbolRef;
+
+/// RelocationRef - This is a value type class that represents a single
+/// relocation in the list of relocations in the object file.
+class RelocationRef {
+ DataRefImpl RelocationPimpl;
+ const ObjectFile *OwningObject;
+
+public:
+ RelocationRef() : OwningObject(NULL) { }
+
+ RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
+
+ bool operator==(const RelocationRef &Other) const;
+
+ error_code getNext(RelocationRef &Result) const;
+
+ error_code getAddress(uint64_t &Result) const;
+ error_code getOffset(uint64_t &Result) const;
+ error_code getSymbol(SymbolRef &Result) const;
+ error_code getType(uint64_t &Result) const;
+
+ /// @brief Indicates whether this relocation should hidden when listing
+ /// relocations, usually because it is the trailing part of a multipart
+ /// relocation that will be printed as part of the leading relocation.
+ error_code getHidden(bool &Result) const;
+
+ /// @brief Get a string that represents the type of this relocation.
+ ///
+ /// This is for display purposes only.
+ error_code getTypeName(SmallVectorImpl<char> &Result) const;
+ error_code getAdditionalInfo(int64_t &Result) const;
+
+ /// @brief Get a string that represents the calculation of the value of this
+ /// relocation.
+ ///
+ /// This is for display purposes only.
+ error_code getValueString(SmallVectorImpl<char> &Result) const;
+};
+typedef content_iterator<RelocationRef> relocation_iterator;
+
+/// SectionRef - This is a value type class that represents a single section in
+/// the list of sections in the object file.
+class SectionRef {
+ friend class SymbolRef;
+ DataRefImpl SectionPimpl;
+ const ObjectFile *OwningObject;
+
+public:
+ SectionRef() : OwningObject(NULL) { }
+
+ SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
+
+ bool operator==(const SectionRef &Other) const;
+ bool operator <(const SectionRef &Other) const;
+
+ error_code getNext(SectionRef &Result) const;
+
+ error_code getName(StringRef &Result) const;
+ error_code getAddress(uint64_t &Result) const;
+ error_code getSize(uint64_t &Result) const;
+ error_code getContents(StringRef &Result) const;
+
+ /// @brief Get the alignment of this section as the actual value (not log 2).
+ error_code getAlignment(uint64_t &Result) const;
+
+ // FIXME: Move to the normalization layer when it's created.
+ error_code isText(bool &Result) const;
+ error_code isData(bool &Result) const;
+ error_code isBSS(bool &Result) const;
+ error_code isRequiredForExecution(bool &Result) const;
+ error_code isVirtual(bool &Result) const;
+ error_code isZeroInit(bool &Result) const;
+
+ error_code containsSymbol(SymbolRef S, bool &Result) const;
+
+ relocation_iterator begin_relocations() const;
+ relocation_iterator end_relocations() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+};
+typedef content_iterator<SectionRef> section_iterator;
+
+/// SymbolRef - This is a value type class that represents a single symbol in
+/// the list of symbols in the object file.
+class SymbolRef {
+ friend class SectionRef;
+ DataRefImpl SymbolPimpl;
+ const ObjectFile *OwningObject;
+
+public:
+ SymbolRef() : OwningObject(NULL) { }
+
+ enum Type {
+ ST_Unknown, // Type not specified
+ ST_Data,
+ ST_Debug,
+ ST_File,
+ ST_Function,
+ ST_Other
+ };
+
+ enum Flags {
+ SF_None = 0,
+ SF_Undefined = 1U << 0, // Symbol is defined in another object file
+ SF_Global = 1U << 1, // Global symbol
+ SF_Weak = 1U << 2, // Weak symbol
+ SF_Absolute = 1U << 3, // Absolute symbol
+ SF_ThreadLocal = 1U << 4, // Thread local symbol
+ SF_Common = 1U << 5, // Symbol has common linkage
+ SF_FormatSpecific = 1U << 31 // Specific to the object file format
+ // (e.g. section symbols)
+ };
+
+ SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
+
+ bool operator==(const SymbolRef &Other) const;
+ bool operator <(const SymbolRef &Other) const;
+
+ error_code getNext(SymbolRef &Result) const;
+
+ error_code getName(StringRef &Result) const;
+ error_code getAddress(uint64_t &Result) const;
+ error_code getFileOffset(uint64_t &Result) const;
+ error_code getSize(uint64_t &Result) const;
+ error_code getType(SymbolRef::Type &Result) const;
+
+ /// Returns the ascii char that should be displayed in a symbol table dump via
+ /// nm for this symbol.
+ error_code getNMTypeChar(char &Result) const;
+
+ /// Get symbol flags (bitwise OR of SymbolRef::Flags)
+ error_code getFlags(uint32_t &Result) const;
+
+ /// @brief Return true for common symbols such as uninitialized globals
+ error_code isCommon(bool &Result) const;
+
+ /// @brief Get section this symbol is defined in reference to. Result is
+ /// end_sections() if it is undefined or is an absolute symbol.
+ error_code getSection(section_iterator &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
+};
+typedef content_iterator<SymbolRef> symbol_iterator;
+
+/// LibraryRef - This is a value type class that represents a single library in
+/// the list of libraries needed by a shared or dynamic object.
+class LibraryRef {
+ friend class SectionRef;
+ DataRefImpl LibraryPimpl;
+ const ObjectFile *OwningObject;
+
+public:
+ LibraryRef() : OwningObject(NULL) { }
+
+ LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
+
+ bool operator==(const LibraryRef &Other) const;
+ bool operator <(const LibraryRef &Other) const;
+
+ error_code getNext(LibraryRef &Result) const;
+
+ // Get the path to this library, as stored in the object file.
+ error_code getPath(StringRef &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
+};
+typedef content_iterator<LibraryRef> library_iterator;
+
+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.
+class ObjectFile : public Binary {
+ virtual void anchor();
+ ObjectFile(); // = delete
+ ObjectFile(const ObjectFile &other); // = delete
+
+protected:
+ ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
+
+ const uint8_t *base() const {
+ return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
+ }
+
+ // These functions are for SymbolRef to call internally. The main goal of
+ // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
+ // entry in the memory mapped object file. SymbolPimpl cannot contain any
+ // virtual functions because then it could not point into the memory mapped
+ // file.
+ //
+ // Implementations assume that the DataRefImpl is valid and has not been
+ // modified externally. It's UB otherwise.
+ 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 getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
+ virtual error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const = 0;
+ virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
+ virtual error_code getSymbolFlags(DataRefImpl Symb,
+ uint32_t &Res) const = 0;
+ virtual error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const = 0;
+
+ // Same as above for SectionRef.
+ friend class SectionRef;
+ virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
+ virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
+ virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
+ virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
+ virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
+ virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0;
+ virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
+ virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
+ virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
+ virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const = 0;
+ // 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 sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const = 0;
+ virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0;
+ virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const = 0;
+
+
+ // Same as above for RelocationRef.
+ friend class RelocationRef;
+ virtual error_code getRelocationNext(DataRefImpl Rel,
+ RelocationRef &Res) const = 0;
+ virtual error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const =0;
+ virtual error_code getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Res) const =0;
+ virtual error_code getRelocationSymbol(DataRefImpl Rel,
+ SymbolRef &Res) const = 0;
+ virtual error_code getRelocationType(DataRefImpl Rel,
+ uint64_t &Res) const = 0;
+ virtual error_code getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+ virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
+ int64_t &Res) const = 0;
+ virtual error_code getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+ virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const {
+ Result = false;
+ return object_error::success;
+ }
+
+ // Same for LibraryRef
+ friend class LibraryRef;
+ virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
+ virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
+
+public:
+
+ virtual symbol_iterator begin_symbols() const = 0;
+ virtual symbol_iterator end_symbols() const = 0;
+
+ virtual symbol_iterator begin_dynamic_symbols() const = 0;
+ virtual symbol_iterator end_dynamic_symbols() const = 0;
+
+ virtual section_iterator begin_sections() const = 0;
+ virtual section_iterator end_sections() const = 0;
+
+ virtual library_iterator begin_libraries_needed() const = 0;
+ virtual library_iterator end_libraries_needed() const = 0;
+
+ /// @brief The number of bytes used to represent an address in this object
+ /// file format.
+ virtual uint8_t getBytesInAddress() const = 0;
+
+ virtual StringRef getFileFormatName() const = 0;
+ virtual /* Triple::ArchType */ unsigned getArch() const = 0;
+
+ /// For shared objects, returns the name which this object should be
+ /// loaded from at runtime. This corresponds to DT_SONAME on ELF and
+ /// LC_ID_DYLIB (install name) on MachO.
+ virtual StringRef getLoadName() const = 0;
+
+ /// @returns Pointer to ObjectFile subclass to handle this type of object.
+ /// @param ObjectPath The path to the object file. ObjectPath.isObject must
+ /// return true.
+ /// @brief Create ObjectFile from path.
+ static ObjectFile *createObjectFile(StringRef ObjectPath);
+ static ObjectFile *createObjectFile(MemoryBuffer *Object);
+
+ 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);
+ static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
+ static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
+};
+
+// Inline function definitions.
+inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
+ : SymbolPimpl(SymbolP)
+ , OwningObject(Owner) {}
+
+inline bool SymbolRef::operator==(const SymbolRef &Other) const {
+ return SymbolPimpl == Other.SymbolPimpl;
+}
+
+inline bool SymbolRef::operator <(const SymbolRef &Other) const {
+ return SymbolPimpl < Other.SymbolPimpl;
+}
+
+inline error_code SymbolRef::getNext(SymbolRef &Result) const {
+ return OwningObject->getSymbolNext(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getName(StringRef &Result) const {
+ return OwningObject->getSymbolName(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getAddress(uint64_t &Result) const {
+ return OwningObject->getSymbolAddress(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
+ return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getSize(uint64_t &Result) const {
+ return OwningObject->getSymbolSize(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getNMTypeChar(char &Result) const {
+ return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getFlags(uint32_t &Result) const {
+ return OwningObject->getSymbolFlags(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getSection(section_iterator &Result) const {
+ return OwningObject->getSymbolSection(SymbolPimpl, Result);
+}
+
+inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
+ return OwningObject->getSymbolType(SymbolPimpl, Result);
+}
+
+inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
+ return SymbolPimpl;
+}
+
+
+/// SectionRef
+inline SectionRef::SectionRef(DataRefImpl SectionP,
+ const ObjectFile *Owner)
+ : SectionPimpl(SectionP)
+ , OwningObject(Owner) {}
+
+inline bool SectionRef::operator==(const SectionRef &Other) const {
+ return SectionPimpl == Other.SectionPimpl;
+}
+
+inline bool SectionRef::operator <(const SectionRef &Other) const {
+ return SectionPimpl < Other.SectionPimpl;
+}
+
+inline error_code SectionRef::getNext(SectionRef &Result) const {
+ return OwningObject->getSectionNext(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::getName(StringRef &Result) const {
+ return OwningObject->getSectionName(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::getAddress(uint64_t &Result) const {
+ return OwningObject->getSectionAddress(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::getSize(uint64_t &Result) const {
+ return OwningObject->getSectionSize(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::getContents(StringRef &Result) const {
+ return OwningObject->getSectionContents(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::getAlignment(uint64_t &Result) const {
+ return OwningObject->getSectionAlignment(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::isText(bool &Result) const {
+ return OwningObject->isSectionText(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::isData(bool &Result) const {
+ return OwningObject->isSectionData(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::isBSS(bool &Result) const {
+ return OwningObject->isSectionBSS(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::isRequiredForExecution(bool &Result) const {
+ return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::isVirtual(bool &Result) const {
+ return OwningObject->isSectionVirtual(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::isZeroInit(bool &Result) const {
+ return OwningObject->isSectionZeroInit(SectionPimpl, Result);
+}
+
+inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
+ return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
+ Result);
+}
+
+inline relocation_iterator SectionRef::begin_relocations() const {
+ return OwningObject->getSectionRelBegin(SectionPimpl);
+}
+
+inline relocation_iterator SectionRef::end_relocations() const {
+ return OwningObject->getSectionRelEnd(SectionPimpl);
+}
+
+inline DataRefImpl SectionRef::getRawDataRefImpl() const {
+ return SectionPimpl;
+}
+
+/// RelocationRef
+inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
+ const ObjectFile *Owner)
+ : RelocationPimpl(RelocationP)
+ , OwningObject(Owner) {}
+
+inline bool RelocationRef::operator==(const RelocationRef &Other) const {
+ return RelocationPimpl == Other.RelocationPimpl;
+}
+
+inline error_code RelocationRef::getNext(RelocationRef &Result) const {
+ return OwningObject->getRelocationNext(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getAddress(uint64_t &Result) const {
+ return OwningObject->getRelocationAddress(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getOffset(uint64_t &Result) const {
+ return OwningObject->getRelocationOffset(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
+ return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getType(uint64_t &Result) const {
+ return OwningObject->getRelocationType(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result)
+ const {
+ return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const {
+ return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
+ const {
+ return OwningObject->getRelocationValueString(RelocationPimpl, Result);
+}
+
+inline error_code RelocationRef::getHidden(bool &Result) const {
+ return OwningObject->getRelocationHidden(RelocationPimpl, Result);
+}
+// Inline function definitions.
+inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
+ : LibraryPimpl(LibraryP)
+ , OwningObject(Owner) {}
+
+inline bool LibraryRef::operator==(const LibraryRef &Other) const {
+ return LibraryPimpl == Other.LibraryPimpl;
+}
+
+inline bool LibraryRef::operator <(const LibraryRef &Other) const {
+ return LibraryPimpl < Other.LibraryPimpl;
+}
+
+inline error_code LibraryRef::getNext(LibraryRef &Result) const {
+ return OwningObject->getLibraryNext(LibraryPimpl, Result);
+}
+
+inline error_code LibraryRef::getPath(StringRef &Result) const {
+ return OwningObject->getLibraryPath(LibraryPimpl, Result);
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/OperandTraits.h b/contrib/llvm/include/llvm/OperandTraits.h
new file mode 100644
index 000000000000..3d8dc329b39f
--- /dev/null
+++ b/contrib/llvm/include/llvm/OperandTraits.h
@@ -0,0 +1,160 @@
+//===-- llvm/OperandTraits.h - OperandTraits class definition ---*- 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 traits classes that are handy for enforcing the correct
+// layout of various User subclasses. It also provides the means for accessing
+// the operands in the most efficient manner.
+//
+
+#ifndef LLVM_OPERAND_TRAITS_H
+#define LLVM_OPERAND_TRAITS_H
+
+#include "llvm/User.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// FixedNumOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// FixedNumOperandTraits - determine the allocation regime of the Use array
+/// when it is a prefix to the User object, and the number of Use objects is
+/// known at compile time.
+
+template <typename SubClass, unsigned ARITY>
+struct FixedNumOperandTraits {
+ static Use *op_begin(SubClass* U) {
+ return reinterpret_cast<Use*>(U) - ARITY;
+ }
+ static Use *op_end(SubClass* U) {
+ return reinterpret_cast<Use*>(U);
+ }
+ static unsigned operands(const User*) {
+ return ARITY;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// OptionalOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// OptionalOperandTraits - when the number of operands may change at runtime.
+/// Naturally it may only decrease, because the allocations may not change.
+
+template <typename SubClass, unsigned ARITY = 1>
+struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> {
+ static unsigned operands(const User *U) {
+ return U->getNumOperands();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// VariadicOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// VariadicOperandTraits - determine the allocation regime of the Use array
+/// when it is a prefix to the User object, and the number of Use objects is
+/// only known at allocation time.
+
+template <typename SubClass, unsigned MINARITY = 0>
+struct VariadicOperandTraits {
+ static Use *op_begin(SubClass* U) {
+ return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands();
+ }
+ static Use *op_end(SubClass* U) {
+ return reinterpret_cast<Use*>(U);
+ }
+ static unsigned operands(const User *U) {
+ return U->getNumOperands();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// HungoffOperand Trait Class
+//===----------------------------------------------------------------------===//
+
+/// HungoffOperandTraits - determine the allocation regime of the Use array
+/// when it is not a prefix to the User object, but allocated at an unrelated
+/// heap address.
+/// Assumes that the User subclass that is determined by this traits class
+/// has an OperandList member of type User::op_iterator. [Note: this is now
+/// trivially satisfied, because User has that member for historic reasons.]
+///
+/// This is the traits class that is needed when the Use array must be
+/// resizable.
+
+template <unsigned MINARITY = 1>
+struct HungoffOperandTraits {
+ static Use *op_begin(User* U) {
+ return U->OperandList;
+ }
+ static Use *op_end(User* U) {
+ return U->OperandList + U->getNumOperands();
+ }
+ static unsigned operands(const User *U) {
+ return U->getNumOperands();
+ }
+};
+
+/// Macro for generating in-class operand accessor declarations.
+/// It should only be called in the public section of the interface.
+///
+#define DECLARE_TRANSPARENT_OPERAND_ACCESSORS(VALUECLASS) \
+ public: \
+ inline VALUECLASS *getOperand(unsigned) const; \
+ inline void setOperand(unsigned, VALUECLASS*); \
+ inline op_iterator op_begin(); \
+ inline const_op_iterator op_begin() const; \
+ inline op_iterator op_end(); \
+ inline const_op_iterator op_end() const; \
+ protected: \
+ template <int> inline Use &Op(); \
+ template <int> inline const Use &Op() const; \
+ public: \
+ inline unsigned getNumOperands() const
+
+/// Macro for generating out-of-class operand accessor definitions
+#define DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CLASS, VALUECLASS) \
+CLASS::op_iterator CLASS::op_begin() { \
+ return OperandTraits<CLASS>::op_begin(this); \
+} \
+CLASS::const_op_iterator CLASS::op_begin() const { \
+ return OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this)); \
+} \
+CLASS::op_iterator CLASS::op_end() { \
+ return OperandTraits<CLASS>::op_end(this); \
+} \
+CLASS::const_op_iterator CLASS::op_end() const { \
+ return OperandTraits<CLASS>::op_end(const_cast<CLASS*>(this)); \
+} \
+VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \
+ assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
+ && "getOperand() out of range!"); \
+ return cast_or_null<VALUECLASS>( \
+ OperandTraits<CLASS>::op_begin(const_cast<CLASS*>(this))[i_nocapture].get()); \
+} \
+void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \
+ assert(i_nocapture < OperandTraits<CLASS>::operands(this) \
+ && "setOperand() out of range!"); \
+ OperandTraits<CLASS>::op_begin(this)[i_nocapture] = Val_nocapture; \
+} \
+unsigned CLASS::getNumOperands() const { \
+ return OperandTraits<CLASS>::operands(this); \
+} \
+template <int Idx_nocapture> Use &CLASS::Op() { \
+ return this->OpFrom<Idx_nocapture>(this); \
+} \
+template <int Idx_nocapture> const Use &CLASS::Op() const { \
+ return this->OpFrom<Idx_nocapture>(this); \
+}
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Operator.h b/contrib/llvm/include/llvm/Operator.h
new file mode 100644
index 000000000000..1e86980cf303
--- /dev/null
+++ b/contrib/llvm/include/llvm/Operator.h
@@ -0,0 +1,326 @@
+//===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various classes for working with Instructions and
+// ConstantExprs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPERATOR_H
+#define LLVM_OPERATOR_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instruction.h"
+#include "llvm/Type.h"
+
+namespace llvm {
+
+class GetElementPtrInst;
+class BinaryOperator;
+class ConstantExpr;
+
+/// Operator - This is a utility class that provides an abstraction for the
+/// common functionality between Instructions and ConstantExprs.
+///
+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();
+ ~Operator();
+
+public:
+ /// getOpcode - Return the opcode for this Instruction or ConstantExpr.
+ ///
+ unsigned getOpcode() const {
+ if (const Instruction *I = dyn_cast<Instruction>(this))
+ return I->getOpcode();
+ return cast<ConstantExpr>(this)->getOpcode();
+ }
+
+ /// getOpcode - If V is an Instruction or ConstantExpr, return its
+ /// opcode. Otherwise return UserOp1.
+ ///
+ static unsigned getOpcode(const Value *V) {
+ if (const Instruction *I = dyn_cast<Instruction>(V))
+ return I->getOpcode();
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode();
+ 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) {
+ return isa<Instruction>(V) || isa<ConstantExpr>(V);
+ }
+};
+
+/// OverflowingBinaryOperator - Utility class for integer arithmetic operators
+/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv,
+/// despite that operator having the potential for overflow.
+///
+class OverflowingBinaryOperator : public Operator {
+public:
+ enum {
+ NoUnsignedWrap = (1 << 0),
+ NoSignedWrap = (1 << 1)
+ };
+
+private:
+ ~OverflowingBinaryOperator(); // do not implement
+
+ friend class BinaryOperator;
+ friend class ConstantExpr;
+ void setHasNoUnsignedWrap(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
+ }
+ void setHasNoSignedWrap(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
+ }
+
+public:
+ /// hasNoUnsignedWrap - Test whether this operation is known to never
+ /// undergo unsigned overflow, aka the nuw property.
+ bool hasNoUnsignedWrap() const {
+ return SubclassOptionalData & NoUnsignedWrap;
+ }
+
+ /// hasNoSignedWrap - Test whether this operation is known to never
+ /// undergo signed overflow, aka the nsw property.
+ bool hasNoSignedWrap() const {
+ 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 ||
+ I->getOpcode() == Instruction::Mul ||
+ I->getOpcode() == Instruction::Shl;
+ }
+ static inline bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Instruction::Add ||
+ CE->getOpcode() == Instruction::Sub ||
+ CE->getOpcode() == Instruction::Mul ||
+ CE->getOpcode() == Instruction::Shl;
+ }
+ static inline bool classof(const Value *V) {
+ return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ }
+};
+
+/// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as
+/// "exact", indicating that no bits are destroyed.
+class PossiblyExactOperator : public Operator {
+public:
+ enum {
+ IsExact = (1 << 0)
+ };
+
+private:
+ ~PossiblyExactOperator(); // do not implement
+
+ 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 ||
+ OpC == Instruction::AShr ||
+ OpC == Instruction::LShr;
+ }
+ static inline bool classof(const ConstantExpr *CE) {
+ return isPossiblyExactOpcode(CE->getOpcode());
+ }
+ static inline bool classof(const Instruction *I) {
+ return isPossiblyExactOpcode(I->getOpcode());
+ }
+ static inline bool classof(const Value *V) {
+ return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ }
+};
+
+/// 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
+
+public:
+
+ /// \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();
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+/// 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;
+ }
+ static inline bool classof(const ConstantExpr *CE) {
+ return CE->getOpcode() == Opc;
+ }
+ static inline bool classof(const Value *V) {
+ return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
+ (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
+ }
+};
+
+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)
+ };
+
+ friend class GetElementPtrInst;
+ friend class ConstantExpr;
+ void setIsInBounds(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
+ }
+
+public:
+ /// isInBounds - Test whether this is an inbounds GEP, as defined
+ /// by LangRef.html.
+ bool isInBounds() const {
+ return SubclassOptionalData & IsInBounds;
+ }
+
+ 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(); }
+ inline const_op_iterator idx_end() const { return op_end(); }
+
+ Value *getPointerOperand() {
+ return getOperand(0);
+ }
+ const Value *getPointerOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getPointerOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ /// getPointerOperandType - Method to return the pointer operand as a
+ /// PointerType.
+ Type *getPointerOperandType() const {
+ return getPointerOperand()->getType();
+ }
+
+ unsigned getNumIndices() const { // Note: always non-negative
+ return getNumOperands() - 1;
+ }
+
+ bool hasIndices() const {
+ return getNumOperands() > 1;
+ }
+
+ /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+ /// zeros. If so, the result pointer and the first operand have the same
+ /// value, just potentially different types.
+ bool hasAllZeroIndices() const {
+ for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+ if (ConstantInt *C = dyn_cast<ConstantInt>(I))
+ if (C->isZero())
+ continue;
+ return false;
+ }
+ return true;
+ }
+
+ /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+ /// constant integers. If so, the result pointer and the first operand have
+ /// a constant offset between them.
+ bool hasAllConstantIndices() const {
+ for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
+ if (!isa<ConstantInt>(I))
+ return false;
+ }
+ return true;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Pass.h b/contrib/llvm/include/llvm/Pass.h
new file mode 100644
index 000000000000..888537daa425
--- /dev/null
+++ b/contrib/llvm/include/llvm/Pass.h
@@ -0,0 +1,375 @@
+//===- llvm/Pass.h - Base class for Passes ----------------------*- 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 base class that indicates that a specified class is a
+// transformation pass implementation.
+//
+// Passes are designed this way so that it is possible to run passes in a cache
+// and organizationally optimal order without having to specify it at the front
+// end. This allows arbitrary passes to be strung together and have them
+// executed as efficiently as possible.
+//
+// Passes should extend one of the classes below, depending on the guarantees
+// that it can make about what will be modified as it is run. For example, most
+// global optimizations should derive from FunctionPass, because they do not add
+// or delete functions, they operate on the internals of the function.
+//
+// Note that this file #includes PassSupport.h and PassAnalysisSupport.h (at the
+// bottom), so the APIs exposed by these files are also automatically available
+// to all users of this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASS_H
+#define LLVM_PASS_H
+
+#include <string>
+
+namespace llvm {
+
+class BasicBlock;
+class Function;
+class Module;
+class AnalysisUsage;
+class PassInfo;
+class ImmutablePass;
+class PMStack;
+class AnalysisResolver;
+class PMDataManager;
+class raw_ostream;
+class StringRef;
+
+// AnalysisID - Use the PassInfo to identify a pass...
+typedef const void* AnalysisID;
+
+/// Different types of internal pass managers. External pass managers
+/// (PassManager and FunctionPassManager) are not represented here.
+/// Ordering of pass manager types is important here.
+enum PassManagerType {
+ PMT_Unknown = 0,
+ PMT_ModulePassManager = 1, ///< MPPassManager
+ PMT_CallGraphPassManager, ///< CGPassManager
+ PMT_FunctionPassManager, ///< FPPassManager
+ PMT_LoopPassManager, ///< LPPassManager
+ PMT_RegionPassManager, ///< RGPassManager
+ PMT_BasicBlockPassManager, ///< BBPassManager
+ PMT_Last
+};
+
+// Different types of passes.
+enum PassKind {
+ PT_BasicBlock,
+ PT_Region,
+ PT_Loop,
+ PT_Function,
+ PT_CallGraphSCC,
+ PT_Module,
+ PT_PassManager
+};
+
+//===----------------------------------------------------------------------===//
+/// Pass interface - Implemented by all 'passes'. Subclass this if you are an
+/// interprocedural optimization or you do not fit into any of the more
+/// constrained passes described below.
+///
+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
+
+public:
+ explicit Pass(PassKind K, char &pid) : Resolver(0), PassID(&pid), Kind(K) { }
+ virtual ~Pass();
+
+
+ PassKind getPassKind() const { return Kind; }
+
+ /// getPassName - Return a nice clean name for a pass. This usually
+ /// implemented in terms of the name that is registered by one of the
+ /// Registration templates, but can be overloaded directly.
+ ///
+ virtual const char *getPassName() const;
+
+ /// getPassID - Return the PassID number that corresponds to this pass.
+ AnalysisID getPassID() const {
+ return PassID;
+ }
+
+ /// 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
+ /// null. This automatically forwards to a virtual function that does not
+ /// provide the Module* in case the analysis doesn't need it it can just be
+ /// ignored.
+ ///
+ virtual void print(raw_ostream &O, const Module *M) const;
+ void dump() const; // dump - Print to stderr.
+
+ /// createPrinterPass - Get a Pass appropriate to print the IR this
+ /// pass operates on (Module, Function or MachineFunction).
+ virtual Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const = 0;
+
+ /// Each pass is responsible for assigning a pass manager to itself.
+ /// PMS is the stack of available pass manager.
+ virtual void assignPassManager(PMStack &,
+ PassManagerType) {}
+ /// Check if available pass managers are suitable for this pass or not.
+ virtual void preparePassManager(PMStack &);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const;
+
+ // Access AnalysisResolver
+ void setResolver(AnalysisResolver *AR);
+ AnalysisResolver *getResolver() const { return Resolver; }
+
+ /// getAnalysisUsage - This function should be overriden by passes that need
+ /// analysis information to do their job. If a pass specifies that it uses a
+ /// particular analysis result to this function, it can then use the
+ /// getAnalysis<AnalysisType>() function, below.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &) const;
+
+ /// releaseMemory() - This member can be implemented by a pass if it wants to
+ /// be able to release its memory when it is no longer needed. The default
+ /// behavior of passes is to hold onto memory for the entire duration of their
+ /// lifetime (which is the entire compile time). For pipelined passes, this
+ /// is not a big deal because that memory gets recycled every time the pass is
+ /// invoked on another program unit. For IP passes, it is more important to
+ /// free memory when it is unused.
+ ///
+ /// Optionally implement this function to release pass memory when it is no
+ /// longer used.
+ ///
+ virtual void releaseMemory();
+
+ /// getAdjustedAnalysisPointer - This method is used when a pass implements
+ /// an analysis interface through multiple inheritance. If needed, it should
+ /// override this to adjust the this pointer as needed for the specified pass
+ /// info.
+ virtual void *getAdjustedAnalysisPointer(AnalysisID ID);
+ virtual ImmutablePass *getAsImmutablePass();
+ virtual PMDataManager *getAsPMDataManager();
+
+ /// verifyAnalysis() - This member can be implemented by a analysis pass to
+ /// check state of analysis information.
+ virtual void verifyAnalysis() const;
+
+ // dumpPassStructure - Implement the -debug-passes=PassStructure option
+ virtual void dumpPassStructure(unsigned Offset = 0);
+
+ // lookupPassInfo - Return the pass info object for the specified pass class,
+ // or null if it is not known.
+ static const PassInfo *lookupPassInfo(const void *TI);
+
+ // lookupPassInfo - Return the pass info object for the pass with the given
+ // argument string, or null if it is not known.
+ static const PassInfo *lookupPassInfo(StringRef Arg);
+
+ // createPass - Create a object for the specified pass class,
+ // or null if it is not known.
+ static Pass *createPass(AnalysisID ID);
+
+ /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+ /// get analysis information that might be around, for example to update it.
+ /// This is different than getAnalysis in that it can fail (if the analysis
+ /// results haven't been computed), so should only be used if you can handle
+ /// the case when the analysis is not available. This method is often used by
+ /// transformation APIs to update analysis results for a pass automatically as
+ /// the transform is performed.
+ ///
+ template<typename AnalysisType> AnalysisType *
+ getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
+
+ /// mustPreserveAnalysisID - This method serves the same function as
+ /// getAnalysisIfAvailable, but works if you just have an AnalysisID. This
+ /// obviously cannot give you a properly typed instance of the class if you
+ /// don't have the class name available (use getAnalysisIfAvailable if you
+ /// do), but it can tell you if you need to preserve the pass at least.
+ ///
+ bool mustPreserveAnalysisID(char &AID) const;
+
+ /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+ /// to the analysis information that they claim to use by overriding the
+ /// getAnalysisUsage function.
+ ///
+ template<typename AnalysisType>
+ AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
+
+ template<typename AnalysisType>
+ AnalysisType &getAnalysis(Function &F); // Defined in PassAnalysisSupport.h
+
+ template<typename AnalysisType>
+ AnalysisType &getAnalysisID(AnalysisID PI) const;
+
+ template<typename AnalysisType>
+ AnalysisType &getAnalysisID(AnalysisID PI, Function &F);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ModulePass class - This class is used to implement unstructured
+/// interprocedural optimizations and analyses. ModulePasses may do anything
+/// they want to the program.
+///
+class ModulePass : public Pass {
+public:
+ /// createPrinterPass - Get a module printer pass.
+ Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+
+ /// runOnModule - Virtual method overriden by subclasses to process the module
+ /// being operated on.
+ virtual bool runOnModule(Module &M) = 0;
+
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType T);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const;
+
+ explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
+ // Force out-of-line virtual method.
+ virtual ~ModulePass();
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ImmutablePass class - This class is used to provide information that does
+/// not need to be run. This is useful for things like target information and
+/// "basic" versions of AnalysisGroups.
+///
+class ImmutablePass : public ModulePass {
+public:
+ /// initializePass - This method may be overriden by immutable passes to allow
+ /// them to perform various initialization actions they require. This is
+ /// primarily because an ImmutablePass can "require" another ImmutablePass,
+ /// and if it does, the overloaded version of initializePass may get access to
+ /// these passes with getAnalysis<>.
+ ///
+ virtual void initializePass();
+
+ virtual ImmutablePass *getAsImmutablePass() { return this; }
+
+ /// ImmutablePasses are never run.
+ ///
+ bool runOnModule(Module &) { return false; }
+
+ explicit ImmutablePass(char &pid)
+ : ModulePass(pid) {}
+
+ // Force out-of-line virtual method.
+ virtual ~ImmutablePass();
+};
+
+//===----------------------------------------------------------------------===//
+/// FunctionPass class - This class is used to implement most global
+/// optimizations. Optimizations should subclass this class if they meet the
+/// following constraints:
+///
+/// 1. Optimizations are organized globally, i.e., a function at a time
+/// 2. Optimizing a function does not cause the addition or removal of any
+/// functions in the module
+///
+class FunctionPass : public Pass {
+public:
+ explicit FunctionPass(char &pid) : Pass(PT_Function, pid) {}
+
+ /// 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);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const;
+};
+
+
+
+//===----------------------------------------------------------------------===//
+/// BasicBlockPass class - This class is used to implement most local
+/// optimizations. Optimizations should subclass this class if they
+/// meet the following constraints:
+/// 1. Optimizations are local, operating on either a basic block or
+/// instruction at a time.
+/// 2. Optimizations do not modify the CFG of the contained function, or any
+/// other basic block in the function.
+/// 3. Optimizations conform to all of the constraints of FunctionPasses.
+///
+class BasicBlockPass : public Pass {
+public:
+ explicit BasicBlockPass(char &pid) : Pass(PT_BasicBlock, pid) {}
+
+ /// 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 &);
+
+ /// doInitialization - Virtual method overridden by BasicBlockPass subclasses
+ /// to do any necessary per-function initialization.
+ ///
+ virtual bool doInitialization(Function &);
+
+ /// runOnBasicBlock - Virtual method overriden by subclasses to do the
+ /// per-basicblock processing of the pass.
+ ///
+ virtual bool runOnBasicBlock(BasicBlock &BB) = 0;
+
+ /// doFinalization - Virtual method overriden by BasicBlockPass subclasses to
+ /// do any post processing needed after all passes have run.
+ ///
+ 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);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const;
+};
+
+/// If the user specifies the -time-passes argument on an LLVM tool command line
+/// then the value of this boolean will be true, otherwise false.
+/// @brief This is the storage for the -time-passes option.
+extern bool TimePassesIsEnabled;
+
+} // End llvm namespace
+
+// Include support files that contain important APIs commonly used by Passes,
+// but that we want to separate out to make it easier to read the header files.
+//
+#include "llvm/PassSupport.h"
+#include "llvm/PassAnalysisSupport.h"
+
+#endif
diff --git a/contrib/llvm/include/llvm/PassAnalysisSupport.h b/contrib/llvm/include/llvm/PassAnalysisSupport.h
new file mode 100644
index 000000000000..5c6a2d7a92f9
--- /dev/null
+++ b/contrib/llvm/include/llvm/PassAnalysisSupport.h
@@ -0,0 +1,253 @@
+//===- llvm/PassAnalysisSupport.h - Analysis 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 stuff that is used to define and "use" Analysis Passes.
+// This file is automatically #included by Pass.h, so:
+//
+// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
+//
+// Instead, #include Pass.h
+//
+//===----------------------------------------------------------------------===//
+
+#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 <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// AnalysisUsage - Represent the analysis usage information of a pass. This
+// tracks analyses that the pass REQUIRES (must be available when the pass
+// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the
+// pass), and analyses that the pass PRESERVES (the pass does not invalidate the
+// results of these analyses). This information is provided by a pass to the
+// Pass infrastructure through the getAnalysisUsage virtual function.
+//
+class AnalysisUsage {
+public:
+ typedef SmallVector<AnalysisID, 32> VectorType;
+
+private:
+ // Sets of analyses required and preserved by a pass
+ VectorType Required, RequiredTransitive, Preserved;
+ bool PreservesAll;
+
+public:
+ AnalysisUsage() : PreservesAll(false) {}
+
+ // addRequired - Add the specified ID to the required set of the usage info
+ // for a pass.
+ //
+ AnalysisUsage &addRequiredID(const void *ID);
+ AnalysisUsage &addRequiredID(char &ID);
+ template<class PassClass>
+ AnalysisUsage &addRequired() {
+ return addRequiredID(PassClass::ID);
+ }
+
+ AnalysisUsage &addRequiredTransitiveID(char &ID);
+ template<class PassClass>
+ AnalysisUsage &addRequiredTransitive() {
+ return addRequiredTransitiveID(PassClass::ID);
+ }
+
+ // addPreserved - Add the specified ID to the set of analyses preserved by
+ // this pass
+ //
+ AnalysisUsage &addPreservedID(const void *ID) {
+ Preserved.push_back(ID);
+ return *this;
+ }
+ AnalysisUsage &addPreservedID(char &ID) {
+ Preserved.push_back(&ID);
+ return *this;
+ }
+
+ // addPreserved - Add the specified Pass class to the set of analyses
+ // preserved by this pass.
+ //
+ template<class PassClass>
+ AnalysisUsage &addPreserved() {
+ Preserved.push_back(&PassClass::ID);
+ return *this;
+ }
+
+ // addPreserved - Add the Pass with the specified argument string to the set
+ // of analyses preserved by this pass. If no such Pass exists, do nothing.
+ // This can be useful when a pass is trivially preserved, but may not be
+ // linked in. Be careful about spelling!
+ //
+ AnalysisUsage &addPreserved(StringRef Arg);
+
+ // setPreservesAll - Set by analyses that do not transform their input at all
+ void setPreservesAll() { PreservesAll = true; }
+ bool getPreservesAll() const { return PreservesAll; }
+
+ /// setPreservesCFG - This function should be called by the pass, iff they do
+ /// not:
+ ///
+ /// 1. Add or remove basic blocks from the function
+ /// 2. Modify terminator instructions in any way.
+ ///
+ /// This function annotates the AnalysisUsage info object to say that analyses
+ /// that only depend on the CFG are preserved by this pass.
+ ///
+ void setPreservesCFG();
+
+ const VectorType &getRequiredSet() const { return Required; }
+ const VectorType &getRequiredTransitiveSet() const {
+ return RequiredTransitive;
+ }
+ const VectorType &getPreservedSet() const { return Preserved; }
+};
+
+//===----------------------------------------------------------------------===//
+// AnalysisResolver - Simple interface used by Pass objects to pull all
+// analysis information out of pass manager that is responsible to manage
+// the pass.
+//
+class PMDataManager;
+class AnalysisResolver {
+private:
+ AnalysisResolver(); // DO NOT IMPLEMENT
+
+public:
+ explicit AnalysisResolver(PMDataManager &P) : PM(P) { }
+
+ inline PMDataManager &getPMDataManager() { return PM; }
+
+ // Find pass that is implementing PI.
+ Pass *findImplPass(AnalysisID PI) {
+ Pass *ResultPass = 0;
+ for (unsigned i = 0; i < AnalysisImpls.size() ; ++i) {
+ if (AnalysisImpls[i].first == PI) {
+ ResultPass = AnalysisImpls[i].second;
+ break;
+ }
+ }
+ return ResultPass;
+ }
+
+ // Find pass that is implementing PI. Initialize pass for Function F.
+ Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
+
+ void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
+ if (findImplPass(PI) == P)
+ return;
+ std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P);
+ AnalysisImpls.push_back(pir);
+ }
+
+ /// clearAnalysisImpls - Clear cache that is used to connect a pass to the
+ /// the analysis (PassInfo).
+ void clearAnalysisImpls() {
+ AnalysisImpls.clear();
+ }
+
+ // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist
+ Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const;
+
+private:
+ // AnalysisImpls - This keeps track of which passes implements the interfaces
+ // that are required by the current pass (to implement getAnalysis()).
+ std::vector<std::pair<AnalysisID, Pass*> > AnalysisImpls;
+
+ // PassManager that is used to resolve analysis info
+ PMDataManager &PM;
+};
+
+/// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+/// get analysis information that might be around, for example to update it.
+/// This is different than getAnalysis in that it can fail (if the analysis
+/// results haven't been computed), so should only be used if you can handle
+/// the case when the analysis is not available. This method is often used by
+/// transformation APIs to update analysis results for a pass automatically as
+/// the transform is performed.
+///
+template<typename AnalysisType>
+AnalysisType *Pass::getAnalysisIfAvailable() const {
+ assert(Resolver && "Pass not resident in a PassManager object!");
+
+ const void *PI = &AnalysisType::ID;
+
+ Pass *ResultPass = Resolver->getAnalysisIfAvailable(PI, true);
+ if (ResultPass == 0) return 0;
+
+ // Because the AnalysisType may not be a subclass of pass (for
+ // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+ // adjust the return pointer (because the class may multiply inherit, once
+ // from pass, once from AnalysisType).
+ return (AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
+}
+
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis() const {
+ assert(Resolver && "Pass has not been inserted into a PassManager object!");
+ return getAnalysisID<AnalysisType>(&AnalysisType::ID);
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
+ assert(PI && "getAnalysis for unregistered pass!");
+ assert(Resolver&&"Pass has not been inserted into a PassManager object!");
+ // PI *must* appear in AnalysisImpls. Because the number of passes used
+ // should be a small number, we just do a linear search over a (dense)
+ // vector.
+ Pass *ResultPass = Resolver->findImplPass(PI);
+ assert (ResultPass &&
+ "getAnalysis*() called on an analysis that was not "
+ "'required' by pass!");
+
+ // Because the AnalysisType may not be a subclass of pass (for
+ // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+ // adjust the return pointer (because the class may multiply inherit, once
+ // from pass, once from AnalysisType).
+ return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
+}
+
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis(Function &F) {
+ assert(Resolver &&"Pass has not been inserted into a PassManager object!");
+
+ return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) {
+ assert(PI && "getAnalysis for unregistered pass!");
+ assert(Resolver && "Pass has not been inserted into a PassManager object!");
+ // PI *must* appear in AnalysisImpls. Because the number of passes used
+ // should be a small number, we just do a linear search over a (dense)
+ // vector.
+ Pass *ResultPass = Resolver->findImplPass(this, PI, F);
+ assert(ResultPass && "Unable to find requested analysis info");
+
+ // Because the AnalysisType may not be a subclass of pass (for
+ // AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
+ // adjust the return pointer (because the class may multiply inherit, once
+ // from pass, once from AnalysisType).
+ return *(AnalysisType*)ResultPass->getAdjustedAnalysisPointer(PI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/PassManager.h b/contrib/llvm/include/llvm/PassManager.h
new file mode 100644
index 000000000000..ce5fda79f9c7
--- /dev/null
+++ b/contrib/llvm/include/llvm/PassManager.h
@@ -0,0 +1,103 @@
+//===- llvm/PassManager.h - Container for Passes ----------------*- 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 PassManager class. This class is used to hold,
+// maintain, and optimize execution of Passes. The PassManager class ensures
+// that analysis results are available before a pass runs, and that Pass's are
+// destroyed when the PassManager is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSMANAGER_H
+#define LLVM_PASSMANAGER_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class Pass;
+class Module;
+
+class PassManagerImpl;
+class FunctionPassManagerImpl;
+
+/// PassManagerBase - An abstract interface to allow code to add passes to
+/// a pass manager without having to hard-code what kind of pass manager
+/// it is.
+class PassManagerBase {
+public:
+ virtual ~PassManagerBase();
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ virtual void add(Pass *P) = 0;
+};
+
+/// PassManager manages ModulePassManagers
+class PassManager : public PassManagerBase {
+public:
+
+ PassManager();
+ ~PassManager();
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P);
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool run(Module &M);
+
+private:
+ /// PassManagerImpl_New is the actual class. PassManager is just the
+ /// wraper to publish simple pass manager interface
+ PassManagerImpl *PM;
+};
+
+/// FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
+class FunctionPassManager : public PassManagerBase {
+public:
+ /// FunctionPassManager ctor - This initializes the pass manager. It needs,
+ /// but does not take ownership of, the specified Module.
+ explicit FunctionPassManager(Module *M);
+ ~FunctionPassManager();
+
+ /// add - Add a pass to the queue of passes to run. This passes
+ /// ownership of the Pass to the PassManager. When the
+ /// PassManager_X is destroyed, the pass will be destroyed as well, so
+ /// there is no need to delete the pass.
+ /// This implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P);
+
+ /// run - Execute all of the passes scheduled for execution. Keep
+ /// track of whether any of the passes modifies the function, and if
+ /// so, return true.
+ ///
+ bool run(Function &F);
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Run all of the finalizers for the function passes.
+ ///
+ bool doFinalization();
+
+private:
+ FunctionPassManagerImpl *FPM;
+ Module *M;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/PassManagers.h b/contrib/llvm/include/llvm/PassManagers.h
new file mode 100644
index 000000000000..fa29f50ccf77
--- /dev/null
+++ b/contrib/llvm/include/llvm/PassManagers.h
@@ -0,0 +1,460 @@
+//===- llvm/PassManagers.h - Pass Infrastructure classes -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the LLVM Pass Manager infrastructure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSMANAGERS_H
+#define LLVM_PASSMANAGERS_H
+
+#include "llvm/Pass.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include <vector>
+#include <map>
+
+//===----------------------------------------------------------------------===//
+// Overview:
+// The Pass Manager Infrastructure manages passes. It's responsibilities are:
+//
+// o Manage optimization pass execution order
+// o Make required Analysis information available before pass P is run
+// o Release memory occupied by dead passes
+// o If Analysis information is dirtied by a pass then regenerate Analysis
+// information before it is consumed by another pass.
+//
+// Pass Manager Infrastructure uses multiple pass managers. They are
+// PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager.
+// This class hierarchy uses multiple inheritance but pass managers do not
+// derive from another pass manager.
+//
+// PassManager and FunctionPassManager are two top-level pass manager that
+// represents the external interface of this entire pass manager infrastucture.
+//
+// Important classes :
+//
+// [o] class PMTopLevelManager;
+//
+// Two top level managers, PassManager and FunctionPassManager, derive from
+// PMTopLevelManager. PMTopLevelManager manages information used by top level
+// managers such as last user info.
+//
+// [o] class PMDataManager;
+//
+// PMDataManager manages information, e.g. list of available analysis info,
+// used by a pass manager to manage execution order of passes. It also provides
+// a place to implement common pass manager APIs. All pass managers derive from
+// PMDataManager.
+//
+// [o] class BBPassManager : public FunctionPass, public PMDataManager;
+//
+// BBPassManager manages BasicBlockPasses.
+//
+// [o] class FunctionPassManager;
+//
+// This is a external interface used by JIT to manage FunctionPasses. This
+// interface relies on FunctionPassManagerImpl to do all the tasks.
+//
+// [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager,
+// public PMTopLevelManager;
+//
+// FunctionPassManagerImpl is a top level manager. It manages FPPassManagers
+//
+// [o] class FPPassManager : public ModulePass, public PMDataManager;
+//
+// FPPassManager manages FunctionPasses and BBPassManagers
+//
+// [o] class MPPassManager : public Pass, public PMDataManager;
+//
+// MPPassManager manages ModulePasses and FPPassManagers
+//
+// [o] class PassManager;
+//
+// This is a external interface used by various tools to manages passes. It
+// relies on PassManagerImpl to do all the tasks.
+//
+// [o] class PassManagerImpl : public Pass, public PMDataManager,
+// public PMTopLevelManager
+//
+// PassManagerImpl is a top level pass manager responsible for managing
+// MPPassManagers.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PrettyStackTrace.h"
+
+namespace llvm {
+ class Module;
+ class Pass;
+ class StringRef;
+ class Value;
+ class Timer;
+ class PMDataManager;
+
+// enums for debugging strings
+enum PassDebuggingString {
+ EXECUTION_MSG, // "Executing Pass '"
+ MODIFICATION_MSG, // "' Made Modification '"
+ FREEING_MSG, // " Freeing Pass '"
+ ON_BASICBLOCK_MSG, // "' on BasicBlock '" + PassName + "'...\n"
+ ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n"
+ ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n"
+ ON_REGION_MSG, // " 'on Region ...\n'"
+ ON_LOOP_MSG, // " 'on Loop ...\n'"
+ ON_CG_MSG // "' on Call Graph ...\n'"
+};
+
+/// PassManagerPrettyStackEntry - This is used to print informative information
+/// about what pass is running when/if a stack trace is generated.
+class PassManagerPrettyStackEntry : public PrettyStackTraceEntry {
+ Pass *P;
+ Value *V;
+ Module *M;
+public:
+ explicit PassManagerPrettyStackEntry(Pass *p)
+ : P(p), V(0), M(0) {} // When P is releaseMemory'd.
+ PassManagerPrettyStackEntry(Pass *p, Value &v)
+ : P(p), V(&v), M(0) {} // When P is run on V
+ PassManagerPrettyStackEntry(Pass *p, Module &m)
+ : P(p), V(0), M(&m) {} // When P is run on M
+
+ /// print - Emit information about this stack frame to OS.
+ virtual void print(raw_ostream &OS) const;
+};
+
+
+//===----------------------------------------------------------------------===//
+// PMStack
+//
+/// PMStack - This class implements a stack data structure of PMDataManager
+/// pointers.
+///
+/// Top level pass managers (see PassManager.cpp) maintain active Pass Managers
+/// using PMStack. Each Pass implements assignPassManager() to connect itself
+/// with appropriate manager. assignPassManager() walks PMStack to find
+/// suitable manager.
+class PMStack {
+public:
+ typedef std::vector<PMDataManager *>::const_reverse_iterator iterator;
+ iterator begin() const { return S.rbegin(); }
+ iterator end() const { return S.rend(); }
+
+ void pop();
+ PMDataManager *top() const { return S.back(); }
+ void push(PMDataManager *PM);
+ bool empty() const { return S.empty(); }
+
+ void dump() const;
+
+private:
+ std::vector<PMDataManager *> S;
+};
+
+
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager
+//
+/// PMTopLevelManager manages LastUser info and collects common APIs used by
+/// top level pass managers.
+class PMTopLevelManager {
+protected:
+ explicit PMTopLevelManager(PMDataManager *PMDM);
+
+ virtual unsigned getNumContainedManagers() const {
+ return (unsigned)PassManagers.size();
+ }
+
+ void initializeAllAnalysisInfo();
+
+private:
+ virtual PMDataManager *getAsPMDataManager() = 0;
+ virtual PassManagerType getTopLevelPassManagerType() = 0;
+
+public:
+ /// Schedule pass P for execution. Make sure that passes required by
+ /// P are run before P is run. Update analysis info maintained by
+ /// the manager. Remove dead passes. This is a recursive function.
+ void schedulePass(Pass *P);
+
+ /// Set pass P as the last user of the given analysis passes.
+ void setLastUser(const SmallVectorImpl<Pass *> &AnalysisPasses, Pass *P);
+
+ /// Collect passes whose last user is P
+ void collectLastUses(SmallVectorImpl<Pass *> &LastUses, Pass *P);
+
+ /// Find the pass that implements Analysis AID. Search immutable
+ /// passes and all pass managers. If desired pass is not found
+ /// then return NULL.
+ Pass *findAnalysisPass(AnalysisID AID);
+
+ /// Find analysis usage information for the pass P.
+ AnalysisUsage *findAnalysisUsage(Pass *P);
+
+ virtual ~PMTopLevelManager();
+
+ /// Add immutable pass and initialize it.
+ inline void addImmutablePass(ImmutablePass *P) {
+ P->initializePass();
+ ImmutablePasses.push_back(P);
+ }
+
+ inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() {
+ return ImmutablePasses;
+ }
+
+ void addPassManager(PMDataManager *Manager) {
+ PassManagers.push_back(Manager);
+ }
+
+ // Add Manager into the list of managers that are not directly
+ // maintained by this top level pass manager
+ inline void addIndirectPassManager(PMDataManager *Manager) {
+ IndirectPassManagers.push_back(Manager);
+ }
+
+ // Print passes managed by this top level manager.
+ void dumpPasses() const;
+ void dumpArguments() const;
+
+ // Active Pass Managers
+ PMStack activeStack;
+
+protected:
+
+ /// Collection of pass managers
+ SmallVector<PMDataManager *, 8> PassManagers;
+
+private:
+
+ /// Collection of pass managers that are not directly maintained
+ /// by this pass manager
+ SmallVector<PMDataManager *, 8> IndirectPassManagers;
+
+ // Map to keep track of last user of the analysis pass.
+ // LastUser->second is the last user of Lastuser->first.
+ DenseMap<Pass *, Pass *> LastUser;
+
+ // Map to keep track of passes that are last used by a pass.
+ // This inverse map is initialized at PM->run() based on
+ // LastUser map.
+ DenseMap<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser;
+
+ /// Immutable passes are managed by top level manager.
+ SmallVector<ImmutablePass *, 8> ImmutablePasses;
+
+ DenseMap<Pass *, AnalysisUsage *> AnUsageMap;
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// PMDataManager
+
+/// PMDataManager provides the common place to manage the analysis data
+/// used by pass managers.
+class PMDataManager {
+public:
+
+ explicit PMDataManager() : TPM(NULL), Depth(0) {
+ initializeAnalysisInfo();
+ }
+
+ virtual ~PMDataManager();
+
+ virtual Pass *getAsPass() = 0;
+
+ /// Augment AvailableAnalysis by adding analysis made available by pass P.
+ void recordAvailableAnalysis(Pass *P);
+
+ /// verifyPreservedAnalysis -- Verify analysis presreved by pass P.
+ void verifyPreservedAnalysis(Pass *P);
+
+ /// Remove Analysis that is not preserved by the pass
+ void removeNotPreservedAnalysis(Pass *P);
+
+ /// Remove dead passes used by P.
+ void removeDeadPasses(Pass *P, StringRef Msg,
+ enum PassDebuggingString);
+
+ /// Remove P.
+ void freePass(Pass *P, StringRef Msg,
+ enum PassDebuggingString);
+
+ /// Add pass P into the PassVector. Update
+ /// AvailableAnalysis appropriately if ProcessAnalysis is true.
+ void add(Pass *P, bool ProcessAnalysis = true);
+
+ /// Add RequiredPass into list of lower level passes required by pass P.
+ /// RequiredPass is run on the fly by Pass Manager when P requests it
+ /// through getAnalysis interface.
+ virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
+
+ virtual Pass *getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F);
+
+ /// Initialize available analysis information.
+ void initializeAnalysisInfo() {
+ AvailableAnalysis.clear();
+ for (unsigned i = 0; i < PMT_Last; ++i)
+ InheritedAnalysis[i] = NULL;
+ }
+
+ // Return true if P preserves high level analysis used by other
+ // passes that are managed by this manager.
+ bool preserveHigherLevelAnalysis(Pass *P);
+
+
+ /// Populate RequiredPasses with analysis pass that are required by
+ /// pass P and are available. Populate ReqPassNotAvailable with analysis
+ /// pass that are required by pass P but are not available.
+ void collectRequiredAnalysis(SmallVectorImpl<Pass *> &RequiredPasses,
+ SmallVectorImpl<AnalysisID> &ReqPassNotAvailable,
+ Pass *P);
+
+ /// All Required analyses should be available to the pass as it runs! Here
+ /// we fill in the AnalysisImpls member of the pass so that it can
+ /// successfully use the getAnalysis() method to retrieve the
+ /// implementations it needs.
+ void initializeAnalysisImpl(Pass *P);
+
+ /// Find the pass that implements Analysis AID. If desired pass is not found
+ /// then return NULL.
+ Pass *findAnalysisPass(AnalysisID AID, bool Direction);
+
+ // Access toplevel manager
+ PMTopLevelManager *getTopLevelManager() { return TPM; }
+ void setTopLevelManager(PMTopLevelManager *T) { TPM = T; }
+
+ unsigned getDepth() const { return Depth; }
+ void setDepth(unsigned newDepth) { Depth = newDepth; }
+
+ // Print routines used by debug-pass
+ void dumpLastUses(Pass *P, unsigned Offset) const;
+ void dumpPassArguments() const;
+ void dumpPassInfo(Pass *P, enum PassDebuggingString S1,
+ enum PassDebuggingString S2, StringRef Msg);
+ void dumpRequiredSet(const Pass *P) const;
+ void dumpPreservedSet(const Pass *P) const;
+
+ virtual unsigned getNumContainedPasses() const {
+ return (unsigned)PassVector.size();
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ assert ( 0 && "Invalid use of getPassManagerType");
+ return PMT_Unknown;
+ }
+
+ std::map<AnalysisID, Pass*> *getAvailableAnalysis() {
+ return &AvailableAnalysis;
+ }
+
+ // Collect AvailableAnalysis from all the active Pass Managers.
+ void populateInheritedAnalysis(PMStack &PMS) {
+ unsigned Index = 0;
+ for (PMStack::iterator I = PMS.begin(), E = PMS.end();
+ I != E; ++I)
+ InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis();
+ }
+
+protected:
+
+ // Top level manager.
+ PMTopLevelManager *TPM;
+
+ // Collection of pass that are managed by this manager
+ SmallVector<Pass *, 16> PassVector;
+
+ // Collection of Analysis provided by Parent pass manager and
+ // used by current pass manager. At at time there can not be more
+ // then PMT_Last active pass mangers.
+ std::map<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
+
+
+ /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
+ /// or higher is specified.
+ bool isPassDebuggingExecutionsOrMore() const;
+
+private:
+ void dumpAnalysisUsage(StringRef Msg, const Pass *P,
+ const AnalysisUsage::VectorType &Set) const;
+
+ // Set of available Analysis. This information is used while scheduling
+ // pass. If a pass requires an analysis which is not available then
+ // the required analysis pass is scheduled to run before the pass itself is
+ // scheduled to run.
+ std::map<AnalysisID, Pass*> AvailableAnalysis;
+
+ // Collection of higher level analysis used by the pass managed by
+ // this manager.
+ SmallVector<Pass *, 8> HigherLevelAnalysis;
+
+ unsigned Depth;
+};
+
+//===----------------------------------------------------------------------===//
+// FPPassManager
+//
+/// FPPassManager manages BBPassManagers and FunctionPasses.
+/// It batches all function passes and basic block pass managers together and
+/// sequence them to process one function at a time before processing next
+/// function.
+class FPPassManager : public ModulePass, public PMDataManager {
+public:
+ static char ID;
+ explicit FPPassManager()
+ : ModulePass(ID), PMDataManager() { }
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool runOnFunction(Function &F);
+ bool runOnModule(Module &M);
+
+ /// cleanup - After running all passes, clean up pass manager cache.
+ void cleanup();
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Run all of the finalizers for the function passes.
+ ///
+ bool doFinalization(Module &M);
+
+ virtual PMDataManager *getAsPMDataManager() { return this; }
+ virtual Pass *getAsPass() { return this; }
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.setPreservesAll();
+ }
+
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset);
+
+ virtual const char *getPassName() const {
+ return "Function Pass Manager";
+ }
+
+ FunctionPass *getContainedPass(unsigned N) {
+ assert ( N < PassVector.size() && "Pass number out of range!");
+ FunctionPass *FP = static_cast<FunctionPass *>(PassVector[N]);
+ return FP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_FunctionPassManager;
+ }
+};
+
+Timer *getPassTimer(Pass *);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/PassRegistry.h b/contrib/llvm/include/llvm/PassRegistry.h
new file mode 100644
index 000000000000..5d89c492218d
--- /dev/null
+++ b/contrib/llvm/include/llvm/PassRegistry.h
@@ -0,0 +1,84 @@
+//===- llvm/PassRegistry.h - Pass Information Registry ----------*- 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 PassRegistry, a class that is used in the initialization
+// and registration of passes. At application startup, passes are registered
+// with the PassRegistry, which is later provided to the PassManager for
+// dependency resolution and similar tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSREGISTRY_H
+#define LLVM_PASSREGISTRY_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+class PassInfo;
+struct PassRegistrationListener;
+
+/// PassRegistry - This class manages the registration and intitialization of
+/// the pass subsystem as application startup, and assists the PassManager
+/// in resolving pass dependencies.
+/// NOTE: PassRegistry is NOT thread-safe. If you want to use LLVM on multiple
+/// threads simultaneously, you will need to use a separate PassRegistry on
+/// each thread.
+class PassRegistry {
+ mutable void *pImpl;
+ void *getImpl() const;
+
+public:
+ PassRegistry() : pImpl(0) { }
+ ~PassRegistry();
+
+ /// getPassRegistry - Access the global registry object, which is
+ /// automatically initialized at application launch and destroyed by
+ /// llvm_shutdown.
+ static PassRegistry *getPassRegistry();
+
+ /// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
+ /// type identifier (&MyPass::ID).
+ const PassInfo *getPassInfo(const void *TI) const;
+
+ /// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
+ /// argument string.
+ const PassInfo *getPassInfo(StringRef Arg) const;
+
+ /// registerPass - Register a pass (by means of its PassInfo) with the
+ /// registry. Required in order to use the pass with a PassManager.
+ void registerPass(const PassInfo &PI, bool ShouldFree = false);
+
+ /// registerPass - Unregister a pass (by means of its PassInfo) with the
+ /// registry.
+ void unregisterPass(const PassInfo &PI);
+
+ /// registerAnalysisGroup - Register an analysis group (or a pass implementing
+ // an analysis group) with the registry. Like registerPass, this is required
+ // in order for a PassManager to be able to use this group/pass.
+ void registerAnalysisGroup(const void *InterfaceID, const void *PassID,
+ PassInfo& Registeree, bool isDefault,
+ bool ShouldFree = false);
+
+ /// enumerateWith - Enumerate the registered passes, calling the provided
+ /// PassRegistrationListener's passEnumerate() callback on each of them.
+ void enumerateWith(PassRegistrationListener *L);
+
+ /// addRegistrationListener - Register the given PassRegistrationListener
+ /// to receive passRegistered() callbacks whenever a new pass is registered.
+ void addRegistrationListener(PassRegistrationListener *L);
+
+ /// removeRegistrationListener - Unregister a PassRegistrationListener so that
+ /// it no longer receives passRegistered() callbacks.
+ void removeRegistrationListener(PassRegistrationListener *L);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/PassSupport.h b/contrib/llvm/include/llvm/PassSupport.h
new file mode 100644
index 000000000000..c50c2cc184e3
--- /dev/null
+++ b/contrib/llvm/include/llvm/PassSupport.h
@@ -0,0 +1,341 @@
+//===- llvm/PassSupport.h - 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 stuff that is used to define and "use" Passes. This file
+// is automatically #included by Pass.h, so:
+//
+// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
+//
+// Instead, #include Pass.h.
+//
+// This file defines Pass registration code and classes used for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASS_SUPPORT_H
+#define LLVM_PASS_SUPPORT_H
+
+#include "Pass.h"
+#include "llvm/PassRegistry.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Valgrind.h"
+#include <vector>
+
+namespace llvm {
+
+//===---------------------------------------------------------------------------
+/// PassInfo class - An instance of this class exists for every pass known by
+/// the system, and can be obtained from a live Pass by calling its
+/// getPassInfo() method. These objects are set up by the RegisterPass<>
+/// template, defined below.
+///
+class PassInfo {
+public:
+ typedef Pass* (*NormalCtor_t)();
+
+private:
+ const char *const PassName; // Nice name for Pass
+ const char *const PassArgument; // Command Line argument to run this pass
+ const void *PassID;
+ const bool IsCFGOnlyPass; // Pass only looks at the CFG.
+ const bool IsAnalysis; // True if an analysis pass.
+ const bool IsAnalysisGroup; // True if an analysis group.
+ std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
+
+ NormalCtor_t NormalCtor;
+
+public:
+ /// PassInfo ctor - Do not call this directly, this should only be invoked
+ /// through RegisterPass.
+ PassInfo(const char *name, const char *arg, const void *pi,
+ NormalCtor_t normal, bool isCFGOnly, bool is_analysis)
+ : PassName(name), PassArgument(arg), PassID(pi),
+ IsCFGOnlyPass(isCFGOnly),
+ IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) { }
+ /// PassInfo ctor - Do not call this directly, this should only be invoked
+ /// through RegisterPass. This version is for use by analysis groups; it
+ /// does not auto-register the pass.
+ PassInfo(const char *name, const void *pi)
+ : PassName(name), PassArgument(""), PassID(pi),
+ IsCFGOnlyPass(false),
+ IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0) { }
+
+ /// getPassName - Return the friendly name for the pass, never returns null
+ ///
+ const char *getPassName() const { return PassName; }
+
+ /// getPassArgument - Return the command line option that may be passed to
+ /// 'opt' that will cause this pass to be run. This will return null if there
+ /// is no argument.
+ ///
+ const char *getPassArgument() const { return PassArgument; }
+
+ /// getTypeInfo - Return the id object for the pass...
+ /// TODO : Rename
+ const void *getTypeInfo() const { return PassID; }
+
+ /// Return true if this PassID implements the specified ID pointer.
+ bool isPassID(const void *IDPtr) const {
+ return PassID == IDPtr;
+ }
+
+ /// isAnalysisGroup - Return true if this is an analysis group, not a normal
+ /// pass.
+ ///
+ bool isAnalysisGroup() const { return IsAnalysisGroup; }
+ bool isAnalysis() const { return IsAnalysis; }
+
+ /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
+ /// function.
+ bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
+
+ /// getNormalCtor - Return a pointer to a function, that when called, creates
+ /// an instance of the pass and returns it. This pointer may be null if there
+ /// is no default constructor for the pass.
+ ///
+ NormalCtor_t getNormalCtor() const {
+ return NormalCtor;
+ }
+ void setNormalCtor(NormalCtor_t Ctor) {
+ NormalCtor = Ctor;
+ }
+
+ /// createPass() - Use this method to create an instance of this pass.
+ Pass *createPass() const;
+
+ /// addInterfaceImplemented - This method is called when this pass is
+ /// registered as a member of an analysis group with the RegisterAnalysisGroup
+ /// template.
+ ///
+ void addInterfaceImplemented(const PassInfo *ItfPI) {
+ ItfImpl.push_back(ItfPI);
+ }
+
+ /// getInterfacesImplemented - Return a list of all of the analysis group
+ /// interfaces implemented by this pass.
+ ///
+ const std::vector<const PassInfo*> &getInterfacesImplemented() const {
+ return ItfImpl;
+ }
+
+private:
+ void operator=(const PassInfo &); // do not implement
+ PassInfo(const PassInfo &); // do not implement
+};
+
+#define CALL_ONCE_INITIALIZATION(function) \
+ static volatile sys::cas_flag initialized = 0; \
+ sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
+ if (old_val == 0) { \
+ function(Registry); \
+ sys::MemoryFence(); \
+ TsanIgnoreWritesBegin(); \
+ TsanHappensBefore(&initialized); \
+ initialized = 2; \
+ TsanIgnoreWritesEnd(); \
+ } else { \
+ sys::cas_flag tmp = initialized; \
+ sys::MemoryFence(); \
+ while (tmp != 2) { \
+ tmp = initialized; \
+ sys::MemoryFence(); \
+ } \
+ } \
+ TsanHappensAfter(&initialized);
+
+#define INITIALIZE_PASS(passName, arg, name, cfg, analysis) \
+ static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+ Registry.registerPass(*PI, true); \
+ return PI; \
+ } \
+ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+ }
+
+#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis) \
+ static void* initialize##passName##PassOnce(PassRegistry &Registry) {
+
+#define INITIALIZE_PASS_DEPENDENCY(depName) \
+ initialize##depName##Pass(Registry);
+#define INITIALIZE_AG_DEPENDENCY(depName) \
+ initialize##depName##AnalysisGroup(Registry);
+
+#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis) \
+ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+ Registry.registerPass(*PI, true); \
+ return PI; \
+ } \
+ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+ }
+
+template<typename PassName>
+Pass *callDefaultCtor() { return new PassName(); }
+
+//===---------------------------------------------------------------------------
+/// RegisterPass<t> template - This template class is used to notify the system
+/// that a Pass is available for use, and registers it into the internal
+/// database maintained by the PassManager. Unless this template is used, opt,
+/// for example will not be able to see the pass and attempts to create the pass
+/// will fail. This template is used in the follow manner (at global scope, in
+/// your .cpp file):
+///
+/// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
+///
+/// This statement will cause your pass to be created by calling the default
+/// constructor exposed by the pass. If you have a different constructor that
+/// must be called, create a global constructor function (which takes the
+/// arguments you need and returns a Pass*) and register your pass like this:
+///
+/// static RegisterPass<PassClassName> tmp("passopt", "My Name");
+///
+template<typename passName>
+struct RegisterPass : public PassInfo {
+
+ // Register Pass using default constructor...
+ RegisterPass(const char *PassArg, const char *Name, bool CFGOnly = false,
+ bool is_analysis = false)
+ : PassInfo(Name, PassArg, &passName::ID,
+ PassInfo::NormalCtor_t(callDefaultCtor<passName>),
+ CFGOnly, is_analysis) {
+ PassRegistry::getPassRegistry()->registerPass(*this);
+ }
+};
+
+
+/// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_.
+/// Analysis groups are used to define an interface (which need not derive from
+/// Pass) that is required by passes to do their job. Analysis Groups differ
+/// from normal analyses because any available implementation of the group will
+/// be used if it is available.
+///
+/// If no analysis implementing the interface is available, a default
+/// implementation is created and added. A pass registers itself as the default
+/// implementation by specifying 'true' as the second template argument of this
+/// class.
+///
+/// In addition to registering itself as an analysis group member, a pass must
+/// register itself normally as well. Passes may be members of multiple groups
+/// and may still be "required" specifically by name.
+///
+/// The actual interface may also be registered as well (by not specifying the
+/// second template argument). The interface should be registered to associate
+/// a nice name with the interface.
+///
+class RegisterAGBase : public PassInfo {
+public:
+ RegisterAGBase(const char *Name,
+ const void *InterfaceID,
+ const void *PassID = 0,
+ bool isDefault = false);
+};
+
+template<typename Interface, bool Default = false>
+struct RegisterAnalysisGroup : public RegisterAGBase {
+ explicit RegisterAnalysisGroup(PassInfo &RPB)
+ : RegisterAGBase(RPB.getPassName(),
+ &Interface::ID, RPB.getTypeInfo(),
+ Default) {
+ }
+
+ explicit RegisterAnalysisGroup(const char *Name)
+ : RegisterAGBase(Name, &Interface::ID) {
+ }
+};
+
+#define INITIALIZE_ANALYSIS_GROUP(agName, name, defaultPass) \
+ static void* initialize##agName##AnalysisGroupOnce(PassRegistry &Registry) { \
+ initialize##defaultPass##Pass(Registry); \
+ PassInfo *AI = new PassInfo(name, & agName :: ID); \
+ Registry.registerAnalysisGroup(& agName ::ID, 0, *AI, false, true); \
+ return AI; \
+ } \
+ void llvm::initialize##agName##AnalysisGroup(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##agName##AnalysisGroupOnce) \
+ }
+
+
+#define INITIALIZE_AG_PASS(passName, agName, arg, name, cfg, analysis, def) \
+ static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+ if (!def) initialize##agName##AnalysisGroup(Registry); \
+ PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
+ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+ Registry.registerPass(*PI, true); \
+ \
+ PassInfo *AI = new PassInfo(name, & agName :: ID); \
+ Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
+ *AI, def, true); \
+ return AI; \
+ } \
+ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+ }
+
+
+#define INITIALIZE_AG_PASS_BEGIN(passName, agName, arg, n, cfg, analysis, def) \
+ static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+ if (!def) initialize##agName##AnalysisGroup(Registry);
+
+#define INITIALIZE_AG_PASS_END(passName, agName, arg, n, cfg, analysis, def) \
+ PassInfo *PI = new PassInfo(n, arg, & passName ::ID, \
+ PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis); \
+ Registry.registerPass(*PI, true); \
+ \
+ PassInfo *AI = new PassInfo(n, & agName :: ID); \
+ Registry.registerAnalysisGroup(& agName ::ID, & passName ::ID, \
+ *AI, def, true); \
+ return AI; \
+ } \
+ void llvm::initialize##passName##Pass(PassRegistry &Registry) { \
+ CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
+ }
+
+//===---------------------------------------------------------------------------
+/// PassRegistrationListener class - This class is meant to be derived from by
+/// 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
+/// registers your object to receive callbacks indicating when passes are loaded
+/// and removed.
+///
+struct PassRegistrationListener {
+
+ /// PassRegistrationListener ctor - Add the current object to the list of
+ /// PassRegistrationListeners...
+ PassRegistrationListener();
+
+ /// dtor - Remove object from list of listeners...
+ ///
+ virtual ~PassRegistrationListener();
+
+ /// Callback functions - These functions are invoked whenever a pass is loaded
+ /// or removed from the current executable.
+ ///
+ virtual void passRegistered(const PassInfo *) {}
+
+ /// enumeratePasses - Iterate over the registered passes, calling the
+ /// passEnumerate callback on each PassInfo object.
+ ///
+ void enumeratePasses();
+
+ /// passEnumerate - Callback function invoked when someone calls
+ /// enumeratePasses on this PassRegistrationListener object.
+ ///
+ virtual void passEnumerate(const PassInfo *) {}
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/AIXDataTypesFix.h b/contrib/llvm/include/llvm/Support/AIXDataTypesFix.h
new file mode 100644
index 000000000000..a9a9147de294
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/AIXDataTypesFix.h
@@ -0,0 +1,25 @@
+//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file overrides default system-defined types and limits which cannot be
+// done in DataTypes.h.in because it is processed by autoheader first, which
+// comments out any #undef statement
+//
+//===----------------------------------------------------------------------===//
+
+// No include guards desired!
+
+#ifndef SUPPORT_DATATYPES_H
+#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
+#endif
+
+// GCC is strict about defining large constants: they must have LL modifier.
+// These will be defined properly at the end of DataTypes.h
+#undef INT64_MAX
+#undef INT64_MIN
diff --git a/contrib/llvm/include/llvm/Support/AlignOf.h b/contrib/llvm/include/llvm/Support/AlignOf.h
new file mode 100644
index 000000000000..cebfa7982d6d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/AlignOf.h
@@ -0,0 +1,60 @@
+//===--- AlignOf.h - Portable calculation of type alignment -----*- 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 AlignOf function that computes alignments for
+// arbitrary types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALIGNOF_H
+#define LLVM_SUPPORT_ALIGNOF_H
+
+namespace llvm {
+
+template <typename T>
+struct AlignmentCalcImpl {
+ char x;
+ T t;
+private:
+ AlignmentCalcImpl() {} // Never instantiate.
+};
+
+/// AlignOf - A templated class that contains an enum value representing
+/// the alignment of the template argument. For example,
+/// AlignOf<int>::Alignment represents the alignment of type "int". The
+/// alignment calculated is the minimum alignment, and not necessarily
+/// the "desired" alignment returned by GCC's __alignof__ (for example). Note
+/// that because the alignment is an enum value, it can be used as a
+/// compile-time constant (e.g., for template instantiation).
+template <typename T>
+struct AlignOf {
+ enum { Alignment =
+ static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T)) };
+
+ enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
+ enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
+ enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
+ enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
+
+ enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
+ 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
+/// of a type. This provides no extra functionality beyond the AlignOf
+/// class besides some cosmetic cleanliness. Example usage:
+/// alignOf<int>() returns the alignment of an int.
+template <typename T>
+static inline unsigned alignOf() { return AlignOf<T>::Alignment; }
+
+} // end namespace llvm
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Allocator.h b/contrib/llvm/include/llvm/Support/Allocator.h
new file mode 100644
index 000000000000..a2ad24ffead9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Allocator.h
@@ -0,0 +1,242 @@
+//===--- Allocator.h - Simple memory allocation abstraction -----*- 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 MallocAllocator and BumpPtrAllocator interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALLOCATOR_H
+#define LLVM_SUPPORT_ALLOCATOR_H
+
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/DataTypes.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <cstddef>
+
+namespace llvm {
+template <typename T> struct ReferenceAdder { typedef T& result; };
+template <typename T> struct ReferenceAdder<T&> { typedef T result; };
+
+class MallocAllocator {
+public:
+ MallocAllocator() {}
+ ~MallocAllocator() {}
+
+ void Reset() {}
+
+ void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
+
+ template <typename T>
+ T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); }
+
+ template <typename T>
+ T *Allocate(size_t Num) {
+ return static_cast<T*>(malloc(sizeof(T)*Num));
+ }
+
+ void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); }
+
+ void PrintStats() const {}
+};
+
+/// MemSlab - This structure lives at the beginning of every slab allocated by
+/// the bump allocator.
+class MemSlab {
+public:
+ size_t Size;
+ MemSlab *NextPtr;
+};
+
+/// SlabAllocator - This class can be used to parameterize the underlying
+/// allocation strategy for the bump allocator. In particular, this is used
+/// by the JIT to allocate contiguous swathes of executable memory. The
+/// interface uses MemSlab's instead of void *'s so that the allocator
+/// doesn't have to remember the size of the pointer it allocated.
+class SlabAllocator {
+public:
+ virtual ~SlabAllocator();
+ virtual MemSlab *Allocate(size_t Size) = 0;
+ virtual void Deallocate(MemSlab *Slab) = 0;
+};
+
+/// MallocSlabAllocator - The default slab allocator for the bump allocator
+/// is an adapter class for MallocAllocator that just forwards the method
+/// calls and translates the arguments.
+class MallocSlabAllocator : public SlabAllocator {
+ /// Allocator - The underlying allocator that we forward to.
+ ///
+ MallocAllocator Allocator;
+
+public:
+ MallocSlabAllocator() : Allocator() { }
+ virtual ~MallocSlabAllocator();
+ virtual MemSlab *Allocate(size_t Size);
+ virtual void Deallocate(MemSlab *Slab);
+};
+
+/// BumpPtrAllocator - This allocator is useful for containers that need
+/// very simple memory allocation strategies. In particular, this just keeps
+/// 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
+
+ /// SlabSize - Allocate data into slabs of this size unless we get an
+ /// allocation above SizeThreshold.
+ size_t SlabSize;
+
+ /// SizeThreshold - For any allocation larger than this threshold, we should
+ /// allocate a separate slab.
+ size_t SizeThreshold;
+
+ /// Allocator - The underlying allocator we use to get slabs of memory. This
+ /// defaults to MallocSlabAllocator, which wraps malloc, but it could be
+ /// changed to use a custom allocator.
+ SlabAllocator &Allocator;
+
+ /// CurSlab - The slab that we are currently allocating into.
+ ///
+ MemSlab *CurSlab;
+
+ /// CurPtr - The current pointer into the current slab. This points to the
+ /// next free byte in the slab.
+ char *CurPtr;
+
+ /// End - The end of the current slab.
+ ///
+ char *End;
+
+ /// BytesAllocated - This field tracks how many bytes we've allocated, so
+ /// that we can compute how much space was wasted.
+ size_t BytesAllocated;
+
+ /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should
+ /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and
+ /// AlignPtr(8, 4) == 8.
+ static char *AlignPtr(char *Ptr, size_t Alignment);
+
+ /// StartNewSlab - Allocate a new slab and move the bump pointers over into
+ /// the new slab. Modifies CurPtr and End.
+ void StartNewSlab();
+
+ /// DeallocateSlabs - Deallocate all memory slabs after and including this
+ /// one.
+ void DeallocateSlabs(MemSlab *Slab);
+
+ static MallocSlabAllocator DefaultSlabAllocator;
+
+ template<typename T> friend class SpecificBumpPtrAllocator;
+public:
+ BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
+ SlabAllocator &allocator = DefaultSlabAllocator);
+ ~BumpPtrAllocator();
+
+ /// Reset - Deallocate all but the current slab and reset the current pointer
+ /// to the beginning of it, freeing all memory allocated so far.
+ void Reset();
+
+ /// Allocate - Allocate space at the specified alignment.
+ ///
+ void *Allocate(size_t Size, size_t Alignment);
+
+ /// Allocate space, but do not construct, one object.
+ ///
+ template <typename T>
+ T *Allocate() {
+ return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
+ }
+
+ /// Allocate space for an array of objects. This does not construct the
+ /// objects though.
+ template <typename T>
+ T *Allocate(size_t Num) {
+ return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+ }
+
+ /// Allocate space for a specific count of elements and with a specified
+ /// alignment.
+ template <typename T>
+ T *Allocate(size_t Num, size_t Alignment) {
+ // Round EltSize up to the specified alignment.
+ size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment);
+ return static_cast<T*>(Allocate(Num * EltSize, Alignment));
+ }
+
+ void Deallocate(const void * /*Ptr*/) {}
+
+ unsigned GetNumSlabs() const;
+
+ void PrintStats() const;
+
+ /// Compute the total physical memory allocated by this allocator.
+ size_t getTotalMemory() const;
+};
+
+/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only
+/// elements of one type to be allocated. This allows calling the destructor
+/// in DestroyAll() and when the allocator is destroyed.
+template <typename T>
+class SpecificBumpPtrAllocator {
+ BumpPtrAllocator Allocator;
+public:
+ SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096,
+ SlabAllocator &allocator = BumpPtrAllocator::DefaultSlabAllocator)
+ : Allocator(size, threshold, allocator) {}
+
+ ~SpecificBumpPtrAllocator() {
+ DestroyAll();
+ }
+
+ /// Call the destructor of each allocated object and deallocate all but the
+ /// current slab and reset the current pointer to the beginning of it, freeing
+ /// all memory allocated so far.
+ void DestroyAll() {
+ MemSlab *Slab = Allocator.CurSlab;
+ while (Slab) {
+ char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr :
+ (char *)Slab + Slab->Size;
+ for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) {
+ Ptr = Allocator.AlignPtr(Ptr, alignOf<T>());
+ if (Ptr + sizeof(T) <= End)
+ reinterpret_cast<T*>(Ptr)->~T();
+ }
+ Slab = Slab->NextPtr;
+ }
+ Allocator.Reset();
+ }
+
+ /// Allocate space for a specific count of elements.
+ T *Allocate(size_t num = 1) {
+ return Allocator.Allocate<T>(num);
+ }
+};
+
+} // end namespace llvm
+
+inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
+ struct S {
+ char c;
+ union {
+ double D;
+ long double LD;
+ long long L;
+ void *P;
+ } x;
+ };
+ return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
+ offsetof(S, x)));
+}
+
+inline void operator delete(void *, llvm::BumpPtrAllocator &) {}
+
+#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/contrib/llvm/include/llvm/Support/Atomic.h b/contrib/llvm/include/llvm/Support/Atomic.h
new file mode 100644
index 000000000000..1a6c606aa5f6
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Atomic.h
@@ -0,0 +1,39 @@
+//===- llvm/Support/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys atomic operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ATOMIC_H
+#define LLVM_SYSTEM_ATOMIC_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ namespace sys {
+ void MemoryFence();
+
+#ifdef _MSC_VER
+ typedef long cas_flag;
+#else
+ typedef uint32_t cas_flag;
+#endif
+ cas_flag CompareAndSwap(volatile cas_flag* ptr,
+ cas_flag new_value,
+ cas_flag old_value);
+ cas_flag AtomicIncrement(volatile cas_flag* ptr);
+ cas_flag AtomicDecrement(volatile cas_flag* ptr);
+ cas_flag AtomicAdd(volatile cas_flag* ptr, cas_flag val);
+ cas_flag AtomicMul(volatile cas_flag* ptr, cas_flag val);
+ cas_flag AtomicDiv(volatile cas_flag* ptr, cas_flag val);
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/BlockFrequency.h b/contrib/llvm/include/llvm/Support/BlockFrequency.h
new file mode 100644
index 000000000000..839cf9371247
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BlockFrequency.h
@@ -0,0 +1,65 @@
+//===-------- BlockFrequency.h - Block Frequency 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 implements Block Frequency class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H
+#define LLVM_SUPPORT_BLOCKFREQUENCY_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class raw_ostream;
+class BranchProbability;
+
+// This class represents Block Frequency as a 64-bit value.
+class BlockFrequency {
+
+ uint64_t Frequency;
+ static const int64_t ENTRY_FREQ = 1024;
+
+public:
+ BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
+
+ static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
+ uint64_t getFrequency() const { return Frequency; }
+
+ BlockFrequency &operator*=(const BranchProbability &Prob);
+ const BlockFrequency operator*(const BranchProbability &Prob) const;
+
+ BlockFrequency &operator+=(const BlockFrequency &Freq);
+ const BlockFrequency operator+(const BlockFrequency &Freq) const;
+
+ bool operator<(const BlockFrequency &RHS) const {
+ return Frequency < RHS.Frequency;
+ }
+
+ bool operator<=(const BlockFrequency &RHS) const {
+ return Frequency <= RHS.Frequency;
+ }
+
+ bool operator>(const BlockFrequency &RHS) const {
+ return Frequency > RHS.Frequency;
+ }
+
+ bool operator>=(const BlockFrequency &RHS) const {
+ return Frequency >= RHS.Frequency;
+ }
+
+ void print(raw_ostream &OS) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/BranchProbability.h b/contrib/llvm/include/llvm/Support/BranchProbability.h
new file mode 100644
index 000000000000..eedf69247ef5
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/BranchProbability.h
@@ -0,0 +1,77 @@
+//===- BranchProbability.h - Branch Probability Wrapper ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Definition of BranchProbability shared by IR and Machine Instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BRANCHPROBABILITY_H
+#define LLVM_SUPPORT_BRANCHPROBABILITY_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+class raw_ostream;
+
+// This class represents Branch Probability as a non-negative fraction.
+class BranchProbability {
+ // Numerator
+ uint32_t N;
+
+ // Denominator
+ uint32_t D;
+
+public:
+ BranchProbability(uint32_t n, uint32_t d) : N(n), D(d) {
+ assert(d > 0 && "Denomiator cannot be 0!");
+ assert(n <= d && "Probability cannot be bigger than 1!");
+ }
+
+ static BranchProbability getZero() { return BranchProbability(0, 1); }
+ static BranchProbability getOne() { return BranchProbability(1, 1); }
+
+ uint32_t getNumerator() const { return N; }
+ uint32_t getDenominator() const { return D; }
+
+ // Return (1 - Probability).
+ BranchProbability getCompl() const {
+ return BranchProbability(D - N, D);
+ }
+
+ void print(raw_ostream &OS) const;
+
+ void dump() const;
+
+ bool operator==(BranchProbability RHS) const {
+ return (uint64_t)N * RHS.D == (uint64_t)D * RHS.N;
+ }
+ bool operator!=(BranchProbability RHS) const {
+ return !(*this == RHS);
+ }
+ bool operator<(BranchProbability RHS) const {
+ return (uint64_t)N * RHS.D < (uint64_t)D * RHS.N;
+ }
+ bool operator>(BranchProbability RHS) const {
+ return RHS < *this;
+ }
+ bool operator<=(BranchProbability RHS) const {
+ return (uint64_t)N * RHS.D <= (uint64_t)D * RHS.N;
+ }
+ bool operator>=(BranchProbability RHS) const {
+ return RHS <= *this;
+ }
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/CFG.h b/contrib/llvm/include/llvm/Support/CFG.h
new file mode 100644
index 000000000000..f5dc8ea055a3
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/CFG.h
@@ -0,0 +1,357 @@
+//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- 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 specializations of GraphTraits that allow Function and
+// BasicBlock graphs to be treated as proper graphs for generic algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CFG_H
+#define LLVM_SUPPORT_CFG_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// BasicBlock pred_iterator definition
+//===----------------------------------------------------------------------===//
+
+template <class Ptr, class USE_iterator> // Predecessor Iterator
+class PredIterator : public std::iterator<std::forward_iterator_tag,
+ Ptr, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super;
+ typedef PredIterator<Ptr, USE_iterator> Self;
+ USE_iterator It;
+
+ inline void advancePastNonTerminators() {
+ // Loop to ignore non terminator uses (for example BlockAddresses).
+ while (!It.atEnd() && !isa<TerminatorInst>(*It))
+ ++It;
+ }
+
+public:
+ typedef typename super::pointer pointer;
+
+ PredIterator() {}
+ explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
+ advancePastNonTerminators();
+ }
+ inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {}
+
+ inline bool operator==(const Self& x) const { return It == x.It; }
+ inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ assert(!It.atEnd() && "pred_iterator out of range!");
+ return cast<TerminatorInst>(*It)->getParent();
+ }
+ inline pointer *operator->() const { return &operator*(); }
+
+ inline Self& operator++() { // Preincrement
+ assert(!It.atEnd() && "pred_iterator out of range!");
+ ++It; advancePastNonTerminators();
+ return *this;
+ }
+
+ inline Self operator++(int) { // Postincrement
+ Self tmp = *this; ++*this; return tmp;
+ }
+
+ /// getOperandNo - Return the operand number in the predecessor's
+ /// terminator of the successor.
+ unsigned getOperandNo() const {
+ return It.getOperandNo();
+ }
+
+ /// getUse - Return the operand Use in the predecessor's terminator
+ /// of the successor.
+ Use &getUse() const {
+ return It.getUse();
+ }
+};
+
+typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
+typedef PredIterator<const BasicBlock,
+ Value::const_use_iterator> const_pred_iterator;
+
+inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
+inline const_pred_iterator pred_begin(const BasicBlock *BB) {
+ return const_pred_iterator(BB);
+}
+inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
+inline const_pred_iterator pred_end(const BasicBlock *BB) {
+ return const_pred_iterator(BB, true);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// BasicBlock succ_iterator definition
+//===----------------------------------------------------------------------===//
+
+template <class Term_, class BB_> // Successor Iterator
+class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
+ BB_, ptrdiff_t> {
+ const Term_ Term;
+ unsigned idx;
+ typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super;
+ typedef SuccIterator<Term_, BB_> Self;
+
+ inline bool index_is_valid(int idx) {
+ return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
+ }
+
+public:
+ typedef typename super::pointer pointer;
+ // TODO: This can be random access iterator, only operator[] missing.
+
+ explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
+ }
+ inline SuccIterator(Term_ T, bool) // end iterator
+ : Term(T) {
+ if (Term)
+ idx = Term->getNumSuccessors();
+ else
+ // Term == NULL happens, if a basic block is not fully constructed and
+ // consequently getTerminator() returns NULL. In this case we construct a
+ // SuccIterator which describes a basic block that has zero successors.
+ // Defining SuccIterator for incomplete and malformed CFGs is especially
+ // useful for debugging.
+ idx = 0;
+ }
+
+ inline const Self &operator=(const Self &I) {
+ assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
+ idx = I.idx;
+ return *this;
+ }
+
+ /// getSuccessorIndex - This is used to interface between code that wants to
+ /// operate on terminator instructions directly.
+ unsigned getSuccessorIndex() const { return idx; }
+
+ inline bool operator==(const Self& x) const { return idx == x.idx; }
+ inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const { return Term->getSuccessor(idx); }
+ inline pointer operator->() const { return operator*(); }
+
+ inline Self& operator++() { ++idx; return *this; } // Preincrement
+
+ inline Self operator++(int) { // Postincrement
+ Self tmp = *this; ++*this; return tmp;
+ }
+
+ inline Self& operator--() { --idx; return *this; } // Predecrement
+ inline Self operator--(int) { // Postdecrement
+ Self tmp = *this; --*this; return tmp;
+ }
+
+ inline bool operator<(const Self& x) const {
+ assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+ return idx < x.idx;
+ }
+
+ inline bool operator<=(const Self& x) const {
+ assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+ return idx <= x.idx;
+ }
+ inline bool operator>=(const Self& x) const {
+ assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+ return idx >= x.idx;
+ }
+
+ inline bool operator>(const Self& x) const {
+ assert(Term == x.Term && "Cannot compare iterators of different blocks!");
+ return idx > x.idx;
+ }
+
+ inline Self& operator+=(int Right) {
+ unsigned new_idx = idx + Right;
+ assert(index_is_valid(new_idx) && "Iterator index out of bound");
+ idx = new_idx;
+ return *this;
+ }
+
+ inline Self operator+(int Right) {
+ Self tmp = *this;
+ tmp += Right;
+ return tmp;
+ }
+
+ inline Self& operator-=(int Right) {
+ return operator+=(-Right);
+ }
+
+ inline Self operator-(int Right) {
+ return operator+(-Right);
+ }
+
+ inline int operator-(const Self& x) {
+ assert(Term == x.Term && "Cannot work on iterators of different blocks!");
+ int distance = idx - x.idx;
+ return distance;
+ }
+
+ // This works for read access, however write access is difficult as changes
+ // to Term are only possible with Term->setSuccessor(idx). Pointers that can
+ // be modified are not available.
+ //
+ // inline pointer operator[](int offset) {
+ // Self tmp = *this;
+ // tmp += offset;
+ // return tmp.operator*();
+ // }
+
+ /// Get the source BB of this iterator.
+ inline BB_ *getSource() {
+ assert(Term && "Source not available, if basic block was malformed");
+ return Term->getParent();
+ }
+};
+
+typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
+typedef SuccIterator<const TerminatorInst*,
+ const BasicBlock> succ_const_iterator;
+
+inline succ_iterator succ_begin(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator());
+}
+inline succ_const_iterator succ_begin(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator());
+}
+inline succ_iterator succ_end(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator(), true);
+}
+inline succ_const_iterator succ_end(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator(), true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks...
+
+template <> struct GraphTraits<BasicBlock*> {
+ typedef BasicBlock NodeType;
+ typedef succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+template <> struct GraphTraits<const BasicBlock*> {
+ typedef const BasicBlock NodeType;
+ typedef succ_const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<BasicBlock*> > {
+ typedef BasicBlock NodeType;
+ typedef pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+template <> struct GraphTraits<Inverse<const BasicBlock*> > {
+ typedef const BasicBlock NodeType;
+ typedef const_pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... these are the same as the basic block iterators,
+// except that the root node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
+ static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef Function::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
+ static nodes_iterator nodes_end (Function *F) { return F->end(); }
+ static unsigned size (Function *F) { return F->size(); }
+};
+template <> struct GraphTraits<const Function*> :
+ public GraphTraits<const BasicBlock*> {
+ static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef Function::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
+ static nodes_iterator nodes_end (const Function *F) { return F->end(); }
+ static unsigned size (const Function *F) { return F->size(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<Function*> > :
+ public GraphTraits<Inverse<BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<Function*> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+template <> struct GraphTraits<Inverse<const Function*> > :
+ public GraphTraits<Inverse<const BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const Function *> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/COFF.h b/contrib/llvm/include/llvm/Support/COFF.h
new file mode 100644
index 000000000000..88c60bac7402
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/COFF.h
@@ -0,0 +1,586 @@
+//===-- llvm/Support/COFF.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 definitions used in Windows COFF Files.
+//
+// Structures and enums defined within this file where created using
+// information from Microsoft's publicly available PE/COFF format document:
+//
+// Microsoft Portable Executable and Common Object File Format Specification
+// Revision 8.1 - February 15, 2008
+//
+// As of 5/2/2010, hosted by Microsoft at:
+// http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WIN_COFF_H
+#define LLVM_SUPPORT_WIN_COFF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+namespace COFF {
+
+ // Sizes in bytes of various things in the COFF format.
+ enum {
+ HeaderSize = 20,
+ NameSize = 8,
+ SymbolSize = 18,
+ SectionSize = 40,
+ RelocationSize = 10
+ };
+
+ struct header {
+ uint16_t Machine;
+ uint16_t NumberOfSections;
+ uint32_t TimeDateStamp;
+ uint32_t PointerToSymbolTable;
+ uint32_t NumberOfSymbols;
+ uint16_t SizeOfOptionalHeader;
+ uint16_t Characteristics;
+ };
+
+ enum MachineTypes {
+ IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
+ IMAGE_FILE_MACHINE_AM33 = 0x13,
+ IMAGE_FILE_MACHINE_AMD64 = 0x8664,
+ IMAGE_FILE_MACHINE_ARM = 0x1C0,
+ IMAGE_FILE_MACHINE_ARMV7 = 0x1C4,
+ IMAGE_FILE_MACHINE_EBC = 0xEBC,
+ IMAGE_FILE_MACHINE_I386 = 0x14C,
+ IMAGE_FILE_MACHINE_IA64 = 0x200,
+ IMAGE_FILE_MACHINE_M32R = 0x9041,
+ IMAGE_FILE_MACHINE_MIPS16 = 0x266,
+ IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
+ IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
+ IMAGE_FILE_MACHINE_POWERPC = 0x1F0,
+ IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1,
+ IMAGE_FILE_MACHINE_R4000 = 0x166,
+ IMAGE_FILE_MACHINE_SH3 = 0x1A2,
+ IMAGE_FILE_MACHINE_SH3DSP = 0x1A3,
+ IMAGE_FILE_MACHINE_SH4 = 0x1A6,
+ IMAGE_FILE_MACHINE_SH5 = 0x1A8,
+ IMAGE_FILE_MACHINE_THUMB = 0x1C2,
+ IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
+ };
+
+ enum Characteristics {
+ /// The file does not contain base relocations and must be loaded at its
+ /// preferred base. If this cannot be done, the loader will error.
+ IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
+ /// The file is valid and can be run.
+ IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
+ /// COFF line numbers have been stripped. This is deprecated and should be
+ /// 0.
+ IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
+ /// COFF symbol table entries for local symbols have been removed. This is
+ /// deprecated and should be 0.
+ IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
+ /// Aggressively trim working set. This is deprecated and must be 0.
+ IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010,
+ /// Image can handle > 2GiB addresses.
+ IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
+ /// Little endian: the LSB precedes the MSB in memory. This is deprecated
+ /// and should be 0.
+ IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
+ /// Machine is based on a 32bit word architecture.
+ IMAGE_FILE_32BIT_MACHINE = 0x0100,
+ /// Debugging info has been removed.
+ IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
+ /// If the image is on removable media, fully load it and copy it to swap.
+ IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
+ /// If the image is on network media, fully load it and copy it to swap.
+ IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
+ /// The image file is a system file, not a user program.
+ IMAGE_FILE_SYSTEM = 0x1000,
+ /// The image file is a DLL.
+ IMAGE_FILE_DLL = 0x2000,
+ /// This file should only be run on a uniprocessor machine.
+ IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
+ /// Big endian: the MSB precedes the LSB in memory. This is deprecated
+ /// and should be 0.
+ IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
+ };
+
+ struct symbol {
+ char Name[NameSize];
+ uint32_t Value;
+ uint16_t Type;
+ uint8_t StorageClass;
+ uint16_t SectionNumber;
+ uint8_t NumberOfAuxSymbols;
+ };
+
+ enum SymbolFlags {
+ SF_TypeMask = 0x0000FFFF,
+ SF_TypeShift = 0,
+
+ SF_ClassMask = 0x00FF0000,
+ SF_ClassShift = 16,
+
+ SF_WeakExternal = 0x01000000
+ };
+
+ enum SymbolSectionNumber {
+ IMAGE_SYM_DEBUG = -2,
+ IMAGE_SYM_ABSOLUTE = -1,
+ IMAGE_SYM_UNDEFINED = 0
+ };
+
+ /// Storage class tells where and what the symbol represents
+ enum SymbolStorageClass {
+ IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
+ IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
+ IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
+ IMAGE_SYM_CLASS_EXTERNAL = 2, ///< External symbol
+ IMAGE_SYM_CLASS_STATIC = 3, ///< Static
+ IMAGE_SYM_CLASS_REGISTER = 4, ///< Register variable
+ IMAGE_SYM_CLASS_EXTERNAL_DEF = 5, ///< External definition
+ IMAGE_SYM_CLASS_LABEL = 6, ///< Label
+ IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7, ///< Undefined label
+ IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8, ///< Member of structure
+ IMAGE_SYM_CLASS_ARGUMENT = 9, ///< Function argument
+ IMAGE_SYM_CLASS_STRUCT_TAG = 10, ///< Structure tag
+ IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11, ///< Member of union
+ IMAGE_SYM_CLASS_UNION_TAG = 12, ///< Union tag
+ IMAGE_SYM_CLASS_TYPE_DEFINITION = 13, ///< Type definition
+ IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14, ///< Undefined static
+ IMAGE_SYM_CLASS_ENUM_TAG = 15, ///< Enumeration tag
+ IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16, ///< Member of enumeration
+ IMAGE_SYM_CLASS_REGISTER_PARAM = 17, ///< Register parameter
+ IMAGE_SYM_CLASS_BIT_FIELD = 18, ///< Bit field
+ /// ".bb" or ".eb" - beginning or end of block
+ IMAGE_SYM_CLASS_BLOCK = 100,
+ /// ".bf" or ".ef" - beginning or end of function
+ IMAGE_SYM_CLASS_FUNCTION = 101,
+ IMAGE_SYM_CLASS_END_OF_STRUCT = 102, ///< End of structure
+ IMAGE_SYM_CLASS_FILE = 103, ///< File name
+ /// Line number, reformatted as symbol
+ IMAGE_SYM_CLASS_SECTION = 104,
+ IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105, ///< Duplicate tag
+ /// External symbol in dmert public lib
+ IMAGE_SYM_CLASS_CLR_TOKEN = 107
+ };
+
+ enum SymbolBaseType {
+ IMAGE_SYM_TYPE_NULL = 0, ///< No type information or unknown base type.
+ IMAGE_SYM_TYPE_VOID = 1, ///< Used with void pointers and functions.
+ IMAGE_SYM_TYPE_CHAR = 2, ///< A character (signed byte).
+ IMAGE_SYM_TYPE_SHORT = 3, ///< A 2-byte signed integer.
+ IMAGE_SYM_TYPE_INT = 4, ///< A natural integer type on the target.
+ IMAGE_SYM_TYPE_LONG = 5, ///< A 4-byte signed integer.
+ IMAGE_SYM_TYPE_FLOAT = 6, ///< A 4-byte floating-point number.
+ IMAGE_SYM_TYPE_DOUBLE = 7, ///< An 8-byte floating-point number.
+ IMAGE_SYM_TYPE_STRUCT = 8, ///< A structure.
+ IMAGE_SYM_TYPE_UNION = 9, ///< An union.
+ IMAGE_SYM_TYPE_ENUM = 10, ///< An enumerated type.
+ IMAGE_SYM_TYPE_MOE = 11, ///< A member of enumeration (a specific value).
+ IMAGE_SYM_TYPE_BYTE = 12, ///< A byte; unsigned 1-byte integer.
+ IMAGE_SYM_TYPE_WORD = 13, ///< A word; unsigned 2-byte integer.
+ IMAGE_SYM_TYPE_UINT = 14, ///< An unsigned integer of natural size.
+ IMAGE_SYM_TYPE_DWORD = 15 ///< An unsigned 4-byte integer.
+ };
+
+ enum SymbolComplexType {
+ IMAGE_SYM_DTYPE_NULL = 0, ///< No complex type; simple scalar variable.
+ IMAGE_SYM_DTYPE_POINTER = 1, ///< A pointer to base type.
+ IMAGE_SYM_DTYPE_FUNCTION = 2, ///< A function that returns a base type.
+ IMAGE_SYM_DTYPE_ARRAY = 3, ///< An array of base type.
+
+ /// Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
+ SCT_COMPLEX_TYPE_SHIFT = 4
+ };
+
+ struct section {
+ char Name[NameSize];
+ uint32_t VirtualSize;
+ uint32_t VirtualAddress;
+ uint32_t SizeOfRawData;
+ uint32_t PointerToRawData;
+ uint32_t PointerToRelocations;
+ uint32_t PointerToLineNumbers;
+ uint16_t NumberOfRelocations;
+ uint16_t NumberOfLineNumbers;
+ uint32_t Characteristics;
+ };
+
+ enum SectionCharacteristics {
+ IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
+ IMAGE_SCN_CNT_CODE = 0x00000020,
+ IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
+ IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
+ IMAGE_SCN_LNK_OTHER = 0x00000100,
+ IMAGE_SCN_LNK_INFO = 0x00000200,
+ IMAGE_SCN_LNK_REMOVE = 0x00000800,
+ IMAGE_SCN_LNK_COMDAT = 0x00001000,
+ IMAGE_SCN_GPREL = 0x00008000,
+ IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
+ IMAGE_SCN_MEM_16BIT = 0x00020000,
+ IMAGE_SCN_MEM_LOCKED = 0x00040000,
+ IMAGE_SCN_MEM_PRELOAD = 0x00080000,
+ IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
+ IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
+ IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
+ IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
+ IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
+ IMAGE_SCN_ALIGN_32BYTES = 0x00600000,
+ IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
+ IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
+ IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
+ IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
+ IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
+ IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
+ IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
+ IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
+ IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
+ IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
+ IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
+ IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
+ IMAGE_SCN_MEM_SHARED = 0x10000000,
+ IMAGE_SCN_MEM_EXECUTE = 0x20000000,
+ IMAGE_SCN_MEM_READ = 0x40000000,
+ IMAGE_SCN_MEM_WRITE = 0x80000000
+ };
+
+ struct relocation {
+ uint32_t VirtualAddress;
+ uint32_t SymbolTableIndex;
+ uint16_t Type;
+ };
+
+ enum RelocationTypeX86 {
+ IMAGE_REL_I386_ABSOLUTE = 0x0000,
+ IMAGE_REL_I386_DIR16 = 0x0001,
+ IMAGE_REL_I386_REL16 = 0x0002,
+ IMAGE_REL_I386_DIR32 = 0x0006,
+ IMAGE_REL_I386_DIR32NB = 0x0007,
+ IMAGE_REL_I386_SEG12 = 0x0009,
+ IMAGE_REL_I386_SECTION = 0x000A,
+ IMAGE_REL_I386_SECREL = 0x000B,
+ IMAGE_REL_I386_TOKEN = 0x000C,
+ IMAGE_REL_I386_SECREL7 = 0x000D,
+ IMAGE_REL_I386_REL32 = 0x0014,
+
+ IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
+ IMAGE_REL_AMD64_ADDR64 = 0x0001,
+ IMAGE_REL_AMD64_ADDR32 = 0x0002,
+ IMAGE_REL_AMD64_ADDR32NB = 0x0003,
+ IMAGE_REL_AMD64_REL32 = 0x0004,
+ IMAGE_REL_AMD64_REL32_1 = 0x0005,
+ IMAGE_REL_AMD64_REL32_2 = 0x0006,
+ IMAGE_REL_AMD64_REL32_3 = 0x0007,
+ IMAGE_REL_AMD64_REL32_4 = 0x0008,
+ IMAGE_REL_AMD64_REL32_5 = 0x0009,
+ IMAGE_REL_AMD64_SECTION = 0x000A,
+ IMAGE_REL_AMD64_SECREL = 0x000B,
+ IMAGE_REL_AMD64_SECREL7 = 0x000C,
+ IMAGE_REL_AMD64_TOKEN = 0x000D,
+ IMAGE_REL_AMD64_SREL32 = 0x000E,
+ IMAGE_REL_AMD64_PAIR = 0x000F,
+ IMAGE_REL_AMD64_SSPAN32 = 0x0010
+ };
+
+ enum RelocationTypesARM {
+ IMAGE_REL_ARM_ABSOLUTE = 0x0000,
+ IMAGE_REL_ARM_ADDR32 = 0x0001,
+ IMAGE_REL_ARM_ADDR32NB = 0x0002,
+ IMAGE_REL_ARM_BRANCH24 = 0x0003,
+ IMAGE_REL_ARM_BRANCH11 = 0x0004,
+ IMAGE_REL_ARM_TOKEN = 0x0005,
+ IMAGE_REL_ARM_BLX24 = 0x0008,
+ IMAGE_REL_ARM_BLX11 = 0x0009,
+ IMAGE_REL_ARM_SECTION = 0x000E,
+ IMAGE_REL_ARM_SECREL = 0x000F,
+ IMAGE_REL_ARM_MOV32A = 0x0010,
+ IMAGE_REL_ARM_MOV32T = 0x0011,
+ IMAGE_REL_ARM_BRANCH20T = 0x0012,
+ IMAGE_REL_ARM_BRANCH24T = 0x0014,
+ IMAGE_REL_ARM_BLX23T = 0x0015
+ };
+
+ enum COMDATType {
+ IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
+ IMAGE_COMDAT_SELECT_ANY,
+ IMAGE_COMDAT_SELECT_SAME_SIZE,
+ IMAGE_COMDAT_SELECT_EXACT_MATCH,
+ IMAGE_COMDAT_SELECT_ASSOCIATIVE,
+ IMAGE_COMDAT_SELECT_LARGEST
+ };
+
+ // Auxiliary Symbol Formats
+ struct AuxiliaryFunctionDefinition {
+ uint32_t TagIndex;
+ uint32_t TotalSize;
+ uint32_t PointerToLinenumber;
+ uint32_t PointerToNextFunction;
+ uint8_t unused[2];
+ };
+
+ struct AuxiliarybfAndefSymbol {
+ uint8_t unused1[4];
+ uint16_t Linenumber;
+ uint8_t unused2[6];
+ uint32_t PointerToNextFunction;
+ uint8_t unused3[2];
+ };
+
+ struct AuxiliaryWeakExternal {
+ uint32_t TagIndex;
+ uint32_t Characteristics;
+ uint8_t unused[10];
+ };
+
+ /// These are not documented in the spec, but are located in WinNT.h.
+ enum WeakExternalCharacteristics {
+ IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1,
+ IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2,
+ IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3
+ };
+
+ struct AuxiliaryFile {
+ uint8_t FileName[18];
+ };
+
+ struct AuxiliarySectionDefinition {
+ uint32_t Length;
+ uint16_t NumberOfRelocations;
+ uint16_t NumberOfLinenumbers;
+ uint32_t CheckSum;
+ uint16_t Number;
+ uint8_t Selection;
+ uint8_t unused[3];
+ };
+
+ union Auxiliary {
+ AuxiliaryFunctionDefinition FunctionDefinition;
+ AuxiliarybfAndefSymbol bfAndefSymbol;
+ AuxiliaryWeakExternal WeakExternal;
+ AuxiliaryFile File;
+ AuxiliarySectionDefinition SectionDefinition;
+ };
+
+ /// @brief The Import Directory Table.
+ ///
+ /// There is a single array of these and one entry per imported DLL.
+ struct ImportDirectoryTableEntry {
+ uint32_t ImportLookupTableRVA;
+ uint32_t TimeDateStamp;
+ uint32_t ForwarderChain;
+ uint32_t NameRVA;
+ uint32_t ImportAddressTableRVA;
+ };
+
+ /// @brief The PE32 Import Lookup Table.
+ ///
+ /// There is an array of these for each imported DLL. It represents either
+ /// the ordinal to import from the target DLL, or a name to lookup and import
+ /// from the target DLL.
+ ///
+ /// This also happens to be the same format used by the Import Address Table
+ /// when it is initially written out to the image.
+ struct ImportLookupTableEntry32 {
+ uint32_t data;
+
+ /// @brief Is this entry specified by ordinal, or name?
+ bool isOrdinal() const { return data & 0x80000000; }
+
+ /// @brief Get the ordinal value of this entry. isOrdinal must be true.
+ uint16_t getOrdinal() const {
+ assert(isOrdinal() && "ILT entry is not an ordinal!");
+ return data & 0xFFFF;
+ }
+
+ /// @brief Set the ordinal value and set isOrdinal to true.
+ void setOrdinal(uint16_t o) {
+ data = o;
+ data |= 0x80000000;
+ }
+
+ /// @brief Get the Hint/Name entry RVA. isOrdinal must be false.
+ uint32_t getHintNameRVA() const {
+ assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+ return data;
+ }
+
+ /// @brief Set the Hint/Name entry RVA and set isOrdinal to false.
+ void setHintNameRVA(uint32_t rva) { data = rva; }
+ };
+
+ /// @brief The DOS compatible header at the front of all PEs.
+ struct DOSHeader {
+ uint16_t Magic;
+ uint16_t UsedBytesInTheLastPage;
+ uint16_t FileSizeInPages;
+ uint16_t NumberOfRelocationItems;
+ uint16_t HeaderSizeInParagraphs;
+ uint16_t MinimumExtraParagraphs;
+ uint16_t MaximumExtraParagraphs;
+ uint16_t InitialRelativeSS;
+ uint16_t InitialSP;
+ uint16_t Checksum;
+ uint16_t InitialIP;
+ uint16_t InitialRelativeCS;
+ uint16_t AddressOfRelocationTable;
+ uint16_t OverlayNumber;
+ uint16_t Reserved[4];
+ uint16_t OEMid;
+ uint16_t OEMinfo;
+ uint16_t Reserved2[10];
+ uint32_t AddressOfNewExeHeader;
+ };
+
+ struct PEHeader {
+ uint32_t Signature;
+ header COFFHeader;
+ uint16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ uint32_t SizeOfCode;
+ uint32_t SizeOfInitializedData;
+ uint32_t SizeOfUninitializedData;
+ uint32_t AddressOfEntryPoint; // RVA
+ uint32_t BaseOfCode; // RVA
+ uint32_t BaseOfData; // RVA
+ uint64_t ImageBase;
+ uint32_t SectionAlignment;
+ uint32_t FileAlignment;
+ uint16_t MajorOperatingSystemVersion;
+ uint16_t MinorOperatingSystemVersion;
+ uint16_t MajorImageVersion;
+ uint16_t MinorImageVersion;
+ uint16_t MajorSubsystemVersion;
+ uint16_t MinorSubsystemVersion;
+ uint32_t Win32VersionValue;
+ uint32_t SizeOfImage;
+ uint32_t SizeOfHeaders;
+ uint32_t CheckSum;
+ uint16_t Subsystem;
+ uint16_t DLLCharacteristics;
+ uint64_t SizeOfStackReserve;
+ uint64_t SizeOfStackCommit;
+ uint64_t SizeOfHeapReserve;
+ uint64_t SizeOfHeapCommit;
+ uint32_t LoaderFlags;
+ uint32_t NumberOfRvaAndSize;
+ };
+
+ struct DataDirectory {
+ uint32_t RelativeVirtualAddress;
+ uint32_t Size;
+ };
+
+ enum WindowsSubsystem {
+ IMAGE_SUBSYSTEM_UNKNOWN = 0, ///< An unknown subsystem.
+ IMAGE_SUBSYSTEM_NATIVE = 1, ///< Device drivers and native Windows processes
+ IMAGE_SUBSYSTEM_WINDOWS_GUI = 2, ///< The Windows GUI subsystem.
+ IMAGE_SUBSYSTEM_WINDOWS_CUI = 3, ///< The Windows character subsystem.
+ IMAGE_SUBSYSTEM_POSIX_CUI = 7, ///< The POSIX character subsystem.
+ IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9, ///< Windows CE.
+ IMAGE_SUBSYSTEM_EFI_APPLICATION = 10, ///< An EFI application.
+ IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11, ///< An EFI driver with boot
+ /// services.
+ IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12, ///< An EFI driver with run-time
+ /// services.
+ IMAGE_SUBSYSTEM_EFI_ROM = 13, ///< An EFI ROM image.
+ IMAGE_SUBSYSTEM_XBOX = 14 ///< XBOX.
+ };
+
+ enum DLLCharacteristics {
+ /// DLL can be relocated at load time.
+ IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
+ /// Code integrity checks are enforced.
+ IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
+ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100, ///< Image is NX compatible.
+ /// Isolation aware, but do not isolate the image.
+ IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION = 0x0200,
+ /// Does not use structured exception handling (SEH). No SEH handler may be
+ /// called in this image.
+ IMAGE_DLL_CHARACTERISTICS_NO_SEH = 0x0400,
+ /// Do not bind the image.
+ IMAGE_DLL_CHARACTERISTICS_NO_BIND = 0x0800,
+ IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER = 0x2000, ///< A WDM driver.
+ /// Terminal Server aware.
+ IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
+ };
+
+ enum DebugType {
+ IMAGE_DEBUG_TYPE_UNKNOWN = 0,
+ IMAGE_DEBUG_TYPE_COFF = 1,
+ IMAGE_DEBUG_TYPE_CODEVIEW = 2,
+ IMAGE_DEBUG_TYPE_FPO = 3,
+ IMAGE_DEBUG_TYPE_MISC = 4,
+ IMAGE_DEBUG_TYPE_EXCEPTION = 5,
+ IMAGE_DEBUG_TYPE_FIXUP = 6,
+ IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
+ IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
+ IMAGE_DEBUG_TYPE_BORLAND = 9,
+ IMAGE_DEBUG_TYPE_CLSID = 11
+ };
+
+ enum BaseRelocationType {
+ IMAGE_REL_BASED_ABSOLUTE = 0,
+ IMAGE_REL_BASED_HIGH = 1,
+ IMAGE_REL_BASED_LOW = 2,
+ IMAGE_REL_BASED_HIGHLOW = 3,
+ IMAGE_REL_BASED_HIGHADJ = 4,
+ IMAGE_REL_BASED_MIPS_JMPADDR = 5,
+ IMAGE_REL_BASED_ARM_MOV32A = 5,
+ IMAGE_REL_BASED_ARM_MOV32T = 7,
+ IMAGE_REL_BASED_MIPS_JMPADDR16 = 9,
+ IMAGE_REL_BASED_DIR64 = 10
+ };
+
+ enum ImportType {
+ IMPORT_CODE = 0,
+ IMPORT_DATA = 1,
+ IMPORT_CONST = 2
+ };
+
+ enum ImportNameType {
+ /// Import is by ordinal. This indicates that the value in the Ordinal/Hint
+ /// field of the import header is the import's ordinal. If this constant is
+ /// not specified, then the Ordinal/Hint field should always be interpreted
+ /// as the import's hint.
+ IMPORT_ORDINAL = 0,
+ /// The import name is identical to the public symbol name
+ IMPORT_NAME = 1,
+ /// The import name is the public symbol name, but skipping the leading ?,
+ /// @, or optionally _.
+ IMPORT_NAME_NOPREFIX = 2,
+ /// The import name is the public symbol name, but skipping the leading ?,
+ /// @, or optionally _, and truncating at the first @.
+ IMPORT_NAME_UNDECORATE = 3
+ };
+
+ struct ImportHeader {
+ uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0).
+ uint16_t Sig2; ///< Must be 0xFFFF.
+ uint16_t Version;
+ uint16_t Machine;
+ uint32_t TimeDateStamp;
+ uint32_t SizeOfData;
+ uint16_t OrdinalHint;
+ uint16_t TypeInfo;
+
+ ImportType getType() const {
+ return static_cast<ImportType>(TypeInfo & 0x3);
+ }
+
+ ImportNameType getNameType() const {
+ return static_cast<ImportNameType>((TypeInfo & 0x1C) >> 3);
+ }
+ };
+
+} // End namespace COFF.
+} // End namespace llvm.
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/CallSite.h b/contrib/llvm/include/llvm/Support/CallSite.h
new file mode 100644
index 000000000000..20634ede7644
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/CallSite.h
@@ -0,0 +1,311 @@
+//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- 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 CallSite class, which is a handy wrapper for code that
+// wants to treat Call and Invoke instructions in a generic way. When in non-
+// mutation context (e.g. an analysis) ImmutableCallSite should be used.
+// Finally, when some degree of customization is necessary between these two
+// extremes, CallSiteBase<> can be supplied with fine-tuned parameters.
+//
+// NOTE: These classes are supposed to have "value semantics". So they should be
+// passed by value, not by reference; they should not be "new"ed or "delete"d.
+// They are efficiently copyable, assignable and constructable, with cost
+// equivalent to copying a pointer (notice that they have only a single data
+// member). The internal representation carries a flag which indicates which of
+// the two variants is enclosed. This allows for cheaper checks when various
+// accessors of CallSite are employed.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class CallInst;
+class InvokeInst;
+
+template <typename FunTy = const Function,
+ typename ValTy = const Value,
+ typename UserTy = const User,
+ typename InstrTy = const Instruction,
+ typename CallTy = const CallInst,
+ typename InvokeTy = const InvokeInst,
+ typename IterTy = User::const_op_iterator>
+class CallSiteBase {
+protected:
+ PointerIntPair<InstrTy*, 1, bool> I;
+public:
+ CallSiteBase() : I(0, false) {}
+ CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); }
+ CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); }
+ CallSiteBase(ValTy *II) { *this = get(II); }
+protected:
+ /// CallSiteBase::get - This static method is sort of like a constructor. It
+ /// will create an appropriate call site for a Call or Invoke instruction, but
+ /// it can also create a null initialized CallSiteBase object for something
+ /// which is NOT a call site.
+ ///
+ static CallSiteBase get(ValTy *V) {
+ if (InstrTy *II = dyn_cast<InstrTy>(V)) {
+ if (II->getOpcode() == Instruction::Call)
+ return CallSiteBase(static_cast<CallTy*>(II));
+ else if (II->getOpcode() == Instruction::Invoke)
+ return CallSiteBase(static_cast<InvokeTy*>(II));
+ }
+ return CallSiteBase();
+ }
+public:
+ /// isCall - true if a CallInst is enclosed.
+ /// Note that !isCall() does not mean it is an InvokeInst enclosed,
+ /// it also could signify a NULL Instruction pointer.
+ bool isCall() const { return I.getInt(); }
+
+ /// isInvoke - true if a InvokeInst is enclosed.
+ ///
+ bool isInvoke() const { return getInstruction() && !I.getInt(); }
+
+ InstrTy *getInstruction() const { return I.getPointer(); }
+ InstrTy *operator->() const { return I.getPointer(); }
+ operator bool() const { return I.getPointer(); }
+
+ /// getCalledValue - Return the pointer to function that is being called...
+ ///
+ ValTy *getCalledValue() const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ return *getCallee();
+ }
+
+ /// getCalledFunction - Return the function being called if this is a direct
+ /// call, otherwise return null (if it's an indirect call).
+ ///
+ FunTy *getCalledFunction() const {
+ return dyn_cast<FunTy>(getCalledValue());
+ }
+
+ /// setCalledFunction - Set the callee to the specified value...
+ ///
+ void setCalledFunction(Value *V) {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ *getCallee() = V;
+ }
+
+ /// isCallee - Determine whether the passed iterator points to the
+ /// callee operand's Use.
+ ///
+ bool isCallee(value_use_iterator<UserTy> UI) const {
+ return getCallee() == &UI.getUse();
+ }
+
+ ValTy *getArgument(unsigned ArgNo) const {
+ assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+ return *(arg_begin() + ArgNo);
+ }
+
+ void setArgument(unsigned ArgNo, Value* newVal) {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+ getInstruction()->setOperand(ArgNo, newVal);
+ }
+
+ /// Given a value use iterator, returns the argument that corresponds to it.
+ /// Iterator must actually correspond to an argument.
+ unsigned getArgumentNo(value_use_iterator<UserTy> I) const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
+ && "Argument # out of range!");
+ return &I.getUse() - arg_begin();
+ }
+
+ /// arg_iterator - The type of iterator to use when looping over actual
+ /// arguments at this call site...
+ typedef IterTy arg_iterator;
+
+ /// arg_begin/arg_end - Return iterators corresponding to the actual argument
+ /// list for a call site.
+ IterTy arg_begin() const {
+ assert(getInstruction() && "Not a call or invoke instruction!");
+ // Skip non-arguments
+ return (*this)->op_begin();
+ }
+
+ IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
+ bool arg_empty() const { return arg_end() == arg_begin(); }
+ unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
+
+ /// getType - Return the type of the instruction that generated this call site
+ ///
+ Type *getType() const { return (*this)->getType(); }
+
+ /// getCaller - Return the caller function for this call site
+ ///
+ FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
+
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+ InstrTy *II = getInstruction(); \
+ return isCall() \
+ ? cast<CallInst>(II)->METHOD \
+ : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+ InstrTy *II = getInstruction(); \
+ if (isCall()) \
+ cast<CallInst>(II)->METHOD; \
+ else \
+ cast<InvokeInst>(II)->METHOD
+
+ /// getCallingConv/setCallingConv - get or set the calling convention of the
+ /// call.
+ CallingConv::ID getCallingConv() const {
+ CALLSITE_DELEGATE_GETTER(getCallingConv());
+ }
+ void setCallingConv(CallingConv::ID CC) {
+ CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
+ }
+
+ /// getAttributes/setAttributes - get or set the parameter attributes of
+ /// the call.
+ const AttrListPtr &getAttributes() const {
+ CALLSITE_DELEGATE_GETTER(getAttributes());
+ }
+ void setAttributes(const AttrListPtr &PAL) {
+ CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
+ }
+
+ /// 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 Extract the alignment for a call or parameter (0=unknown).
+ uint16_t getParamAlignment(uint16_t i) const {
+ CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
+ }
+
+ /// @brief Return true if the call should not be inlined.
+ bool isNoInline() const {
+ CALLSITE_DELEGATE_GETTER(isNoInline());
+ }
+ void setIsNoInline(bool Value = true) {
+ CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
+ }
+
+ /// @brief Determine if the call does not access memory.
+ bool doesNotAccessMemory() const {
+ CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
+ }
+ void setDoesNotAccessMemory(bool doesNotAccessMemory = true) {
+ CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
+ }
+
+ /// @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));
+ }
+
+ /// @brief Determine if the call cannot return.
+ bool doesNotReturn() const {
+ CALLSITE_DELEGATE_GETTER(doesNotReturn());
+ }
+ void setDoesNotReturn(bool doesNotReturn = true) {
+ CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
+ }
+
+ /// @brief Determine if the call cannot unwind.
+ bool doesNotThrow() const {
+ CALLSITE_DELEGATE_GETTER(doesNotThrow());
+ }
+ void setDoesNotThrow(bool doesNotThrow = true) {
+ CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
+ }
+
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
+ /// @brief Determine whether this argument is not captured.
+ bool doesNotCapture(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::NoCapture);
+ }
+
+ /// @brief Determine whether this argument is passed by value.
+ bool isByValArgument(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::ByVal);
+ }
+
+ /// hasArgument - Returns true if this CallSite passes the given Value* as an
+ /// argument to the called function.
+ bool hasArgument(const Value *Arg) const {
+ for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
+ ++AI)
+ if (AI->get() == Arg)
+ return true;
+ return false;
+ }
+
+private:
+ unsigned getArgumentEndOffset() const {
+ if (isCall())
+ return 1; // Skip Callee
+ else
+ return 3; // Skip BB, BB, Callee
+ }
+
+ IterTy getCallee() const {
+ if (isCall()) // Skip Callee
+ return cast<CallInst>(getInstruction())->op_end() - 1;
+ else // Skip BB, BB, Callee
+ return cast<InvokeInst>(getInstruction())->op_end() - 3;
+ }
+};
+
+class CallSite : public CallSiteBase<Function, Value, User, Instruction,
+ CallInst, InvokeInst, User::op_iterator> {
+ typedef CallSiteBase<Function, Value, User, Instruction,
+ CallInst, InvokeInst, User::op_iterator> Base;
+public:
+ CallSite() {}
+ CallSite(Base B) : Base(B) {}
+ CallSite(Value* V) : Base(V) {}
+ CallSite(CallInst *CI) : Base(CI) {}
+ CallSite(InvokeInst *II) : Base(II) {}
+ CallSite(Instruction *II) : Base(II) {}
+
+ bool operator==(const CallSite &CS) const { return I == CS.I; }
+ bool operator!=(const CallSite &CS) const { return I != CS.I; }
+ bool operator<(const CallSite &CS) const {
+ return getInstruction() < CS.getInstruction();
+ }
+
+private:
+ User::op_iterator getCallee() const;
+};
+
+/// ImmutableCallSite - establish a view to a call site for examination
+class ImmutableCallSite : public CallSiteBase<> {
+ typedef CallSiteBase<> Base;
+public:
+ ImmutableCallSite(const Value* V) : Base(V) {}
+ ImmutableCallSite(const CallInst *CI) : Base(CI) {}
+ ImmutableCallSite(const InvokeInst *II) : Base(II) {}
+ ImmutableCallSite(const Instruction *II) : Base(II) {}
+ ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Capacity.h b/contrib/llvm/include/llvm/Support/Capacity.h
new file mode 100644
index 000000000000..7460f9825bd3
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Capacity.h
@@ -0,0 +1,32 @@
+//===--- Capacity.h - Generic computation of ADT memory use -----*- 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 capacity function that computes the amount of
+// memory used by an ADT.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CAPACITY_H
+#define LLVM_SUPPORT_CAPACITY_H
+
+#include <cstddef>
+
+namespace llvm {
+
+template <typename T>
+static inline size_t capacity_in_bytes(const T &x) {
+ // This default definition of capacity should work for things like std::vector
+ // and friends. More specialized versions will work for others.
+ return x.capacity() * sizeof(typename T::value_type);
+}
+
+} // end namespace llvm
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Support/Casting.h b/contrib/llvm/include/llvm/Support/Casting.h
new file mode 100644
index 000000000000..3aab4367f5bb
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Casting.h
@@ -0,0 +1,233 @@
+//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- 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 isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
+// and dyn_cast_or_null<X>() templates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CASTING_H
+#define LLVM_SUPPORT_CASTING_H
+
+#include <cassert>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// isa<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+// Define a template that can be specialized by smart pointers to reflect the
+// fact that they are automatically dereferenced, and are not involved with the
+// template selection process... the default implementation is a noop.
+//
+template<typename From> struct simplify_type {
+ typedef From SimpleType; // The real type this represents...
+
+ // An accessor to get the real value...
+ static SimpleType &getSimplifiedValue(From &Val) { return Val; }
+};
+
+template<typename From> struct simplify_type<const From> {
+ typedef const From SimpleType;
+ static SimpleType &getSimplifiedValue(const From &Val) {
+ return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
+ }
+};
+
+// 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>
+struct isa_impl {
+ static inline bool doit(const From &Val) {
+ return To::classof(&Val);
+ }
+};
+
+template <typename To, typename From> struct isa_impl_cl {
+ static inline bool doit(const From &Val) {
+ 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) {
+ return isa_impl<To, From>::doit(Val);
+ }
+};
+
+template <typename To, typename From> struct isa_impl_cl<To, From*> {
+ static inline bool doit(const From *Val) {
+ 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) {
+ 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) {
+ return isa_impl<To, From>::doit(*Val);
+ }
+};
+
+template<typename To, typename From, typename SimpleFrom>
+struct isa_impl_wrap {
+ // When From != SimplifiedType, we can simplify the type some more by using
+ // the simplify_type template.
+ static bool doit(const From &Val) {
+ return isa_impl_wrap<To, SimpleFrom,
+ typename simplify_type<SimpleFrom>::SimpleType>::doit(
+ simplify_type<From>::getSimplifiedValue(Val));
+ }
+};
+
+template<typename To, typename FromTy>
+struct isa_impl_wrap<To, FromTy, FromTy> {
+ // When From == SimpleType, we are as simple as we are going to get.
+ static bool doit(const FromTy &Val) {
+ return isa_impl_cl<To,FromTy>::doit(Val);
+ }
+};
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument. Used like this:
+//
+// if (isa<Type>(myVal)) { ... }
+//
+template <class X, class Y>
+inline bool isa(const Y &Val) {
+ return isa_impl_wrap<X, Y, typename simplify_type<Y>::SimpleType>::doit(Val);
+}
+
+//===----------------------------------------------------------------------===//
+// cast<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<class To, class From> struct cast_retty;
+
+
+// Calculate what type the 'cast' function should return, based on a requested
+// type of To and a source type of From.
+template<class To, class From> struct cast_retty_impl {
+ typedef To& ret_type; // Normal case, return Ty&
+};
+template<class To, class From> struct cast_retty_impl<To, const From> {
+ typedef const To &ret_type; // Normal case, return Ty&
+};
+
+template<class To, class From> struct cast_retty_impl<To, From*> {
+ typedef To* ret_type; // Pointer arg case, return Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*const> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+
+template<class To, class From, class SimpleFrom>
+struct cast_retty_wrap {
+ // When the simplified type and the from type are not the same, use the type
+ // simplifier to reduce the type, then reuse cast_retty_impl to get the
+ // resultant type.
+ typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
+};
+
+template<class To, class FromTy>
+struct cast_retty_wrap<To, FromTy, FromTy> {
+ // When the simplified type is equal to the from type, use it directly.
+ typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
+};
+
+template<class To, class From>
+struct cast_retty {
+ typedef typename cast_retty_wrap<To, From,
+ typename simplify_type<From>::SimpleType>::ret_type ret_type;
+};
+
+// Ensure the non-simple values are converted using the simplify_type template
+// that may be specialized by smart pointers...
+//
+template<class To, class From, class SimpleFrom> struct cast_convert_val {
+ // This is not a simple type, use the template to simplify it...
+ static typename cast_retty<To, From>::ret_type doit(const From &Val) {
+ return cast_convert_val<To, SimpleFrom,
+ typename simplify_type<SimpleFrom>::SimpleType>::doit(
+ simplify_type<From>::getSimplifiedValue(Val));
+ }
+};
+
+template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
+ // This _is_ a simple type, just cast it.
+ static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
+ typename cast_retty<To, FromTy>::ret_type Res2
+ = (typename cast_retty<To, FromTy>::ret_type)const_cast<FromTy&>(Val);
+ return Res2;
+ }
+};
+
+
+
+// cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator asserts that the type is correct, so it does not return null
+// on failure. It does not allow a null argument (use cast_or_null for that).
+// It is typically used like this:
+//
+// cast<Instruction>(myVal)->getParent()
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
+ assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+ return cast_convert_val<X, Y,
+ typename simplify_type<Y>::SimpleType>::doit(Val);
+}
+
+// cast_or_null<X> - Functionally identical to cast, except that a null value is
+// accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
+ if (Val == 0) return 0;
+ assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
+ return cast<X>(Val);
+}
+
+
+// dyn_cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator returns null if the argument is of the wrong type, so it can
+// be used to test for a type as well as cast if successful. This should be
+// used in the context of an if statement like this:
+//
+// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
+//
+
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
+ return isa<X>(Val) ? cast<X, Y>(Val) : 0;
+}
+
+// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
+// value is accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
+ return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/CodeGen.h b/contrib/llvm/include/llvm/Support/CodeGen.h
new file mode 100644
index 000000000000..1b66c943895e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/CodeGen.h
@@ -0,0 +1,52 @@
+//===-- llvm/Support/CodeGen.h - CodeGen Concepts ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file define some types which define code generation concepts. For
+// example, relocation model.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CODEGEN_H
+#define LLVM_SUPPORT_CODEGEN_H
+
+namespace llvm {
+
+ // Relocation model types.
+ namespace Reloc {
+ enum Model { Default, Static, PIC_, DynamicNoPIC };
+ }
+
+ // Code model types.
+ namespace CodeModel {
+ enum Model { Default, JITDefault, Small, Kernel, Medium, Large };
+ }
+
+ // TLS models.
+ namespace TLSModel {
+ enum Model {
+ GeneralDynamic,
+ LocalDynamic,
+ InitialExec,
+ LocalExec
+ };
+ }
+
+ // Code generation optimization level.
+ namespace CodeGenOpt {
+ enum Level {
+ None, // -O0
+ Less, // -O1
+ Default, // -O2, -Os
+ Aggressive // -O3
+ };
+ }
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm/include/llvm/Support/CommandLine.h
new file mode 100644
index 000000000000..c212d2d59f64
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/CommandLine.h
@@ -0,0 +1,1689 @@
+//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements a command line argument processor that is useful when
+// creating a tool. It provides a simple, minimalistic interface that is easily
+// extensible and supports nonlocal (library) command line options.
+//
+// Note that rather than trying to figure out what this code does, you should
+// read the library documentation located in docs/CommandLine.html or looks at
+// the many example usages in tools/*/*.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#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 <cassert>
+#include <climits>
+#include <cstdarg>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+/// cl Namespace - This namespace contains all of the command line option
+/// processing machinery. It is intentionally a short name to make qualified
+/// usage concise.
+namespace cl {
+
+//===----------------------------------------------------------------------===//
+// ParseCommandLineOptions - Command line option processing entry point.
+//
+void ParseCommandLineOptions(int argc, const char * const *argv,
+ const char *Overview = 0,
+ bool ReadResponseFiles = false);
+
+//===----------------------------------------------------------------------===//
+// ParseEnvironmentOptions - Environment variable option processing alternate
+// entry point.
+//
+void ParseEnvironmentOptions(const char *progName, const char *envvar,
+ const char *Overview = 0,
+ bool ReadResponseFiles = false);
+
+///===---------------------------------------------------------------------===//
+/// SetVersionPrinter - Override the default (LLVM specific) version printer
+/// used to print out the version when --version is given
+/// on the command line. This allows other systems using the
+/// CommandLine utilities to print their own version string.
+void SetVersionPrinter(void (*func)());
+
+///===---------------------------------------------------------------------===//
+/// AddExtraVersionPrinter - Add an extra printer to use in addition to the
+/// default one. This can be called multiple times,
+/// and each time it adds a new function to the list
+/// which will be called after the basic LLVM version
+/// printing is complete. Each can then add additional
+/// information specific to the tool.
+void AddExtraVersionPrinter(void (*func)());
+
+
+// PrintOptionValues - Print option values.
+// With -print-options print the difference between option values and defaults.
+// With -print-all-options print all option values.
+// (Currently not perfect, but best-effort.)
+void PrintOptionValues();
+
+// MarkOptionsChanged - Internal helper function.
+void MarkOptionsChanged();
+
+//===----------------------------------------------------------------------===//
+// Flags permitted to be passed to command line arguments
+//
+
+enum NumOccurrencesFlag { // Flags for the number of occurrences allowed
+ Optional = 0x00, // Zero or One occurrence
+ ZeroOrMore = 0x01, // Zero or more occurrences allowed
+ Required = 0x02, // One occurrence required
+ OneOrMore = 0x03, // One or more occurrences required
+
+ // ConsumeAfter - Indicates that this option is fed anything that follows the
+ // last positional argument required by the application (it is an error if
+ // there are zero positional arguments, and a ConsumeAfter option is used).
+ // Thus, for example, all arguments to LLI are processed until a filename is
+ // found. Once a filename is found, all of the succeeding arguments are
+ // passed, unprocessed, to the ConsumeAfter option.
+ //
+ ConsumeAfter = 0x04
+};
+
+enum ValueExpected { // Is a value required for the option?
+ // zero reserved for the unspecified value
+ ValueOptional = 0x01, // The value can appear... or not
+ ValueRequired = 0x02, // The value is required to appear!
+ ValueDisallowed = 0x03 // A value may not be specified (for flags)
+};
+
+enum OptionHidden { // Control whether -help shows this option
+ NotHidden = 0x00, // Option included in -help & -help-hidden
+ Hidden = 0x01, // -help doesn't, but -help-hidden does
+ ReallyHidden = 0x02 // Neither -help nor -help-hidden show this arg
+};
+
+// Formatting flags - This controls special features that the option might have
+// that cause it to be parsed differently...
+//
+// Prefix - This option allows arguments that are otherwise unrecognized to be
+// matched by options that are a prefix of the actual value. This is useful for
+// cases like a linker, where options are typically of the form '-lfoo' or
+// '-L../../include' where -l or -L are the actual flags. When prefix is
+// enabled, and used, the value for the flag comes from the suffix of the
+// argument.
+//
+// Grouping - With this option enabled, multiple letter options are allowed to
+// bunch together with only a single hyphen for the whole group. This allows
+// emulation of the behavior that ls uses for example: ls -la === ls -l -a
+//
+
+enum FormattingFlags {
+ NormalFormatting = 0x00, // Nothing special
+ Positional = 0x01, // Is a positional argument, no '-' required
+ Prefix = 0x02, // Can this option directly prefix its value?
+ Grouping = 0x03 // Can this option group with other options?
+};
+
+enum MiscFlags { // Miscellaneous flags to adjust argument
+ CommaSeparated = 0x01, // Should this cl::list split between commas?
+ PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args?
+ Sink = 0x04 // Should this cl::list eat all unknown options?
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Option Base class
+//
+class alias;
+class Option {
+ friend class alias;
+
+ // handleOccurrences - Overriden by subclasses to handle the value passed into
+ // an argument. Should return true if there was an error processing the
+ // argument and the program should exit.
+ //
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) = 0;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // Out of line virtual function to provide home for the class.
+ virtual void anchor();
+
+ int NumOccurrences; // The number of times specified
+ // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid
+ // problems with signed enums in bitfields.
+ unsigned Occurrences : 3; // enum NumOccurrencesFlag
+ // not using the enum type for 'Value' because zero is an implementation
+ // detail representing the non-value
+ unsigned Value : 2;
+ unsigned HiddenFlag : 2; // enum OptionHidden
+ unsigned Formatting : 2; // enum FormattingFlags
+ unsigned Misc : 3;
+ unsigned Position; // Position of last occurrence of the option
+ unsigned AdditionalVals;// Greater than 0 for multi-valued option.
+ Option *NextRegistered; // Singly linked list of registered options.
+public:
+ const char *ArgStr; // The argument string itself (ex: "help", "o")
+ const char *HelpStr; // The descriptive text message for -help
+ const char *ValueStr; // String describing what the value of this option is
+
+ inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
+ return (enum NumOccurrencesFlag)Occurrences;
+ }
+ inline enum ValueExpected getValueExpectedFlag() const {
+ return Value ? ((enum ValueExpected)Value)
+ : getValueExpectedFlagDefault();
+ }
+ inline enum OptionHidden getOptionHiddenFlag() const {
+ return (enum OptionHidden)HiddenFlag;
+ }
+ inline enum FormattingFlags getFormattingFlag() const {
+ return (enum FormattingFlags)Formatting;
+ }
+ inline unsigned getMiscFlags() const {
+ return Misc;
+ }
+ inline unsigned getPosition() const { return Position; }
+ inline unsigned getNumAdditionalVals() const { return AdditionalVals; }
+
+ // hasArgStr - Return true if the argstr != ""
+ bool hasArgStr() const { return ArgStr[0] != 0; }
+
+ //-------------------------------------------------------------------------===
+ // Accessor functions set by OptionModifiers
+ //
+ void setArgStr(const char *S) { ArgStr = S; }
+ void setDescription(const char *S) { HelpStr = S; }
+ void setValueStr(const char *S) { ValueStr = S; }
+ void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) {
+ Occurrences = Val;
+ }
+ void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; }
+ void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; }
+ void setFormattingFlag(enum FormattingFlags V) { Formatting = V; }
+ void setMiscFlag(enum MiscFlags M) { Misc |= M; }
+ void setPosition(unsigned pos) { Position = pos; }
+protected:
+ explicit Option(enum NumOccurrencesFlag Occurrences,
+ enum OptionHidden Hidden)
+ : NumOccurrences(0), Occurrences(Occurrences), HiddenFlag(Hidden),
+ Formatting(NormalFormatting), Position(0),
+ AdditionalVals(0), NextRegistered(0),
+ ArgStr(""), HelpStr(""), ValueStr("") {
+ }
+
+ inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
+public:
+ // addArgument - Register this argument with the commandline system.
+ //
+ void addArgument();
+
+ Option *getNextRegisteredOption() const { return NextRegistered; }
+
+ // Return the width of the option tag for printing...
+ virtual size_t getOptionWidth() const = 0;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(size_t GlobalWidth) const = 0;
+
+ virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0;
+
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
+
+ // addOccurrence - Wrapper around handleOccurrence that enforces Flags.
+ //
+ bool addOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Value, bool MultiArg = false);
+
+ // Prints option name followed by message. Always returns true.
+ bool error(const Twine &Message, StringRef ArgName = StringRef());
+
+public:
+ inline int getNumOccurrences() const { return NumOccurrences; }
+ virtual ~Option() {}
+};
+
+
+//===----------------------------------------------------------------------===//
+// Command line option modifiers that can be used to modify the behavior of
+// command line option parsers...
+//
+
+// desc - Modifier to set the description shown in the -help output...
+struct desc {
+ const char *Desc;
+ desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setDescription(Desc); }
+};
+
+// value_desc - Modifier to set the value description shown in the -help
+// output...
+struct value_desc {
+ const char *Desc;
+ value_desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setValueStr(Desc); }
+};
+
+// init - Specify a default (initial) value for the command line argument, if
+// the default constructor for the argument type does not give you what you
+// want. This is only valid on "opt" arguments, not on "list" arguments.
+//
+template<class Ty>
+struct initializer {
+ const Ty &Init;
+ initializer(const Ty &Val) : Init(Val) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setInitialValue(Init); }
+};
+
+template<class Ty>
+initializer<Ty> init(const Ty &Val) {
+ return initializer<Ty>(Val);
+}
+
+
+// location - Allow the user to specify which external variable they want to
+// store the results of the command line argument processing into, if they don't
+// want to store it in the option itself.
+//
+template<class Ty>
+struct LocationClass {
+ Ty &Loc;
+ LocationClass(Ty &L) : Loc(L) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setLocation(O, Loc); }
+};
+
+template<class Ty>
+LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
+
+
+//===----------------------------------------------------------------------===//
+// OptionValue class
+
+// Support value comparison outside the template.
+struct GenericOptionValue {
+ virtual ~GenericOptionValue() {}
+ virtual bool compare(const GenericOptionValue &V) const = 0;
+private:
+ virtual void anchor();
+};
+
+template<class DataType> struct OptionValue;
+
+// The default value safely does nothing. Option value printing is only
+// best-effort.
+template<class DataType, bool isClass>
+struct OptionValueBase : public GenericOptionValue {
+ // Temporary storage for argument passing.
+ typedef OptionValue<DataType> WrapperType;
+
+ bool hasValue() const { return false; }
+
+ const DataType &getValue() const { llvm_unreachable("no default value"); }
+
+ // Some options may take their value from a different data type.
+ template<class DT>
+ void setValue(const DT& /*V*/) {}
+
+ bool compare(const DataType &/*V*/) const { return false; }
+
+ virtual bool compare(const GenericOptionValue& /*V*/) const { return false; }
+};
+
+// Simple copy of the option value.
+template<class DataType>
+class OptionValueCopy : public GenericOptionValue {
+ DataType Value;
+ bool Valid;
+public:
+ OptionValueCopy() : Valid(false) {}
+
+ bool hasValue() const { return Valid; }
+
+ const DataType &getValue() const {
+ assert(Valid && "invalid option value");
+ return Value;
+ }
+
+ void setValue(const DataType &V) { Valid = true; Value = V; }
+
+ bool compare(const DataType &V) const {
+ return Valid && (Value != V);
+ }
+
+ virtual bool compare(const GenericOptionValue &V) const {
+ const OptionValueCopy<DataType> &VC =
+ static_cast< const OptionValueCopy<DataType>& >(V);
+ if (!VC.hasValue()) return false;
+ return compare(VC.getValue());
+ }
+};
+
+// Non-class option values.
+template<class DataType>
+struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
+ typedef DataType WrapperType;
+};
+
+// Top-level option class.
+template<class DataType>
+struct OptionValue : OptionValueBase<DataType, is_class<DataType>::value> {
+ OptionValue() {}
+
+ OptionValue(const DataType& V) {
+ this->setValue(V);
+ }
+ // Some options may take their value from a different data type.
+ template<class DT>
+ OptionValue<DataType> &operator=(const DT& V) {
+ this->setValue(V);
+ return *this;
+ }
+};
+
+// Other safe-to-copy-by-value common option types.
+enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
+template<>
+struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
+ typedef cl::boolOrDefault WrapperType;
+
+ OptionValue() {}
+
+ OptionValue(const cl::boolOrDefault& V) {
+ this->setValue(V);
+ }
+ OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault& V) {
+ setValue(V);
+ return *this;
+ }
+private:
+ virtual void anchor();
+};
+
+template<>
+struct OptionValue<std::string> : OptionValueCopy<std::string> {
+ typedef StringRef WrapperType;
+
+ OptionValue() {}
+
+ OptionValue(const std::string& V) {
+ this->setValue(V);
+ }
+ OptionValue<std::string> &operator=(const std::string& V) {
+ setValue(V);
+ return *this;
+ }
+private:
+ virtual void anchor();
+};
+
+//===----------------------------------------------------------------------===//
+// Enum valued command line option
+//
+#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
+#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
+#define clEnumValEnd (reinterpret_cast<void*>(0))
+
+// values - For custom data types, allow specifying a group of values together
+// as the values that go into the mapping that the option handler uses. Note
+// that the values list must always have a 0 at the end of the list to indicate
+// that the list has ended.
+//
+template<class DataType>
+class ValuesClass {
+ // Use a vector instead of a map, because the lists should be short,
+ // the overhead is less, and most importantly, it keeps them in the order
+ // inserted so we can print our option out nicely.
+ SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
+ void processValues(va_list Vals);
+public:
+ ValuesClass(const char *EnumName, DataType Val, const char *Desc,
+ va_list ValueArgs) {
+ // Insert the first value, which is required.
+ Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
+
+ // Process the varargs portion of the values...
+ while (const char *enumName = va_arg(ValueArgs, const char *)) {
+ DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
+ const char *EnumDesc = va_arg(ValueArgs, const char *);
+ Values.push_back(std::make_pair(enumName, // Add value to value map
+ std::make_pair(EnumVal, EnumDesc)));
+ }
+ }
+
+ template<class Opt>
+ void apply(Opt &O) const {
+ for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
+ i != e; ++i)
+ O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
+ Values[i].second.second);
+ }
+};
+
+template<class DataType>
+ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
+ const char *Desc, ...) {
+ va_list ValueArgs;
+ va_start(ValueArgs, Desc);
+ ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
+ va_end(ValueArgs);
+ return Vals;
+}
+
+//===----------------------------------------------------------------------===//
+// parser class - Parameterizable parser for different data types. By default,
+// known data types (string, int, bool) have specialized parsers, that do what
+// you would expect. The default parser, used for data types that are not
+// built-in, uses a mapping table to map specific options to values, which is
+// used, among other things, to handle enum types.
+
+//--------------------------------------------------
+// generic_parser_base - This class holds all the non-generic code that we do
+// not need replicated for every instance of the generic parser. This also
+// allows us to put stuff into CommandLine.cpp
+//
+class generic_parser_base {
+protected:
+ class GenericOptionInfo {
+ public:
+ GenericOptionInfo(const char *name, const char *helpStr) :
+ Name(name), HelpStr(helpStr) {}
+ const char *Name;
+ const char *HelpStr;
+ };
+public:
+ virtual ~generic_parser_base() {} // Base class should have virtual-dtor
+
+ // getNumOptions - Virtual function implemented by generic subclass to
+ // indicate how many entries are in Values.
+ //
+ virtual unsigned getNumOptions() const = 0;
+
+ // getOption - Return option name N.
+ virtual const char *getOption(unsigned N) const = 0;
+
+ // getDescription - Return description N
+ virtual const char *getDescription(unsigned N) const = 0;
+
+ // Return the width of the option tag for printing...
+ virtual size_t getOptionWidth(const Option &O) const;
+
+ virtual const GenericOptionValue &getOptionValue(unsigned N) const = 0;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const;
+
+ void printGenericOptionDiff(const Option &O, const GenericOptionValue &V,
+ const GenericOptionValue &Default,
+ size_t GlobalWidth) const;
+
+ // printOptionDiff - print the value of an option and it's default.
+ //
+ // Template definition ensures that the option and default have the same
+ // DataType (via the same AnyOptionValue).
+ template<class AnyOptionValue>
+ void printOptionDiff(const Option &O, const AnyOptionValue &V,
+ const AnyOptionValue &Default,
+ size_t GlobalWidth) const {
+ printGenericOptionDiff(O, V, Default, GlobalWidth);
+ }
+
+ void initialize(Option &O) {
+ // All of the modifiers for the option have been processed by now, so the
+ // argstr field should be stable, copy it down now.
+ //
+ hasArgStr = O.hasArgStr();
+ }
+
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ // If there has been no argstr specified, that means that we need to add an
+ // argument for every possible option. This ensures that our options are
+ // vectored to us.
+ if (!hasArgStr)
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+ OptionNames.push_back(getOption(i));
+ }
+
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ // If there is an ArgStr specified, then we are of the form:
+ //
+ // -opt=O2 or -opt O2 or -optO2
+ //
+ // In which case, the value is required. Otherwise if an arg str has not
+ // been specified, we are of the form:
+ //
+ // -O2 or O2 or -la (where -l and -a are separate options)
+ //
+ // If this is the case, we cannot allow a value.
+ //
+ if (hasArgStr)
+ return ValueRequired;
+ else
+ return ValueDisallowed;
+ }
+
+ // findOption - Return the option number corresponding to the specified
+ // argument string. If the option is not found, getNumOptions() is returned.
+ //
+ unsigned findOption(const char *Name);
+
+protected:
+ bool hasArgStr;
+};
+
+// Default parser implementation - This implementation depends on having a
+// mapping of recognized options to values of some sort. In addition to this,
+// each entry in the mapping also tracks a help message that is printed with the
+// command line option for -help. Because this is a simple mapping parser, the
+// data type can be any unsupported type.
+//
+template <class DataType>
+class parser : public generic_parser_base {
+protected:
+ class OptionInfo : public GenericOptionInfo {
+ public:
+ OptionInfo(const char *name, DataType v, const char *helpStr) :
+ GenericOptionInfo(name, helpStr), V(v) {}
+ OptionValue<DataType> V;
+ };
+ SmallVector<OptionInfo, 8> Values;
+public:
+ typedef DataType parser_data_type;
+
+ // Implement virtual functions needed by generic_parser_base
+ unsigned getNumOptions() const { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const { return Values[N].Name; }
+ const char *getDescription(unsigned N) const {
+ return Values[N].HelpStr;
+ }
+
+ // getOptionValue - Return the value of option name N.
+ virtual const GenericOptionValue &getOptionValue(unsigned N) const {
+ return Values[N].V;
+ }
+
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) {
+ StringRef ArgVal;
+ if (hasArgStr)
+ ArgVal = Arg;
+ else
+ ArgVal = ArgName;
+
+ for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
+ i != e; ++i)
+ if (Values[i].Name == ArgVal) {
+ V = Values[i].V.getValue();
+ return false;
+ }
+
+ return O.error("Cannot find option named '" + ArgVal + "'!");
+ }
+
+ /// addLiteralOption - Add an entry to the mapping table.
+ ///
+ template <class DT>
+ void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
+ assert(findOption(Name) == Values.size() && "Option already exists!");
+ OptionInfo X(Name, static_cast<DataType>(V), HelpStr);
+ Values.push_back(X);
+ MarkOptionsChanged();
+ }
+
+ /// removeLiteralOption - Remove the specified option.
+ ///
+ void removeLiteralOption(const char *Name) {
+ unsigned N = findOption(Name);
+ assert(N != Values.size() && "Option not found!");
+ Values.erase(Values.begin()+N);
+ }
+};
+
+//--------------------------------------------------
+// basic_parser - Super class of parsers to provide boilerplate code
+//
+class basic_parser_impl { // non-template implementation of basic_parser<t>
+public:
+ virtual ~basic_parser_impl() {}
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueRequired;
+ }
+
+ void getExtraOptionNames(SmallVectorImpl<const char*> &) {}
+
+ void initialize(Option &) {}
+
+ // Return the width of the option tag for printing...
+ size_t getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ void printOptionInfo(const Option &O, size_t GlobalWidth) const;
+
+ // printOptionNoValue - Print a placeholder for options that don't yet support
+ // printOptionDiff().
+ void printOptionNoValue(const Option &O, size_t GlobalWidth) const;
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "value"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+
+protected:
+ // A helper for basic_parser::printOptionDiff.
+ void printOptionName(const Option &O, size_t GlobalWidth) const;
+};
+
+// basic_parser - The real basic parser is just a template wrapper that provides
+// a typedef for the provided data type.
+//
+template<class DataType>
+class basic_parser : public basic_parser_impl {
+public:
+ typedef DataType parser_data_type;
+ typedef OptionValue<DataType> OptVal;
+};
+
+//--------------------------------------------------
+// parser<bool>
+//
+template<>
+class parser<bool> : public basic_parser<bool> {
+ const char *ArgStr;
+public:
+
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val);
+
+ template <class Opt>
+ void initialize(Opt &O) {
+ ArgStr = O.ArgStr;
+ }
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ void printOptionDiff(const Option &O, bool V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+
+//--------------------------------------------------
+// parser<boolOrDefault>
+template<>
+class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val);
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+
+//--------------------------------------------------
+// parser<int>
+//
+template<>
+class parser<int> : public basic_parser<int> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "int"; }
+
+ void printOptionDiff(const Option &O, int V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+
+
+//--------------------------------------------------
+// parser<unsigned>
+//
+template<>
+class parser<unsigned> : public basic_parser<unsigned> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "uint"; }
+
+ void printOptionDiff(const Option &O, unsigned V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+
+//--------------------------------------------------
+// parser<unsigned long long>
+//
+template<>
+class parser<unsigned long long> : public basic_parser<unsigned long long> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg,
+ unsigned long long &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "uint"; }
+
+ void printOptionDiff(const Option &O, unsigned long long V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
+
+//--------------------------------------------------
+// parser<double>
+//
+template<>
+class parser<double> : public basic_parser<double> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ void printOptionDiff(const Option &O, double V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+
+//--------------------------------------------------
+// parser<float>
+//
+template<>
+class parser<float> : public basic_parser<float> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ void printOptionDiff(const Option &O, float V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+
+//--------------------------------------------------
+// parser<std::string>
+//
+template<>
+class parser<std::string> : public basic_parser<std::string> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &, StringRef, StringRef Arg, std::string &Value) {
+ Value = Arg.str();
+ return false;
+ }
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "string"; }
+
+ void printOptionDiff(const Option &O, StringRef V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+
+//--------------------------------------------------
+// parser<char>
+//
+template<>
+class parser<char> : public basic_parser<char> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &, StringRef, StringRef Arg, char &Value) {
+ Value = Arg[0];
+ return false;
+ }
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "char"; }
+
+ void printOptionDiff(const Option &O, char V, OptVal Default,
+ size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
+
+//--------------------------------------------------
+// PrintOptionDiff
+//
+// This collection of wrappers is the intermediary between class opt and class
+// parser to handle all the template nastiness.
+
+// This overloaded function is selected by the generic parser.
+template<class ParserClass, class DT>
+void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V,
+ const OptionValue<DT> &Default, size_t GlobalWidth) {
+ OptionValue<DT> OV = V;
+ P.printOptionDiff(O, OV, Default, GlobalWidth);
+}
+
+// This is instantiated for basic parsers when the parsed value has a different
+// type than the option value. e.g. HelpPrinter.
+template<class ParserDT, class ValDT>
+struct OptionDiffPrinter {
+ void print(const Option &O, const parser<ParserDT> P, const ValDT &/*V*/,
+ const OptionValue<ValDT> &/*Default*/, size_t GlobalWidth) {
+ P.printOptionNoValue(O, GlobalWidth);
+ }
+};
+
+// This is instantiated for basic parsers when the parsed value has the same
+// type as the option value.
+template<class DT>
+struct OptionDiffPrinter<DT, DT> {
+ void print(const Option &O, const parser<DT> P, const DT &V,
+ const OptionValue<DT> &Default, size_t GlobalWidth) {
+ P.printOptionDiff(O, V, Default, GlobalWidth);
+ }
+};
+
+// This overloaded function is selected by the basic parser, which may parse a
+// different type than the option type.
+template<class ParserClass, class ValDT>
+void printOptionDiff(
+ const Option &O,
+ const basic_parser<typename ParserClass::parser_data_type> &P,
+ const ValDT &V, const OptionValue<ValDT> &Default,
+ size_t GlobalWidth) {
+
+ OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer;
+ printer.print(O, static_cast<const ParserClass&>(P), V, Default,
+ GlobalWidth);
+}
+
+//===----------------------------------------------------------------------===//
+// applicator class - This class is used because we must use partial
+// specialization to handle literal string arguments specially (const char* does
+// not correctly respond to the apply method). Because the syntax to use this
+// is a pain, we have the 'apply' method below to handle the nastiness...
+//
+template<class Mod> struct applicator {
+ template<class Opt>
+ static void opt(const Mod &M, Opt &O) { M.apply(O); }
+};
+
+// Handle const char* as a special case...
+template<unsigned n> struct applicator<char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<unsigned n> struct applicator<const char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<> struct applicator<const char*> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+
+template<> struct applicator<NumOccurrencesFlag> {
+ static void opt(NumOccurrencesFlag NO, Option &O) {
+ O.setNumOccurrencesFlag(NO);
+ }
+};
+template<> struct applicator<ValueExpected> {
+ static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
+};
+template<> struct applicator<OptionHidden> {
+ static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
+};
+template<> struct applicator<FormattingFlags> {
+ static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
+};
+template<> struct applicator<MiscFlags> {
+ static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
+};
+
+// apply method - Apply a modifier to an option in a type safe way.
+template<class Mod, class Opt>
+void apply(const Mod &M, Opt *O) {
+ applicator<Mod>::opt(M, *O);
+}
+
+//===----------------------------------------------------------------------===//
+// opt_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, bool ExternalStorage, bool isClass>
+class opt_storage {
+ DataType *Location; // Where to store the object...
+ OptionValue<DataType> Default;
+
+ void check() const {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage, "
+ "or cl::init specified before cl::location()!!");
+ }
+public:
+ opt_storage() : Location(0) {}
+
+ bool setLocation(Option &O, DataType &L) {
+ if (Location)
+ return O.error("cl::location(x) specified more than once!");
+ Location = &L;
+ Default = L;
+ return false;
+ }
+
+ template<class T>
+ void setValue(const T &V, bool initial = false) {
+ check();
+ *Location = V;
+ if (initial)
+ Default = V;
+ }
+
+ DataType &getValue() { check(); return *Location; }
+ const DataType &getValue() const { check(); return *Location; }
+
+ operator DataType() const { return this->getValue(); }
+
+ const OptionValue<DataType> &getDefault() const { return Default; }
+};
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class opt_storage<DataType,false,true> : public DataType {
+public:
+ OptionValue<DataType> Default;
+
+ template<class T>
+ void setValue(const T &V, bool initial = false) {
+ DataType::operator=(V);
+ if (initial)
+ Default = V;
+ }
+
+ DataType &getValue() { return *this; }
+ const DataType &getValue() const { return *this; }
+
+ const OptionValue<DataType> &getDefault() const { return Default; }
+};
+
+// Define a partial specialization to handle things we cannot inherit from. In
+// this case, we store an instance through containment, and overload operators
+// to get at the value.
+//
+template<class DataType>
+class opt_storage<DataType, false, false> {
+public:
+ DataType Value;
+ OptionValue<DataType> Default;
+
+ // Make sure we initialize the value with the default constructor for the
+ // type.
+ opt_storage() : Value(DataType()) {}
+
+ template<class T>
+ void setValue(const T &V, bool initial = false) {
+ Value = V;
+ if (initial)
+ Default = V;
+ }
+ DataType &getValue() { return Value; }
+ DataType getValue() const { return Value; }
+
+ const OptionValue<DataType> &getDefault() const { return Default; }
+
+ operator DataType() const { return getValue(); }
+
+ // If the datatype is a pointer, support -> on it.
+ DataType operator->() const { return Value; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// opt - A scalar command line option.
+//
+template <class DataType, bool ExternalStorage = false,
+ class ParserClass = parser<DataType> >
+class opt : public Option,
+ public opt_storage<DataType, ExternalStorage,
+ is_class<DataType>::value> {
+ ParserClass Parser;
+
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse error!
+ this->setValue(Val);
+ this->setPosition(pos);
+ return false;
+ }
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ // Forward printing stuff to the parser...
+ virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(size_t GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ virtual void printOptionValue(size_t GlobalWidth, bool Force) const {
+ if (Force || this->getDefault().compare(this->getValue())) {
+ cl::printOptionDiff<ParserClass>(
+ *this, Parser, this->getValue(), this->getDefault(), GlobalWidth);
+ }
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ // setInitialValue - Used by the cl::init modifier...
+ void setInitialValue(const DataType &V) { this->setValue(V, true); }
+
+ ParserClass &getParser() { return Parser; }
+
+ template<class T>
+ DataType &operator=(const T &Val) {
+ this->setValue(Val);
+ return this->getValue();
+ }
+
+ // One option...
+ template<class M0t>
+ explicit opt(const M0t &M0) : Option(Optional, NotHidden) {
+ apply(M0, this);
+ done();
+ }
+
+ // Two options...
+ template<class M0t, class M1t>
+ opt(const M0t &M0, const M1t &M1) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ opt(const M0t &M0, const M1t &M1,
+ const M2t &M2) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2,
+ const M3t &M3) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5,
+ const M6t &M6) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(Optional, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+
+//===----------------------------------------------------------------------===//
+// list_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class list_storage {
+ StorageClass *Location; // Where to store the object...
+
+public:
+ list_storage() : Location(0) {}
+
+ bool setLocation(Option &O, StorageClass &L) {
+ if (Location)
+ return O.error("cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ Location->push_back(V);
+ }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class list_storage<DataType, bool> : public std::vector<DataType> {
+public:
+ template<class T>
+ void addValue(const T &V) { std::vector<DataType>::push_back(V); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// list - A list of command line options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class list : public Option, public list_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ list_storage<DataType, Storage>::addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(size_t GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ // Unimplemented: list options don't currently store their default value.
+ virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ void setNumAdditionalVals(unsigned n) {
+ Option::setNumAdditionalVals(n);
+ }
+
+ // One option...
+ template<class M0t>
+ explicit list(const M0t &M0) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+// multi_val - Modifier to set the number of additional values.
+struct multi_val {
+ unsigned AdditionalVals;
+ explicit multi_val(unsigned N) : AdditionalVals(N) {}
+
+ template <typename D, typename S, typename P>
+ void apply(list<D, S, P> &L) const { L.setNumAdditionalVals(AdditionalVals); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class bits_storage {
+ unsigned *Location; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ bits_storage() : Location(0) {}
+
+ bool setLocation(Option &O, unsigned &L) {
+ if (Location)
+ return O.error("cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ *Location |= Bit(V);
+ }
+
+ unsigned getBits() { return *Location; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (*Location & Bit(V)) != 0;
+ }
+};
+
+
+// Define how to hold bits. Since we can inherit from a class, we do so.
+// This makes us exactly compatible with the bits in all cases that it is used.
+//
+template<class DataType>
+class bits_storage<DataType, bool> {
+ unsigned Bits; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = (unsigned)V;
+ assert(BitPos < sizeof(unsigned) * CHAR_BIT &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ template<class T>
+ void addValue(const T &V) {
+ Bits |= Bit(V);
+ }
+
+ unsigned getBits() { return Bits; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (Bits & Bit(V)) != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits - A bit vector of command options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class bits : public Option, public bits_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(size_t GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ // Unimplemented: bits options don't currently store their default values.
+ virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ // One option...
+ template<class M0t>
+ explicit bits(const M0t &M0) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore, NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Aliased command line option (alias this name to a preexisting name)
+//
+
+class alias : public Option {
+ Option *AliasFor;
+ virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
+ StringRef Arg) {
+ return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
+ }
+ // Handle printing stuff...
+ virtual size_t getOptionWidth() const;
+ virtual void printOptionInfo(size_t GlobalWidth) const;
+
+ // Aliases do not need to print their values.
+ virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+
+ void done() {
+ if (!hasArgStr())
+ error("cl::alias must have argument name specified!");
+ if (AliasFor == 0)
+ error("cl::alias must have an cl::aliasopt(option) specified!");
+ addArgument();
+ }
+public:
+ void setAliasFor(Option &O) {
+ if (AliasFor)
+ error("cl::alias must only have one cl::aliasopt(...) specified!");
+ AliasFor = &O;
+ }
+
+ // One option...
+ template<class M0t>
+ explicit alias(const M0t &M0) : Option(Optional, Hidden), AliasFor(0) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ alias(const M0t &M0, const M1t &M1) : Option(Optional, Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(Optional, Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(Optional, Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+};
+
+// aliasfor - Modifier to set the option an alias aliases.
+struct aliasopt {
+ Option &Opt;
+ explicit aliasopt(Option &O) : Opt(O) {}
+ void apply(alias &A) const { A.setAliasFor(Opt); }
+};
+
+// extrahelp - provide additional help at the end of the normal help
+// output. All occurrences of cl::extrahelp will be accumulated and
+// printed to stderr at the end of the regular help, just before
+// exit is called.
+struct extrahelp {
+ const char * morehelp;
+ explicit extrahelp(const char* help);
+};
+
+void PrintVersionMessage();
+// This function just prints the help message, exactly the same way as if the
+// -help option had been given on the command line.
+// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
+void PrintHelpMessage();
+
+} // End namespace cl
+
+} // End namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Compiler.h b/contrib/llvm/include/llvm/Support/Compiler.h
new file mode 100644
index 000000000000..d0b186ea7c2b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Compiler.h
@@ -0,0 +1,152 @@
+//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- 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 several macros, based on the current compiler. This allows
+// use of compiler-specific features in a way that remains portable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMPILER_H
+#define LLVM_SUPPORT_COMPILER_H
+
+#ifndef __has_feature
+# define __has_feature(x) 0
+#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
+/// functions, making them private to any shared library they are linked into.
+#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden")))
+#else
+#define LLVM_LIBRARY_VISIBILITY
+#endif
+
+#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
+#else
+#define LLVM_ATTRIBUTE_USED
+#endif
+
+// Some compilers warn about unused functions. When a function is sometimes
+// used or not depending on build settings (e.g. a function only called from
+// within "assert"), this attribute can be used to suppress such warnings.
+//
+// However, it shouldn't be used for unused *variables*, as those have a much
+// more portable solution:
+// (void)unused_var_name;
+// Prefer cast-to-void wherever it is sufficient.
+#if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
+#else
+#define LLVM_ATTRIBUTE_UNUSED
+#endif
+
+#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__))
+#else
+#define LLVM_ATTRIBUTE_WEAK
+#endif
+
+#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions.
+#define LLVM_READNONE __attribute__((__const__))
+#else
+#define LLVM_READNONE
+#endif
+
+#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions.
+#define LLVM_READONLY __attribute__((__pure__))
+#else
+#define LLVM_READONLY
+#endif
+
+#if (__GNUC__ >= 4)
+#define BUILTIN_EXPECT(EXPR, VALUE) __builtin_expect((EXPR), (VALUE))
+#else
+#define BUILTIN_EXPECT(EXPR, VALUE) (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>);
+// in the .cpp file, use this:
+// TEMPLATE_INSTANTIATION(class foo<bar>);
+#ifdef __GNUC__
+#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
+#define TEMPLATE_INSTANTIATION(X) template X
+#else
+#define EXTERN_TEMPLATE_INSTANTIATION(X)
+#define TEMPLATE_INSTANTIATION(X)
+#endif
+
+// 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)
+#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline)
+#else
+#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.
+#if __GNUC__ > 3
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
+#else
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+
+#ifdef __GNUC__
+#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#elif defined(_MSC_VER)
+#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn)
+#else
+#define LLVM_ATTRIBUTE_NORETURN
+#endif
+
+// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
+// pedantic diagnostics.
+#ifdef __GNUC__
+#define LLVM_EXTENSION __extension__
+#else
+#define LLVM_EXTENSION
+#endif
+
+// LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
+#if __has_feature(attribute_deprecated_with_message)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ decl __attribute__((deprecated(message)))
+#elif defined(__GNUC__)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ decl __attribute__((deprecated))
+#elif defined(_MSC_VER)
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ __declspec(deprecated(message)) decl
+#else
+# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \
+ 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.
+#if defined(__clang__) || (__GNUC__ > 4) \
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/ConstantFolder.h b/contrib/llvm/include/llvm/Support/ConstantFolder.h
new file mode 100644
index 000000000000..93aa3436d273
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ConstantFolder.h
@@ -0,0 +1,238 @@
+//===-- llvm/Support/ConstantFolder.h - Constant folding helper -*- 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 ConstantFolder class, a helper for IRBuilder.
+// It provides IRBuilder with a set of methods for creating constants
+// with minimal folding. For general constant creation and folding,
+// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
+#define LLVM_SUPPORT_CONSTANTFOLDER_H
+
+#include "llvm/Constants.h"
+#include "llvm/InstrTypes.h"
+
+namespace llvm {
+
+/// ConstantFolder - Create constants with minimum, target independent, folding.
+class ConstantFolder {
+public:
+ explicit ConstantFolder() {}
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
+ }
+ Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFAdd(LHS, RHS);
+ }
+ Constant *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
+ }
+ Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFSub(LHS, RHS);
+ }
+ Constant *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
+ }
+ Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFMul(LHS, RHS);
+ }
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getUDiv(LHS, RHS, isExact);
+ }
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getSDiv(LHS, RHS, isExact);
+ }
+ Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFDiv(LHS, RHS);
+ }
+ Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getURem(LHS, RHS);
+ }
+ Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getSRem(LHS, RHS);
+ }
+ Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getFRem(LHS, RHS);
+ }
+ Constant *CreateShl(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
+ }
+ Constant *CreateLShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getLShr(LHS, RHS, isExact);
+ }
+ Constant *CreateAShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ return ConstantExpr::getAShr(LHS, RHS, isExact);
+ }
+ Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getAnd(LHS, RHS);
+ }
+ Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getOr(LHS, RHS);
+ }
+ Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::getXor(LHS, RHS);
+ }
+
+ Constant *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
+ return ConstantExpr::get(Opc, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return ConstantExpr::getNeg(C, HasNUW, HasNSW);
+ }
+ Constant *CreateFNeg(Constant *C) const {
+ return ConstantExpr::getFNeg(C);
+ }
+ Constant *CreateNot(Constant *C) const {
+ return ConstantExpr::getNot(C);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) const {
+ return ConstantExpr::getGetElementPtr(C, IdxList);
+ }
+ Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ return ConstantExpr::getGetElementPtr(C, Idx);
+ }
+ Constant *CreateGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) const {
+ return ConstantExpr::getGetElementPtr(C, IdxList);
+ }
+
+ Constant *CreateInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ return ConstantExpr::getInBoundsGetElementPtr(C, Idx);
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+ Type *DestTy) const {
+ return ConstantExpr::getCast(Op, C, DestTy);
+ }
+ Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
+ return ConstantExpr::getPointerCast(C, DestTy);
+ }
+ Constant *CreateIntCast(Constant *C, Type *DestTy,
+ bool isSigned) const {
+ return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
+ }
+ Constant *CreateFPCast(Constant *C, Type *DestTy) const {
+ return ConstantExpr::getFPCast(C, DestTy);
+ }
+
+ Constant *CreateBitCast(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::BitCast, C, DestTy);
+ }
+ Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::IntToPtr, C, DestTy);
+ }
+ Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::PtrToInt, C, DestTy);
+ }
+ Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+ return ConstantExpr::getZExtOrBitCast(C, DestTy);
+ }
+ Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+ return ConstantExpr::getSExtOrBitCast(C, DestTy);
+ }
+
+ Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+ return ConstantExpr::getTruncOrBitCast(C, DestTy);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return ConstantExpr::getCompare(P, LHS, RHS);
+ }
+ Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return ConstantExpr::getCompare(P, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ return ConstantExpr::getSelect(C, True, False);
+ }
+
+ Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ return ConstantExpr::getExtractElement(Vec, Idx);
+ }
+
+ Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
+ return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
+ }
+
+ Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+ Constant *Mask) const {
+ return ConstantExpr::getShuffleVector(V1, V2, Mask);
+ }
+
+ Constant *CreateExtractValue(Constant *Agg,
+ ArrayRef<unsigned> IdxList) const {
+ return ConstantExpr::getExtractValue(Agg, IdxList);
+ }
+
+ Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+ ArrayRef<unsigned> IdxList) const {
+ return ConstantExpr::getInsertValue(Agg, Val, IdxList);
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/ConstantRange.h b/contrib/llvm/include/llvm/Support/ConstantRange.h
new file mode 100644
index 000000000000..ced3a2cf2dbd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ConstantRange.h
@@ -0,0 +1,265 @@
+//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Represent a range of possible values that may occur when the program is run
+// for an integral value. This keeps track of a lower and upper bound for the
+// constant, which MAY wrap around the end of the numeric range. To do this, it
+// keeps track of a [lower, upper) bound, which specifies an interval just like
+// STL iterators. When used with boolean values, the following are important
+// ranges: :
+//
+// [F, F) = {} = Empty set
+// [T, F) = {T}
+// [F, T) = {F}
+// [T, T) = {F, T} = Full set
+//
+// The other integral ranges use min/max values for special range values. For
+// example, for 8-bit types, it uses:
+// [0, 0) = {} = Empty set
+// [255, 255) = {0..255} = Full Set
+//
+// Note that ConstantRange can be used to represent either signed or
+// unsigned ranges.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
+#define LLVM_SUPPORT_CONSTANT_RANGE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// ConstantRange - This class represents an range of values.
+///
+class ConstantRange {
+ APInt Lower, Upper;
+
+public:
+ /// Initialize a full (the default) or empty set for the specified bit width.
+ ///
+ explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true);
+
+ /// Initialize a range to hold the single specified value.
+ ///
+ ConstantRange(const APInt &Value);
+
+ /// @brief Initialize a range of values explicitly. This will assert out if
+ /// Lower==Upper and Lower != Min or Max value for its type. It will also
+ /// assert out if the two APInt's are not the same bit width.
+ ConstantRange(const APInt &Lower, const APInt &Upper);
+
+ /// makeICmpRegion - Produce the smallest range that contains all values that
+ /// might satisfy the comparison specified by Pred when compared to any value
+ /// contained within Other.
+ ///
+ /// Solves for range X in 'for all x in X, there exists a y in Y such that
+ /// icmp op x, y is true'. Every value that might make the comparison true
+ /// is included in the resulting range.
+ static ConstantRange makeICmpRegion(unsigned Pred,
+ const ConstantRange &Other);
+
+ /// getLower - Return the lower value for this range...
+ ///
+ const APInt &getLower() const { return Lower; }
+
+ /// getUpper - Return the upper value for this range...
+ ///
+ const APInt &getUpper() const { return Upper; }
+
+ /// getBitWidth - get the bit width of this ConstantRange
+ ///
+ uint32_t getBitWidth() const { return Lower.getBitWidth(); }
+
+ /// isFullSet - Return true if this set contains all of the elements possible
+ /// for this data-type
+ ///
+ bool isFullSet() const;
+
+ /// isEmptySet - Return true if this set contains no members.
+ ///
+ bool isEmptySet() const;
+
+ /// isWrappedSet - Return true if this set wraps around the top of the range,
+ /// for example: [100, 8)
+ ///
+ bool isWrappedSet() const;
+
+ /// isSignWrappedSet - Return true if this set wraps around the INT_MIN of
+ /// its bitwidth, for example: i8 [120, 140).
+ ///
+ bool isSignWrappedSet() const;
+
+ /// contains - Return true if the specified value is in the set.
+ ///
+ bool contains(const APInt &Val) const;
+
+ /// contains - Return true if the other range is a subset of this one.
+ ///
+ bool contains(const ConstantRange &CR) const;
+
+ /// getSingleElement - If this set contains a single element, return it,
+ /// otherwise return null.
+ ///
+ const APInt *getSingleElement() const {
+ if (Upper == Lower + 1)
+ return &Lower;
+ return 0;
+ }
+
+ /// isSingleElement - Return true if this set contains exactly one member.
+ ///
+ bool isSingleElement() const { return getSingleElement() != 0; }
+
+ /// getSetSize - Return the number of elements in this set.
+ ///
+ APInt getSetSize() const;
+
+ /// getUnsignedMax - Return the largest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMax() const;
+
+ /// getUnsignedMin - Return the smallest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMin() const;
+
+ /// getSignedMax - Return the largest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMax() const;
+
+ /// getSignedMin - Return the smallest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMin() const;
+
+ /// operator== - Return true if this range is equal to another range.
+ ///
+ bool operator==(const ConstantRange &CR) const {
+ return Lower == CR.Lower && Upper == CR.Upper;
+ }
+ bool operator!=(const ConstantRange &CR) const {
+ return !operator==(CR);
+ }
+
+ /// subtract - Subtract the specified constant from the endpoints of this
+ /// constant range.
+ ConstantRange subtract(const APInt &CI) const;
+
+ /// intersectWith - Return the range that results from the intersection of
+ /// this range with another range. The resultant range is guaranteed to
+ /// include all elements contained in both input ranges, and to have the
+ /// smallest possible set size that does so. Because there may be two
+ /// intersections with the same set size, A.intersectWith(B) might not
+ /// be equal to B.intersectWith(A).
+ ///
+ ConstantRange intersectWith(const ConstantRange &CR) const;
+
+ /// unionWith - Return the range that results from the union of this range
+ /// with another range. The resultant range is guaranteed to include the
+ /// elements of both sets, but may contain more. For example, [3, 9) union
+ /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
+ /// in either set before.
+ ///
+ ConstantRange unionWith(const ConstantRange &CR) const;
+
+ /// zeroExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// zero extended to BitWidth.
+ ConstantRange zeroExtend(uint32_t BitWidth) const;
+
+ /// signExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// sign extended to BitWidth.
+ ConstantRange signExtend(uint32_t BitWidth) const;
+
+ /// truncate - Return a new range in the specified integer type, which must be
+ /// strictly smaller than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// truncated to the specified type.
+ ConstantRange truncate(uint32_t BitWidth) const;
+
+ /// zextOrTrunc - make this range have the bit width given by \p BitWidth. The
+ /// value is zero extended, truncated, or left alone to make it that width.
+ ConstantRange zextOrTrunc(uint32_t BitWidth) const;
+
+ /// sextOrTrunc - make this range have the bit width given by \p BitWidth. The
+ /// value is sign extended, truncated, or left alone to make it that width.
+ ConstantRange sextOrTrunc(uint32_t BitWidth) const;
+
+ /// add - Return a new range representing the possible values resulting
+ /// from an addition of a value in this range and a value in \p Other.
+ ConstantRange add(const ConstantRange &Other) const;
+
+ /// sub - Return a new range representing the possible values resulting
+ /// from a subtraction of a value in this range and a value in \p Other.
+ ConstantRange sub(const ConstantRange &Other) const;
+
+ /// multiply - Return a new range representing the possible values resulting
+ /// from a multiplication of a value in this range and a value in \p Other.
+ /// TODO: This isn't fully implemented yet.
+ ConstantRange multiply(const ConstantRange &Other) const;
+
+ /// smax - Return a new range representing the possible values resulting
+ /// from a signed maximum of a value in this range and a value in \p Other.
+ ConstantRange smax(const ConstantRange &Other) const;
+
+ /// umax - Return a new range representing the possible values resulting
+ /// from an unsigned maximum of a value in this range and a value in \p Other.
+ ConstantRange umax(const ConstantRange &Other) const;
+
+ /// udiv - Return a new range representing the possible values resulting
+ /// from an unsigned division of a value in this range and a value in
+ /// \p Other.
+ ConstantRange udiv(const ConstantRange &Other) const;
+
+ /// binaryAnd - return a new range representing the possible values resulting
+ /// from a binary-and of a value in this range by a value in \p Other.
+ ConstantRange binaryAnd(const ConstantRange &Other) const;
+
+ /// binaryOr - return a new range representing the possible values resulting
+ /// from a binary-or of a value in this range by a value in \p Other.
+ ConstantRange binaryOr(const ConstantRange &Other) const;
+
+ /// shl - Return a new range representing the possible values resulting
+ /// from a left shift of a value in this range by a value in \p Other.
+ /// TODO: This isn't fully implemented yet.
+ ConstantRange shl(const ConstantRange &Other) const;
+
+ /// lshr - Return a new range representing the possible values resulting
+ /// from a logical right shift of a value in this range and a value in
+ /// \p Other.
+ ConstantRange lshr(const ConstantRange &Other) const;
+
+ /// inverse - Return a new range that is the logical not of the current set.
+ ///
+ ConstantRange inverse() const;
+
+ /// print - Print out the bounds to a stream...
+ ///
+ void print(raw_ostream &OS) const;
+
+ /// dump - Allow printing from a debugger easily...
+ ///
+ void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) {
+ CR.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h b/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h
new file mode 100644
index 000000000000..4c0a5e26f00f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/CrashRecoveryContext.h
@@ -0,0 +1,200 @@
+//===--- CrashRecoveryContext.h - Crash Recovery ----------------*- 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_CRASHRECOVERYCONTEXT_H
+#define LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
+
+#include <string>
+
+namespace llvm {
+class StringRef;
+
+class CrashRecoveryContextCleanup;
+
+/// \brief Crash recovery helper object.
+///
+/// This class implements support for running operations in a safe context so
+/// that crashes (memory errors, stack overflow, assertion violations) can be
+/// detected and control restored to the crashing thread. Crash detection is
+/// purely "best effort", the exact set of failures which can be recovered from
+/// is platform dependent.
+///
+/// Clients make use of this code by first calling
+/// CrashRecoveryContext::Enable(), and then executing unsafe operations via a
+/// CrashRecoveryContext object. For example:
+///
+/// void actual_work(void *);
+///
+/// void foo() {
+/// CrashRecoveryContext CRC;
+///
+/// if (!CRC.RunSafely(actual_work, 0)) {
+/// ... a crash was detected, report error to user ...
+/// }
+///
+/// ... no crash was detected ...
+/// }
+///
+/// Crash recovery contexts may not be nested.
+class CrashRecoveryContext {
+ void *Impl;
+ CrashRecoveryContextCleanup *head;
+
+public:
+ CrashRecoveryContext() : Impl(0), head(0) {}
+ ~CrashRecoveryContext();
+
+ void registerCleanup(CrashRecoveryContextCleanup *cleanup);
+ void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
+
+ /// \brief Enable crash recovery.
+ static void Enable();
+
+ /// \brief Disable crash recovery.
+ static void Disable();
+
+ /// \brief Return the active context, if the code is currently executing in a
+ /// thread which is in a protected context.
+ static CrashRecoveryContext *GetCurrent();
+
+ /// \brief Return true if the current thread is recovering from a
+ /// crash.
+ static bool isRecoveringFromCrash();
+
+ /// \brief Execute the provide callback function (with the given arguments) in
+ /// a protected context.
+ ///
+ /// \return True if the function completed successfully, and false if the
+ /// function crashed (or HandleCrash was called explicitly). Clients should
+ /// make as little assumptions as possible about the program state when
+ /// RunSafely has returned false. Clients can use getBacktrace() to retrieve
+ /// the backtrace of the crash on failures.
+ bool RunSafely(void (*Fn)(void*), void *UserData);
+
+ /// \brief Execute the provide callback function (with the given arguments) in
+ /// a protected context which is run in another thread (optionally with a
+ /// requested stack size).
+ ///
+ /// See RunSafely() and llvm_execute_on_thread().
+ bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize = 0);
+
+ /// \brief Explicitly trigger a crash recovery in the current process, and
+ /// return failure from RunSafely(). This function does not return.
+ void HandleCrash();
+
+ /// \brief Return a string containing the backtrace where the crash was
+ /// detected; or empty if the backtrace wasn't recovered.
+ ///
+ /// This function is only valid when a crash has been detected (i.e.,
+ /// RunSafely() has returned false.
+ const std::string &getBacktrace() const;
+};
+
+class CrashRecoveryContextCleanup {
+protected:
+ CrashRecoveryContext *context;
+ CrashRecoveryContextCleanup(CrashRecoveryContext *context)
+ : context(context), cleanupFired(false) {}
+public:
+ bool cleanupFired;
+
+ virtual ~CrashRecoveryContextCleanup();
+ virtual void recoverResources() = 0;
+
+ CrashRecoveryContext *getContext() const {
+ return context;
+ }
+
+private:
+ friend class CrashRecoveryContext;
+ CrashRecoveryContextCleanup *prev, *next;
+};
+
+template<typename DERIVED, typename T>
+class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup {
+protected:
+ T *resource;
+ CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource)
+ : CrashRecoveryContextCleanup(context), resource(resource) {}
+public:
+ static DERIVED *create(T *x) {
+ if (x) {
+ if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent())
+ return new DERIVED(context, x);
+ }
+ return 0;
+ }
+};
+
+template <typename T>
+class CrashRecoveryContextDestructorCleanup : public
+ CrashRecoveryContextCleanupBase<CrashRecoveryContextDestructorCleanup<T>, T> {
+public:
+ CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context,
+ T *resource)
+ : CrashRecoveryContextCleanupBase<
+ CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {}
+
+ virtual void recoverResources() {
+ this->resource->~T();
+ }
+};
+
+template <typename T>
+class CrashRecoveryContextDeleteCleanup : public
+ CrashRecoveryContextCleanupBase<CrashRecoveryContextDeleteCleanup<T>, T> {
+public:
+ CrashRecoveryContextDeleteCleanup(CrashRecoveryContext *context, T *resource)
+ : CrashRecoveryContextCleanupBase<
+ CrashRecoveryContextDeleteCleanup<T>, T>(context, resource) {}
+
+ virtual void recoverResources() {
+ delete this->resource;
+ }
+};
+
+template <typename T>
+class CrashRecoveryContextReleaseRefCleanup : public
+ CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T>
+{
+public:
+ CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context,
+ T *resource)
+ : CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>,
+ T>(context, resource) {}
+
+ virtual void recoverResources() {
+ this->resource->Release();
+ }
+};
+
+template <typename T, typename Cleanup = CrashRecoveryContextDeleteCleanup<T> >
+class CrashRecoveryContextCleanupRegistrar {
+ CrashRecoveryContextCleanup *cleanup;
+public:
+ CrashRecoveryContextCleanupRegistrar(T *x)
+ : cleanup(Cleanup::create(x)) {
+ if (cleanup)
+ cleanup->getContext()->registerCleanup(cleanup);
+ }
+
+ ~CrashRecoveryContextCleanupRegistrar() {
+ unregister();
+ }
+
+ void unregister() {
+ if (cleanup && !cleanup->cleanupFired)
+ cleanup->getContext()->unregisterCleanup(cleanup);
+ cleanup = 0;
+ }
+};
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/DOTGraphTraits.h b/contrib/llvm/include/llvm/Support/DOTGraphTraits.h
new file mode 100644
index 000000000000..483f2674af7b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DOTGraphTraits.h
@@ -0,0 +1,161 @@
+//===-- llvm/Support/DotGraphTraits.h - Customize .dot output ---*- 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 template class that can be used to customize dot output
+// graphs generated by the GraphWriter.h file. The default implementation of
+// this file will produce a simple, but not very polished graph. By
+// specializing this template, lots of customization opportunities are possible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H
+#define LLVM_SUPPORT_DOTGRAPHTRAITS_H
+
+#include <string>
+
+namespace llvm {
+
+/// DefaultDOTGraphTraits - This class provides the default implementations of
+/// all of the DOTGraphTraits methods. If a specialization does not need to
+/// override all methods here it should inherit so that it can get the default
+/// implementations.
+///
+struct DefaultDOTGraphTraits {
+private:
+ bool IsSimple;
+
+protected:
+ bool isSimple() {
+ return IsSimple;
+ }
+
+public:
+ explicit DefaultDOTGraphTraits(bool simple=false) : IsSimple (simple) {}
+
+ /// getGraphName - Return the label for the graph as a whole. Printed at the
+ /// top of the graph.
+ ///
+ template<typename GraphType>
+ static std::string getGraphName(const GraphType &) { return ""; }
+
+ /// getGraphProperties - Return any custom properties that should be included
+ /// in the top level graph structure for dot.
+ ///
+ template<typename GraphType>
+ static std::string getGraphProperties(const GraphType &) {
+ return "";
+ }
+
+ /// renderGraphFromBottomUp - If this function returns true, the graph is
+ /// emitted bottom-up instead of top-down. This requires graphviz 2.0 to work
+ /// though.
+ static bool renderGraphFromBottomUp() {
+ return false;
+ }
+
+ /// isNodeHidden - If the function returns true, the given node is not
+ /// displayed in the graph.
+ static bool isNodeHidden(const void *) {
+ return false;
+ }
+
+ /// getNodeLabel - Given a node and a pointer to the top level graph, return
+ /// the label to print in the node.
+ template<typename GraphType>
+ std::string getNodeLabel(const void *, const GraphType &) {
+ return "";
+ }
+
+ /// hasNodeAddressLabel - If this method returns true, the address of the node
+ /// is added to the label of the node.
+ template<typename GraphType>
+ static bool hasNodeAddressLabel(const void *, const GraphType &) {
+ return false;
+ }
+
+ /// If you want to specify custom node attributes, this is the place to do so
+ ///
+ template<typename GraphType>
+ static std::string getNodeAttributes(const void *,
+ const GraphType &) {
+ return "";
+ }
+
+ /// If you want to override the dot attributes printed for a particular edge,
+ /// override this method.
+ template<typename EdgeIter, typename GraphType>
+ static std::string getEdgeAttributes(const void *, EdgeIter,
+ const GraphType &) {
+ return "";
+ }
+
+ /// getEdgeSourceLabel - If you want to label the edge source itself,
+ /// implement this method.
+ template<typename EdgeIter>
+ static std::string getEdgeSourceLabel(const void *, EdgeIter) {
+ return "";
+ }
+
+ /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
+ /// should actually target another edge source, not a node. If this method is
+ /// implemented, getEdgeTarget should be implemented.
+ template<typename EdgeIter>
+ static bool edgeTargetsEdgeSource(const void *, EdgeIter) {
+ return false;
+ }
+
+ /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
+ /// called to determine which outgoing edge of Node is the target of this
+ /// edge.
+ template<typename EdgeIter>
+ static EdgeIter getEdgeTarget(const void *, EdgeIter I) {
+ return I;
+ }
+
+ /// hasEdgeDestLabels - If this function returns true, the graph is able
+ /// to provide labels for edge destinations.
+ static bool hasEdgeDestLabels() {
+ return false;
+ }
+
+ /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
+ /// number of incoming edge labels the given node has.
+ static unsigned numEdgeDestLabels(const void *) {
+ return 0;
+ }
+
+ /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
+ /// incoming edge label with the given index in the given node.
+ static std::string getEdgeDestLabel(const void *, unsigned) {
+ return "";
+ }
+
+ /// addCustomGraphFeatures - If a graph is made up of more than just
+ /// straight-forward nodes and edges, this is the place to put all of the
+ /// custom stuff necessary. The GraphWriter object, instantiated with your
+ /// GraphType is passed in as an argument. You may call arbitrary methods on
+ /// it to add things to the output graph.
+ ///
+ template<typename GraphType, typename GraphWriter>
+ static void addCustomGraphFeatures(const GraphType &, GraphWriter &) {}
+};
+
+
+/// DOTGraphTraits - Template class that can be specialized to customize how
+/// graphs are converted to 'dot' graphs. When specializing, you may inherit
+/// from DefaultDOTGraphTraits if you don't need to override everything.
+///
+template <typename Ty>
+struct DOTGraphTraits : public DefaultDOTGraphTraits {
+ DOTGraphTraits (bool simple=false) : DefaultDOTGraphTraits (simple) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/DataExtractor.h b/contrib/llvm/include/llvm/Support/DataExtractor.h
new file mode 100644
index 000000000000..506ec96930d9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DataExtractor.h
@@ -0,0 +1,352 @@
+//===-- DataExtractor.h -----------------------------------------*- 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_DATAEXTRACTOR_H
+#define LLVM_SUPPORT_DATAEXTRACTOR_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+class DataExtractor {
+ StringRef Data;
+ uint8_t IsLittleEndian;
+ uint8_t PointerSize;
+public:
+ /// Construct with a buffer that is owned by the caller.
+ ///
+ /// This constructor allows us to use data that is owned by the
+ /// caller. The data must stay around as long as this object is
+ /// valid.
+ DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize)
+ : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {}
+
+ /// getData - Get the data pointed to by this extractor.
+ StringRef getData() const { return Data; }
+ /// isLittleEndian - Get the endianess for this extractor.
+ bool isLittleEndian() const { return IsLittleEndian; }
+ /// getAddressSize - Get the address size for this extractor.
+ uint8_t getAddressSize() const { return PointerSize; }
+
+ /// Extract a C string from \a *offset_ptr.
+ ///
+ /// Returns a pointer to a C String from the data at the offset
+ /// pointed to by \a offset_ptr. A variable length NULL terminated C
+ /// string will be extracted and the \a offset_ptr will be
+ /// updated with the offset of the byte that follows the NULL
+ /// terminator byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// A pointer to the C string value in the data. If the offset
+ /// pointed to by \a offset_ptr is out of bounds, or if the
+ /// offset plus the length of the C string is out of bounds,
+ /// NULL will be returned.
+ const char *getCStr(uint32_t *offset_ptr) const;
+
+ /// Extract an unsigned integer of size \a byte_size from \a
+ /// *offset_ptr.
+ ///
+ /// Extract a single unsigned integer value and update the offset
+ /// pointed to by \a offset_ptr. The size of the extracted integer
+ /// is specified by the \a byte_size argument. \a byte_size should
+ /// have a value greater than or equal to one and less than or equal
+ /// to eight since the return value is 64 bits wide. Any
+ /// \a byte_size values less than 1 or greater than 8 will result in
+ /// nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to extract.
+ ///
+ /// @return
+ /// The unsigned integer value that was extracted, or zero on
+ /// failure.
+ uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const;
+
+ /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
+ ///
+ /// Extract a single signed integer value (sign extending if required)
+ /// and update the offset pointed to by \a offset_ptr. The size of
+ /// the extracted integer is specified by the \a byte_size argument.
+ /// \a byte_size should have a value greater than or equal to one
+ /// and less than or equal to eight since the return value is 64
+ /// bits wide. Any \a byte_size values less than 1 or greater than
+ /// 8 will result in nothing being extracted, and zero being returned.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[in] byte_size
+ /// The size in byte of the integer to extract.
+ ///
+ /// @return
+ /// The sign extended signed integer value that was extracted,
+ /// or zero on failure.
+ int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const;
+
+ //------------------------------------------------------------------
+ /// Extract an pointer from \a *offset_ptr.
+ ///
+ /// Extract a single pointer from the data and update the offset
+ /// pointed to by \a offset_ptr. The size of the extracted pointer
+ /// comes from the \a m_addr_size member variable and should be
+ /// set correctly prior to extracting any pointer values.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted pointer value as a 64 integer.
+ uint64_t getAddress(uint32_t *offset_ptr) const {
+ return getUnsigned(offset_ptr, PointerSize);
+ }
+
+ /// Extract a uint8_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint8_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and advance the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint8_t value.
+ uint8_t getU8(uint32_t *offset_ptr) const;
+
+ /// Extract \a count uint8_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint8_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint8_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint8_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const;
+
+ //------------------------------------------------------------------
+ /// Extract a uint16_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint16_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and update the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint16_t value.
+ //------------------------------------------------------------------
+ uint16_t getU16(uint32_t *offset_ptr) const;
+
+ /// Extract \a count uint16_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint16_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint16_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint16_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const;
+
+ /// Extract a uint32_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint32_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and update the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint32_t value.
+ uint32_t getU32(uint32_t *offset_ptr) const;
+
+ /// Extract \a count uint32_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint32_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint32_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint32_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const;
+
+ /// Extract a uint64_t value from \a *offset_ptr.
+ ///
+ /// Extract a single uint64_t from the binary data at the offset
+ /// pointed to by \a offset_ptr, and update the offset on success.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted uint64_t value.
+ uint64_t getU64(uint32_t *offset_ptr) const;
+
+ /// Extract \a count uint64_t values from \a *offset_ptr.
+ ///
+ /// Extract \a count uint64_t values from the binary data at the
+ /// offset pointed to by \a offset_ptr, and advance the offset on
+ /// success. The extracted values are copied into \a dst.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @param[out] dst
+ /// A buffer to copy \a count uint64_t values into. \a dst must
+ /// be large enough to hold all requested data.
+ ///
+ /// @param[in] count
+ /// The number of uint64_t values to extract.
+ ///
+ /// @return
+ /// \a dst if all values were properly extracted and copied,
+ /// NULL otherise.
+ uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const;
+
+ /// Extract a signed LEB128 value from \a *offset_ptr.
+ ///
+ /// Extracts an signed LEB128 number from this object's data
+ /// starting at the offset pointed to by \a offset_ptr. The offset
+ /// pointed to by \a offset_ptr will be updated with the offset of
+ /// the byte following the last extracted byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted signed integer value.
+ int64_t getSLEB128(uint32_t *offset_ptr) const;
+
+ /// Extract a unsigned LEB128 value from \a *offset_ptr.
+ ///
+ /// Extracts an unsigned LEB128 number from this object's data
+ /// starting at the offset pointed to by \a offset_ptr. The offset
+ /// pointed to by \a offset_ptr will be updated with the offset of
+ /// the byte following the last extracted byte.
+ ///
+ /// @param[in,out] offset_ptr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// @return
+ /// The extracted unsigned integer value.
+ uint64_t getULEB128(uint32_t *offset_ptr) const;
+
+ /// Test the validity of \a offset.
+ ///
+ /// @return
+ /// \b true if \a offset is a valid offset into the data in this
+ /// object, \b false otherwise.
+ bool isValidOffset(uint32_t offset) const { return Data.size() > offset; }
+
+ /// Test the availability of \a length bytes of data from \a offset.
+ ///
+ /// @return
+ /// \b true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, \b false otherwise.
+ bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
+ return offset + length >= offset && isValidOffset(offset + length - 1);
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/DataFlow.h b/contrib/llvm/include/llvm/Support/DataFlow.h
new file mode 100644
index 000000000000..355c402f542d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DataFlow.h
@@ -0,0 +1,103 @@
+//===-- llvm/Support/DataFlow.h - dataflow as graphs ------------*- 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 specializations of GraphTraits that allows Use-Def and
+// Def-Use relations to be treated as proper graphs for generic algorithms.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DATAFLOW_H
+#define LLVM_SUPPORT_DATAFLOW_H
+
+#include "llvm/User.h"
+#include "llvm/ADT/GraphTraits.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Provide specializations of GraphTraits to be able to treat def-use/use-def
+// chains as graphs
+
+template <> struct GraphTraits<const Value*> {
+ typedef const Value NodeType;
+ typedef Value::const_use_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const Value *G) {
+ return G;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->use_begin();
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->use_end();
+ }
+};
+
+template <> struct GraphTraits<Value*> {
+ typedef Value NodeType;
+ typedef Value::use_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Value *G) {
+ return G;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->use_begin();
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->use_end();
+ }
+};
+
+template <> struct GraphTraits<Inverse<const User*> > {
+ typedef const Value NodeType;
+ typedef User::const_op_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<const User*> G) {
+ return G.Graph;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ if (const User *U = dyn_cast<User>(N))
+ return U->op_begin();
+ return NULL;
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ if(const User *U = dyn_cast<User>(N))
+ return U->op_end();
+ return NULL;
+ }
+};
+
+template <> struct GraphTraits<Inverse<User*> > {
+ typedef Value NodeType;
+ typedef User::op_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Inverse<User*> G) {
+ return G.Graph;
+ }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ if (User *U = dyn_cast<User>(N))
+ return U->op_begin();
+ return NULL;
+ }
+
+ static inline ChildIteratorType child_end(NodeType *N) {
+ if (User *U = dyn_cast<User>(N))
+ return U->op_end();
+ return NULL;
+ }
+};
+
+}
+#endif
diff --git a/contrib/llvm/include/llvm/Support/DataStream.h b/contrib/llvm/include/llvm/Support/DataStream.h
new file mode 100644
index 000000000000..fedb0c925611
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DataStream.h
@@ -0,0 +1,38 @@
+//===---- llvm/Support/DataStream.h - Lazy bitcode streaming ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines DataStreamer, which fetches bytes of data from
+// a stream source. It provides support for streaming (lazy reading) of
+// data, e.g. bitcode
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_DATASTREAM_H_
+#define LLVM_SUPPORT_DATASTREAM_H_
+
+#include <string>
+
+namespace llvm {
+
+class DataStreamer {
+public:
+ /// Fetch bytes [start-end) from the stream, and write them to the
+ /// buffer pointed to by buf. Returns the number of bytes actually written.
+ virtual size_t GetBytes(unsigned char *buf, size_t len) = 0;
+
+ virtual ~DataStreamer();
+};
+
+DataStreamer *getDataFileStreamer(const std::string &Filename,
+ std::string *Err);
+
+}
+
+#endif // LLVM_SUPPORT_DATASTREAM_H_
diff --git a/contrib/llvm/include/llvm/Support/DataTypes.h.in b/contrib/llvm/include/llvm/Support/DataTypes.h.in
new file mode 100644
index 000000000000..b492bb14ba50
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DataTypes.h.in
@@ -0,0 +1,212 @@
+/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
+|* *|
+|* The LLVM Compiler Infrastructure *|
+|* *|
+|* This file is distributed under the University of Illinois Open Source *|
+|* License. See LICENSE.TXT for details. *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This file contains definitions to figure out the size of _HOST_ data types.*|
+|* This file is important because different host OS's define different macros,*|
+|* which makes portability tough. This file exports the following *|
+|* definitions: *|
+|* *|
+|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
+|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
+|* *|
+|* No library is required when using these functions. *|
+|* *|
+|*===----------------------------------------------------------------------===*/
+
+/* Please leave this file C-compatible. */
+
+/* Please keep this file in sync with DataTypes.h.cmake */
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#undef HAVE_SYS_TYPES_H
+#undef HAVE_INTTYPES_H
+#undef HAVE_STDINT_H
+#undef HAVE_UINT64_T
+#undef HAVE_U_INT64_T
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifndef _MSC_VER
+
+/* Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+ being defined. We would define it here, but in order to prevent Bad Things
+ happening when system headers or C++ STL headers include stdint.h before we
+ define it here, we define it on the g++ command line (in Makefile.rules). */
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+#if !defined(__STDC_CONSTANT_MACROS)
+# error "Must #define __STDC_CONSTANT_MACROS before " \
+ "#including Support/DataTypes.h"
+#endif
+
+/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+/* Handle incorrect definition of uint64_t as u_int64_t */
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+/* Visual C++ doesn't provide standard integer headers, but it does provide
+ built-in data types. */
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#ifndef INT8_MAX
+# define INT8_MAX 127
+#endif
+#ifndef INT8_MIN
+# define INT8_MIN -128
+#endif
+#ifndef UINT8_MAX
+# define UINT8_MAX 255
+#endif
+#ifndef INT16_MAX
+# define INT16_MAX 32767
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN -32768
+#endif
+#ifndef UINT16_MAX
+# define UINT16_MAX 65535
+#endif
+#ifndef INT32_MAX
+# define INT32_MAX 2147483647
+#endif
+#ifndef INT32_MIN
+/* MSC treats -2147483648 as -(2147483648U). */
+# define INT32_MIN (-INT32_MAX - 1)
+#endif
+#ifndef UINT32_MAX
+# define UINT32_MAX 4294967295U
+#endif
+/* Certain compatibility updates to VC++ introduce the `cstdint'
+ * header, which defines the INT*_C macros. On default installs they
+ * are absent. */
+#ifndef INT8_C
+# define INT8_C(C) C##i8
+#endif
+#ifndef UINT8_C
+# define UINT8_C(C) C##ui8
+#endif
+#ifndef INT16_C
+# define INT16_C(C) C##i16
+#endif
+#ifndef UINT16_C
+# define UINT16_C(C) C##ui16
+#endif
+#ifndef INT32_C
+# define INT32_C(C) C##i32
+#endif
+#ifndef UINT32_C
+# define UINT32_C(C) C##ui32
+#endif
+#ifndef INT64_C
+# define INT64_C(C) C##i64
+#endif
+#ifndef UINT64_C
+# define UINT64_C(C) C##ui64
+#endif
+
+#ifndef PRId64
+# define PRId64 "I64d"
+#endif
+#ifndef PRIi64
+# define PRIi64 "I64i"
+#endif
+#ifndef PRIo64
+# define PRIo64 "I64o"
+#endif
+#ifndef PRIu64
+# define PRIu64 "I64u"
+#endif
+#ifndef PRIx64
+# define PRIx64 "I64x"
+#endif
+#ifndef PRIX64
+# define PRIX64 "I64X"
+#endif
+
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/contrib/llvm/include/llvm/Support/Debug.h b/contrib/llvm/include/llvm/Support/Debug.h
new file mode 100644
index 000000000000..e72327271f23
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Debug.h
@@ -0,0 +1,101 @@
+//===- llvm/Support/Debug.h - Easy way to add debug output ------*- 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 handy way of adding debugging information to your
+// code, without it being enabled all of the time, and without having to add
+// command line options to enable it.
+//
+// In particular, just wrap your code with the DEBUG() macro, and it will be
+// enabled automatically if you specify '-debug' on the command-line.
+// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
+// that your debug code belongs to class "foo". Then, on the command line, you
+// can specify '-debug-only=foo' to enable JUST the debug information for the
+// foo class.
+//
+// When compiling without assertions, the -debug-* options and all code in
+// DEBUG() statements disappears, so it does not effect the runtime of the code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUG_H
+#define LLVM_SUPPORT_DEBUG_H
+
+namespace llvm {
+
+class raw_ostream;
+
+/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes
+/// all of their DEBUG statements to be activatable with -debug-only=thatstring.
+#ifndef DEBUG_TYPE
+#define DEBUG_TYPE ""
+#endif
+
+#ifndef NDEBUG
+/// DebugFlag - This boolean is set to true if the '-debug' command line option
+/// is specified. This should probably not be referenced directly, instead, use
+/// the DEBUG macro below.
+///
+extern bool DebugFlag;
+
+/// isCurrentDebugType - Return true if the specified string is the debug type
+/// specified on the command line, or if none was specified on the command line
+/// with the -debug-only=X option.
+///
+bool isCurrentDebugType(const char *Type);
+
+/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X
+/// option were specified. Note that DebugFlag also needs to be set to true for
+/// debug output to be produced.
+///
+void SetCurrentDebugType(const char *Type);
+
+/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
+/// information. In the '-debug' option is specified on the commandline, and if
+/// this is a debug build, then the code specified as the option to the macro
+/// will be executed. Otherwise it will not be. Example:
+///
+/// DEBUG_WITH_TYPE("bitset", dbgs() << "Bitset contains: " << Bitset << "\n");
+///
+/// This will emit the debug information if -debug is present, and -debug-only
+/// is not specified, or is specified as "bitset".
+#define DEBUG_WITH_TYPE(TYPE, X) \
+ do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \
+ } while (0)
+
+#else
+#define isCurrentDebugType(X) (false)
+#define SetCurrentDebugType(X)
+#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
+#endif
+
+/// EnableDebugBuffering - This defaults to false. If true, the debug
+/// stream will install signal handlers to dump any buffered debug
+/// output. It allows clients to selectively allow the debug stream
+/// to install signal handlers if they are certain there will be no
+/// conflict.
+///
+extern bool EnableDebugBuffering;
+
+/// dbgs() - This returns a reference to a raw_ostream for debugging
+/// messages. If debugging is disabled it returns errs(). Use it
+/// like: dbgs() << "foo" << "bar";
+raw_ostream &dbgs();
+
+// DEBUG macro - This macro should be used by passes to emit debug information.
+// In the '-debug' option is specified on the commandline, and if this is a
+// debug build, then the code specified as the option to the macro will be
+// executed. Otherwise it will not be. Example:
+//
+// DEBUG(dbgs() << "Bitset contains: " << Bitset << "\n");
+//
+#define DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/DebugLoc.h b/contrib/llvm/include/llvm/Support/DebugLoc.h
new file mode 100644
index 000000000000..2ee9f876c366
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DebugLoc.h
@@ -0,0 +1,113 @@
+//===---- llvm/Support/DebugLoc.h - Debug Location Information --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a number of light weight data structures used
+// to describe and track debug location information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUGLOC_H
+#define LLVM_SUPPORT_DEBUGLOC_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+
+namespace llvm {
+ class MDNode;
+ class LLVMContext;
+
+ /// DebugLoc - Debug location id. This is carried by Instruction, SDNode,
+ /// and MachineInstr to compactly encode file/line/scope information for an
+ /// operation.
+ class DebugLoc {
+ friend struct DenseMapInfo<DebugLoc>;
+
+ /// getEmptyKey() - A private constructor that returns an unknown that is
+ /// not equal to the tombstone key or DebugLoc().
+ static DebugLoc getEmptyKey() {
+ DebugLoc DL;
+ DL.LineCol = 1;
+ return DL;
+ }
+
+ /// getTombstoneKey() - A private constructor that returns an unknown that
+ /// is not equal to the empty key or DebugLoc().
+ static DebugLoc getTombstoneKey() {
+ DebugLoc DL;
+ DL.LineCol = 2;
+ return DL;
+ }
+
+ /// LineCol - This 32-bit value encodes the line and column number for the
+ /// location, encoded as 24-bits for line and 8 bits for col. A value of 0
+ /// for either means unknown.
+ unsigned LineCol;
+
+ /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,
+ /// decoded by LLVMContext. 0 is unknown.
+ int ScopeIdx;
+ public:
+ DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown.
+
+ /// get - Get a new DebugLoc that corresponds to the specified line/col
+ /// scope/inline location.
+ static DebugLoc get(unsigned Line, unsigned Col,
+ MDNode *Scope, MDNode *InlinedAt = 0);
+
+ /// getFromDILocation - Translate the DILocation quad into a DebugLoc.
+ static DebugLoc getFromDILocation(MDNode *N);
+
+ /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc.
+ static DebugLoc getFromDILexicalBlock(MDNode *N);
+
+ /// isUnknown - Return true if this is an unknown location.
+ bool isUnknown() const { return ScopeIdx == 0; }
+
+ unsigned getLine() const {
+ return (LineCol << 8) >> 8; // Mask out column.
+ }
+
+ unsigned getCol() const {
+ return LineCol >> 24;
+ }
+
+ /// getScope - This returns the scope pointer for this DebugLoc, or null if
+ /// invalid.
+ MDNode *getScope(const LLVMContext &Ctx) const;
+
+ /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or
+ /// null if invalid or not present.
+ MDNode *getInlinedAt(const LLVMContext &Ctx) const;
+
+ /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.
+ void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
+ const LLVMContext &Ctx) const;
+
+
+ /// getAsMDNode - This method converts the compressed DebugLoc node into a
+ /// DILocation compatible MDNode.
+ MDNode *getAsMDNode(const LLVMContext &Ctx) const;
+
+ bool operator==(const DebugLoc &DL) const {
+ return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;
+ }
+ bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }
+
+ void dump(const LLVMContext &Ctx) const;
+ };
+
+ template <>
+ struct DenseMapInfo<DebugLoc> {
+ static DebugLoc getEmptyKey();
+ static DebugLoc getTombstoneKey();
+ static unsigned getHashValue(const DebugLoc &Key);
+ static bool isEqual(const DebugLoc &LHS, const DebugLoc &RHS);
+ };
+} // end namespace llvm
+
+#endif /* LLVM_DEBUGLOC_H */
diff --git a/contrib/llvm/include/llvm/Support/Disassembler.h b/contrib/llvm/include/llvm/Support/Disassembler.h
new file mode 100644
index 000000000000..6d1cc0fdcb50
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Disassembler.h
@@ -0,0 +1,35 @@
+//===- llvm/Support/Disassembler.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 implements the necessary glue to call external disassembler
+// libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DISASSEMBLER_H
+#define LLVM_SYSTEM_DISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// This function returns true, if there is possible to use some external
+/// disassembler library. False otherwise.
+bool hasDisassembler();
+
+/// This function provides some "glue" code to call external disassembler
+/// libraries.
+std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0);
+
+}
+}
+
+#endif // LLVM_SYSTEM_DISASSEMBLER_H
diff --git a/contrib/llvm/include/llvm/Support/Dwarf.h b/contrib/llvm/include/llvm/Support/Dwarf.h
new file mode 100644
index 000000000000..8f18a991a9e1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Dwarf.h
@@ -0,0 +1,740 @@
+//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants used for implementing Dwarf debug support. For
+// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
+// V.3 reference manual http://dwarf.freestandards.org ,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DWARF_H
+#define LLVM_SUPPORT_DWARF_H
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Debug info constants.
+
+enum {
+ LLVMDebugVersion = (12 << 16), // Current version of debug information.
+ LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
+ LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
+ LLVMDebugVersion9 = (9 << 16), // Constant for version 9.
+ LLVMDebugVersion8 = (8 << 16), // Constant for version 8.
+ LLVMDebugVersion7 = (7 << 16), // Constant for version 7.
+ LLVMDebugVersion6 = (6 << 16), // Constant for version 6.
+ LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
+ LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
+ LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+};
+
+namespace dwarf {
+
+//===----------------------------------------------------------------------===//
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
+// reference manual http://dwarf.freestandards.org .
+//
+
+// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
+// enumeration base type.
+
+enum llvm_dwarf_constants {
+ // llvm mock tags
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
+
+ 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.
+
+ DW_CIE_VERSION = 1, // Common frame information version.
+ DW_CIE_ID = 0xffffffff // Common frame information mark.
+};
+
+enum dwarf_constants {
+ DWARF_VERSION = 2,
+
+ // Tags
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_parameter = 0x2f,
+ DW_TAG_template_value_parameter = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ DW_TAG_dwarf_procedure = 0x36,
+ DW_TAG_restrict_type = 0x37,
+ DW_TAG_interface_type = 0x38,
+ DW_TAG_namespace = 0x39,
+ DW_TAG_imported_module = 0x3a,
+ DW_TAG_unspecified_type = 0x3b,
+ DW_TAG_partial_unit = 0x3c,
+ DW_TAG_imported_unit = 0x3d,
+ DW_TAG_condition = 0x3f,
+ DW_TAG_shared_type = 0x40,
+ DW_TAG_type_unit = 0x41,
+ DW_TAG_rvalue_reference_type = 0x42,
+ DW_TAG_template_alias = 0x43,
+ DW_TAG_MIPS_loop = 0x4081,
+ DW_TAG_format_label = 0x4101,
+ DW_TAG_function_template = 0x4102,
+ DW_TAG_class_template = 0x4103,
+ DW_TAG_GNU_template_template_param = 0x4106,
+ DW_TAG_GNU_template_parameter_pack = 0x4107,
+ DW_TAG_GNU_formal_parameter_pack = 0x4108,
+ DW_TAG_lo_user = 0x4080,
+ DW_TAG_APPLE_property = 0x4200,
+ DW_TAG_hi_user = 0xffff,
+
+ // Children flag
+ DW_CHILDREN_no = 0x00,
+ DW_CHILDREN_yes = 0x01,
+
+ // Attributes
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_bit_stride = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_item = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ DW_AT_allocated = 0x4e,
+ DW_AT_associated = 0x4f,
+ DW_AT_data_location = 0x50,
+ DW_AT_byte_stride = 0x51,
+ DW_AT_entry_pc = 0x52,
+ DW_AT_use_UTF8 = 0x53,
+ DW_AT_extension = 0x54,
+ DW_AT_ranges = 0x55,
+ DW_AT_trampoline = 0x56,
+ DW_AT_call_column = 0x57,
+ DW_AT_call_file = 0x58,
+ DW_AT_call_line = 0x59,
+ DW_AT_description = 0x5a,
+ DW_AT_binary_scale = 0x5b,
+ DW_AT_decimal_scale = 0x5c,
+ DW_AT_small = 0x5d,
+ DW_AT_decimal_sign = 0x5e,
+ DW_AT_digit_count = 0x5f,
+ DW_AT_picture_string = 0x60,
+ DW_AT_mutable = 0x61,
+ DW_AT_threads_scaled = 0x62,
+ DW_AT_explicit = 0x63,
+ DW_AT_object_pointer = 0x64,
+ DW_AT_endianity = 0x65,
+ DW_AT_elemental = 0x66,
+ DW_AT_pure = 0x67,
+ DW_AT_recursive = 0x68,
+ DW_AT_signature = 0x69,
+ DW_AT_main_subprogram = 0x6a,
+ DW_AT_data_bit_offset = 0x6b,
+ DW_AT_const_expr = 0x6c,
+ DW_AT_enum_class = 0x6d,
+ DW_AT_linkage_name = 0x6e,
+ DW_AT_MIPS_loop_begin = 0x2002,
+ DW_AT_MIPS_tail_loop_begin = 0x2003,
+ DW_AT_MIPS_epilog_begin = 0x2004,
+ DW_AT_MIPS_loop_unroll_factor = 0x2005,
+ DW_AT_MIPS_software_pipeline_depth = 0x2006,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_MIPS_stride = 0x2008,
+ DW_AT_MIPS_abstract_name = 0x2009,
+ DW_AT_MIPS_clone_origin = 0x200a,
+ DW_AT_MIPS_has_inlines = 0x200b,
+ DW_AT_MIPS_stride_byte = 0x200c,
+ DW_AT_MIPS_stride_elem = 0x200d,
+ DW_AT_MIPS_ptr_dopetype = 0x200e,
+ DW_AT_MIPS_allocatable_dopetype = 0x200f,
+ DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ 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,
+
+ // Apple extensions.
+ DW_AT_APPLE_optimized = 0x3fe1,
+ DW_AT_APPLE_flags = 0x3fe2,
+ DW_AT_APPLE_isa = 0x3fe3,
+ DW_AT_APPLE_block = 0x3fe4,
+ DW_AT_APPLE_major_runtime_vers = 0x3fe5,
+ DW_AT_APPLE_runtime_class = 0x3fe6,
+ DW_AT_APPLE_omit_frame_ptr = 0x3fe7,
+ DW_AT_APPLE_property_name = 0x3fe8,
+ DW_AT_APPLE_property_getter = 0x3fe9,
+ DW_AT_APPLE_property_setter = 0x3fea,
+ DW_AT_APPLE_property_attribute = 0x3feb,
+ DW_AT_APPLE_objc_complete_type = 0x3fec,
+ DW_AT_APPLE_property = 0x3fed,
+
+ // Attribute form encodings
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16,
+ DW_FORM_sec_offset = 0x17,
+ DW_FORM_exprloc = 0x18,
+ DW_FORM_flag_present = 0x19,
+ DW_FORM_ref_sig8 = 0x20,
+
+ // Operation encodings
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_skip = 0x2f,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit2 = 0x32,
+ DW_OP_lit3 = 0x33,
+ DW_OP_lit4 = 0x34,
+ DW_OP_lit5 = 0x35,
+ DW_OP_lit6 = 0x36,
+ DW_OP_lit7 = 0x37,
+ DW_OP_lit8 = 0x38,
+ DW_OP_lit9 = 0x39,
+ DW_OP_lit10 = 0x3a,
+ DW_OP_lit11 = 0x3b,
+ DW_OP_lit12 = 0x3c,
+ DW_OP_lit13 = 0x3d,
+ DW_OP_lit14 = 0x3e,
+ DW_OP_lit15 = 0x3f,
+ DW_OP_lit16 = 0x40,
+ DW_OP_lit17 = 0x41,
+ DW_OP_lit18 = 0x42,
+ DW_OP_lit19 = 0x43,
+ DW_OP_lit20 = 0x44,
+ DW_OP_lit21 = 0x45,
+ DW_OP_lit22 = 0x46,
+ DW_OP_lit23 = 0x47,
+ DW_OP_lit24 = 0x48,
+ DW_OP_lit25 = 0x49,
+ DW_OP_lit26 = 0x4a,
+ DW_OP_lit27 = 0x4b,
+ DW_OP_lit28 = 0x4c,
+ DW_OP_lit29 = 0x4d,
+ DW_OP_lit30 = 0x4e,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg2 = 0x52,
+ DW_OP_reg3 = 0x53,
+ DW_OP_reg4 = 0x54,
+ DW_OP_reg5 = 0x55,
+ DW_OP_reg6 = 0x56,
+ DW_OP_reg7 = 0x57,
+ DW_OP_reg8 = 0x58,
+ DW_OP_reg9 = 0x59,
+ DW_OP_reg10 = 0x5a,
+ DW_OP_reg11 = 0x5b,
+ DW_OP_reg12 = 0x5c,
+ DW_OP_reg13 = 0x5d,
+ DW_OP_reg14 = 0x5e,
+ DW_OP_reg15 = 0x5f,
+ DW_OP_reg16 = 0x60,
+ DW_OP_reg17 = 0x61,
+ DW_OP_reg18 = 0x62,
+ DW_OP_reg19 = 0x63,
+ DW_OP_reg20 = 0x64,
+ DW_OP_reg21 = 0x65,
+ DW_OP_reg22 = 0x66,
+ DW_OP_reg23 = 0x67,
+ DW_OP_reg24 = 0x68,
+ DW_OP_reg25 = 0x69,
+ DW_OP_reg26 = 0x6a,
+ DW_OP_reg27 = 0x6b,
+ DW_OP_reg28 = 0x6c,
+ DW_OP_reg29 = 0x6d,
+ DW_OP_reg30 = 0x6e,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg2 = 0x72,
+ DW_OP_breg3 = 0x73,
+ DW_OP_breg4 = 0x74,
+ DW_OP_breg5 = 0x75,
+ DW_OP_breg6 = 0x76,
+ DW_OP_breg7 = 0x77,
+ DW_OP_breg8 = 0x78,
+ DW_OP_breg9 = 0x79,
+ DW_OP_breg10 = 0x7a,
+ DW_OP_breg11 = 0x7b,
+ DW_OP_breg12 = 0x7c,
+ DW_OP_breg13 = 0x7d,
+ DW_OP_breg14 = 0x7e,
+ DW_OP_breg15 = 0x7f,
+ DW_OP_breg16 = 0x80,
+ DW_OP_breg17 = 0x81,
+ DW_OP_breg18 = 0x82,
+ DW_OP_breg19 = 0x83,
+ DW_OP_breg20 = 0x84,
+ DW_OP_breg21 = 0x85,
+ DW_OP_breg22 = 0x86,
+ DW_OP_breg23 = 0x87,
+ DW_OP_breg24 = 0x88,
+ DW_OP_breg25 = 0x89,
+ DW_OP_breg26 = 0x8a,
+ DW_OP_breg27 = 0x8b,
+ DW_OP_breg28 = 0x8c,
+ DW_OP_breg29 = 0x8d,
+ DW_OP_breg30 = 0x8e,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96,
+ DW_OP_push_object_address = 0x97,
+ DW_OP_call2 = 0x98,
+ DW_OP_call4 = 0x99,
+ DW_OP_call_ref = 0x9a,
+ DW_OP_form_tls_address = 0x9b,
+ DW_OP_call_frame_cfa = 0x9c,
+ DW_OP_bit_piece = 0x9d,
+ DW_OP_implicit_value = 0x9e,
+ DW_OP_stack_value = 0x9f,
+ DW_OP_lo_user = 0xe0,
+ DW_OP_hi_user = 0xff,
+
+ // Encoding attribute values
+ DW_ATE_address = 0x01,
+ DW_ATE_boolean = 0x02,
+ DW_ATE_complex_float = 0x03,
+ DW_ATE_float = 0x04,
+ DW_ATE_signed = 0x05,
+ DW_ATE_signed_char = 0x06,
+ DW_ATE_unsigned = 0x07,
+ DW_ATE_unsigned_char = 0x08,
+ DW_ATE_imaginary_float = 0x09,
+ DW_ATE_packed_decimal = 0x0a,
+ DW_ATE_numeric_string = 0x0b,
+ DW_ATE_edited = 0x0c,
+ DW_ATE_signed_fixed = 0x0d,
+ DW_ATE_unsigned_fixed = 0x0e,
+ DW_ATE_decimal_float = 0x0f,
+ DW_ATE_UTF = 0x10,
+ DW_ATE_lo_user = 0x80,
+ DW_ATE_hi_user = 0xff,
+
+ // Decimal sign attribute values
+ DW_DS_unsigned = 0x01,
+ DW_DS_leading_overpunch = 0x02,
+ DW_DS_trailing_overpunch = 0x03,
+ DW_DS_leading_separate = 0x04,
+ DW_DS_trailing_separate = 0x05,
+
+ // Endianity attribute values
+ DW_END_default = 0x00,
+ DW_END_big = 0x01,
+ DW_END_little = 0x02,
+ DW_END_lo_user = 0x40,
+ DW_END_hi_user = 0xff,
+
+ // Accessibility codes
+ DW_ACCESS_public = 0x01,
+ DW_ACCESS_protected = 0x02,
+ DW_ACCESS_private = 0x03,
+
+ // Visibility codes
+ DW_VIS_local = 0x01,
+ DW_VIS_exported = 0x02,
+ DW_VIS_qualified = 0x03,
+
+ // Virtuality codes
+ DW_VIRTUALITY_none = 0x00,
+ DW_VIRTUALITY_virtual = 0x01,
+ DW_VIRTUALITY_pure_virtual = 0x02,
+
+ // Language names
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Java = 0x000b,
+ DW_LANG_C99 = 0x000c,
+ DW_LANG_Ada95 = 0x000d,
+ DW_LANG_Fortran95 = 0x000e,
+ DW_LANG_PLI = 0x000f,
+ DW_LANG_ObjC = 0x0010,
+ DW_LANG_ObjC_plus_plus = 0x0011,
+ DW_LANG_UPC = 0x0012,
+ DW_LANG_D = 0x0013,
+ DW_LANG_Python = 0x0014,
+ DW_LANG_lo_user = 0x8000,
+ DW_LANG_Mips_Assembler = 0x8001,
+ DW_LANG_hi_user = 0xffff,
+
+ // Identifier case codes
+ DW_ID_case_sensitive = 0x00,
+ DW_ID_up_case = 0x01,
+ DW_ID_down_case = 0x02,
+ DW_ID_case_insensitive = 0x03,
+
+ // Calling convention codes
+ DW_CC_normal = 0x01,
+ DW_CC_program = 0x02,
+ DW_CC_nocall = 0x03,
+ DW_CC_lo_user = 0x40,
+ DW_CC_hi_user = 0xff,
+
+ // Inline codes
+ DW_INL_not_inlined = 0x00,
+ DW_INL_inlined = 0x01,
+ DW_INL_declared_not_inlined = 0x02,
+ DW_INL_declared_inlined = 0x03,
+
+ // Array ordering
+ DW_ORD_row_major = 0x00,
+ DW_ORD_col_major = 0x01,
+
+ // Discriminant descriptor values
+ DW_DSC_label = 0x00,
+ DW_DSC_range = 0x01,
+
+ // Line Number Standard Opcode Encodings
+ DW_LNS_extended_op = 0x00,
+ DW_LNS_copy = 0x01,
+ DW_LNS_advance_pc = 0x02,
+ DW_LNS_advance_line = 0x03,
+ DW_LNS_set_file = 0x04,
+ DW_LNS_set_column = 0x05,
+ DW_LNS_negate_stmt = 0x06,
+ DW_LNS_set_basic_block = 0x07,
+ DW_LNS_const_add_pc = 0x08,
+ DW_LNS_fixed_advance_pc = 0x09,
+ DW_LNS_set_prologue_end = 0x0a,
+ DW_LNS_set_epilogue_begin = 0x0b,
+ DW_LNS_set_isa = 0x0c,
+
+ // Line Number Extended Opcode Encodings
+ DW_LNE_end_sequence = 0x01,
+ DW_LNE_set_address = 0x02,
+ DW_LNE_define_file = 0x03,
+ DW_LNE_set_discriminator = 0x04,
+ DW_LNE_lo_user = 0x80,
+ DW_LNE_hi_user = 0xff,
+
+ // Macinfo Type Encodings
+ DW_MACINFO_define = 0x01,
+ DW_MACINFO_undef = 0x02,
+ DW_MACINFO_start_file = 0x03,
+ DW_MACINFO_end_file = 0x04,
+ DW_MACINFO_vendor_ext = 0xff,
+
+ // Call frame instruction encodings
+ DW_CFA_extended = 0x00,
+ DW_CFA_nop = 0x00,
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_def_cfa_expression = 0x0f,
+ DW_CFA_expression = 0x10,
+ DW_CFA_offset_extended_sf = 0x11,
+ DW_CFA_def_cfa_sf = 0x12,
+ DW_CFA_def_cfa_offset_sf = 0x13,
+ DW_CFA_val_offset = 0x14,
+ DW_CFA_val_offset_sf = 0x15,
+ DW_CFA_val_expression = 0x16,
+ DW_CFA_MIPS_advance_loc8 = 0x1d,
+ DW_CFA_GNU_window_save = 0x2d,
+ DW_CFA_GNU_args_size = 0x2e,
+ DW_CFA_lo_user = 0x1c,
+ DW_CFA_hi_user = 0x3f,
+
+ DW_EH_PE_absptr = 0x00,
+ DW_EH_PE_omit = 0xff,
+ DW_EH_PE_uleb128 = 0x01,
+ DW_EH_PE_udata2 = 0x02,
+ DW_EH_PE_udata4 = 0x03,
+ DW_EH_PE_udata8 = 0x04,
+ DW_EH_PE_sleb128 = 0x09,
+ DW_EH_PE_sdata2 = 0x0A,
+ DW_EH_PE_sdata4 = 0x0B,
+ DW_EH_PE_sdata8 = 0x0C,
+ DW_EH_PE_signed = 0x08,
+ DW_EH_PE_pcrel = 0x10,
+ DW_EH_PE_textrel = 0x20,
+ DW_EH_PE_datarel = 0x30,
+ DW_EH_PE_funcrel = 0x40,
+ DW_EH_PE_aligned = 0x50,
+ DW_EH_PE_indirect = 0x80,
+
+ // Apple Objective-C Property Attributes
+ DW_APPLE_PROPERTY_readonly = 0x01,
+ DW_APPLE_PROPERTY_readwrite = 0x02,
+ DW_APPLE_PROPERTY_assign = 0x04,
+ DW_APPLE_PROPERTY_retain = 0x08,
+ DW_APPLE_PROPERTY_copy = 0x10,
+ DW_APPLE_PROPERTY_nonatomic = 0x20
+};
+
+/// TagString - Return the string for the specified tag.
+///
+const char *TagString(unsigned Tag);
+
+/// ChildrenString - Return the string for the specified children flag.
+///
+const char *ChildrenString(unsigned Children);
+
+/// AttributeString - Return the string for the specified attribute.
+///
+const char *AttributeString(unsigned Attribute);
+
+/// FormEncodingString - Return the string for the specified form encoding.
+///
+const char *FormEncodingString(unsigned Encoding);
+
+/// OperationEncodingString - Return the string for the specified operation
+/// encoding.
+const char *OperationEncodingString(unsigned Encoding);
+
+/// AttributeEncodingString - Return the string for the specified attribute
+/// encoding.
+const char *AttributeEncodingString(unsigned Encoding);
+
+/// DecimalSignString - Return the string for the specified decimal sign
+/// attribute.
+const char *DecimalSignString(unsigned Sign);
+
+/// EndianityString - Return the string for the specified endianity.
+///
+const char *EndianityString(unsigned Endian);
+
+/// AccessibilityString - Return the string for the specified accessibility.
+///
+const char *AccessibilityString(unsigned Access);
+
+/// VisibilityString - Return the string for the specified visibility.
+///
+const char *VisibilityString(unsigned Visibility);
+
+/// VirtualityString - Return the string for the specified virtuality.
+///
+const char *VirtualityString(unsigned Virtuality);
+
+/// LanguageString - Return the string for the specified language.
+///
+const char *LanguageString(unsigned Language);
+
+/// CaseString - Return the string for the specified identifier case.
+///
+const char *CaseString(unsigned Case);
+
+/// ConventionString - Return the string for the specified calling convention.
+///
+const char *ConventionString(unsigned Convention);
+
+/// InlineCodeString - Return the string for the specified inline code.
+///
+const char *InlineCodeString(unsigned Code);
+
+/// ArrayOrderString - Return the string for the specified array order.
+///
+const char *ArrayOrderString(unsigned Order);
+
+/// DiscriminantString - Return the string for the specified discriminant
+/// descriptor.
+const char *DiscriminantString(unsigned Discriminant);
+
+/// LNStandardString - Return the string for the specified line number standard.
+///
+const char *LNStandardString(unsigned Standard);
+
+/// LNExtendedString - Return the string for the specified line number extended
+/// opcode encodings.
+const char *LNExtendedString(unsigned Encoding);
+
+/// MacinfoString - Return the string for the specified macinfo type encodings.
+///
+const char *MacinfoString(unsigned Encoding);
+
+/// CallFrameString - Return the string for the specified call frame instruction
+/// encodings.
+const char *CallFrameString(unsigned Encoding);
+} // End of namespace dwarf
+
+} // End of namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/DynamicLibrary.h b/contrib/llvm/include/llvm/Support/DynamicLibrary.h
new file mode 100644
index 000000000000..0f59cbf23947
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/DynamicLibrary.h
@@ -0,0 +1,104 @@
+//===-- llvm/Support/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the sys::DynamicLibrary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+
+#include <string>
+
+namespace llvm {
+
+class StringRef;
+
+namespace sys {
+
+ /// This class provides a portable interface to dynamic libraries which also
+ /// might be known as shared libraries, shared objects, dynamic shared
+ /// objects, or dynamic link libraries. Regardless of the terminology or the
+ /// operating system interface, this class provides a portable interface that
+ /// allows dynamic libraries to be loaded and searched for externally
+ /// defined symbols. This is typically used to provide "plug-in" support.
+ /// It also allows for symbols to be defined which don't live in any library,
+ /// but rather the main program itself, useful on Windows where the main
+ /// executable cannot be searched.
+ ///
+ /// Note: there is currently no interface for temporarily loading a library,
+ /// or for unloading libraries when the LLVM library is unloaded.
+ class DynamicLibrary {
+ // Placeholder whose address represents an invalid library.
+ // We use this instead of NULL or a pointer-int pair because the OS library
+ // might define 0 or 1 to be "special" handles, such as "search all".
+ static char Invalid;
+
+ // Opaque data used to interface with OS-specific dynamic library handling.
+ void *Data;
+
+ explicit DynamicLibrary(void *data = &Invalid) : Data(data) {}
+ public:
+ /// Returns true if the object refers to a valid library.
+ bool isValid() { return Data != &Invalid; }
+
+ /// Searches through the library for the symbol \p symbolName. If it is
+ /// found, the address of that symbol is returned. If not, NULL is returned.
+ /// Note that NULL will also be returned if the library failed to load.
+ /// Use isValid() to distinguish these cases if it is important.
+ /// Note that this will \e not search symbols explicitly registered by
+ /// AddSymbol().
+ void *getAddressOfSymbol(const char *symbolName);
+
+ /// This function permanently loads the dynamic library at the given path.
+ /// The library will only be unloaded when the program terminates.
+ /// This returns a valid DynamicLibrary instance on success and an invalid
+ /// instance on failure (see isValid()). \p *errMsg will only be modified
+ /// if the library fails to load.
+ ///
+ /// It is safe to call this function multiple times for the same library.
+ /// @brief Open a dynamic library permanently.
+ static DynamicLibrary getPermanentLibrary(const char *filename,
+ std::string *errMsg = 0);
+
+ /// This function permanently loads the dynamic library at the given path.
+ /// Use this instead of getPermanentLibrary() when you won't need to get
+ /// symbols from the library itself.
+ ///
+ /// It is safe to call this function multiple times for the same library.
+ static bool LoadLibraryPermanently(const char *Filename,
+ std::string *ErrMsg = 0) {
+ return !getPermanentLibrary(Filename, ErrMsg).isValid();
+ }
+
+ /// This function will search through all previously loaded dynamic
+ /// libraries for the symbol \p symbolName. If it is found, the address of
+ /// that symbol is returned. If not, null is returned. Note that this will
+ /// search permanently loaded libraries (getPermanentLibrary()) as well
+ /// as explicitly registered symbols (AddSymbol()).
+ /// @throws std::string on error.
+ /// @brief Search through libraries for address of a symbol
+ static void *SearchForAddressOfSymbol(const char *symbolName);
+
+ /// @brief Convenience function for C++ophiles.
+ static void *SearchForAddressOfSymbol(const std::string &symbolName) {
+ return SearchForAddressOfSymbol(symbolName.c_str());
+ }
+
+ /// This functions permanently adds the symbol \p symbolName with the
+ /// value \p symbolValue. These symbols are searched before any
+ /// libraries.
+ /// @brief Add searchable symbol/value pair.
+ static void AddSymbol(StringRef symbolName, void *symbolValue);
+ };
+
+} // End sys namespace
+} // End llvm namespace
+
+#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
diff --git a/contrib/llvm/include/llvm/Support/ELF.h b/contrib/llvm/include/llvm/Support/ELF.h
new file mode 100644
index 000000000000..04953b6e5657
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ELF.h
@@ -0,0 +1,1141 @@
+//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains common, non-processor-specific data structures and
+// constants for the ELF file format.
+//
+// The details of the ELF32 bits in this file are largely based on the Tool
+// Interface Standard (TIS) Executable and Linking Format (ELF) Specification
+// Version 1.2, May 1995. The ELF64 stuff is based on ELF-64 Object File Format
+// Version 1.5, Draft 2, May 1998 as well as OpenBSD header files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELF_H
+#define LLVM_SUPPORT_ELF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+
+namespace llvm {
+
+namespace ELF {
+
+typedef uint32_t Elf32_Addr; // Program address
+typedef uint32_t Elf32_Off; // File offset
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+typedef uint16_t Elf64_Half;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+// Object file magic string.
+static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
+
+// e_ident size and indices.
+enum {
+ EI_MAG0 = 0, // File identification index.
+ EI_MAG1 = 1, // File identification index.
+ EI_MAG2 = 2, // File identification index.
+ EI_MAG3 = 3, // File identification index.
+ EI_CLASS = 4, // File class.
+ EI_DATA = 5, // Data encoding.
+ EI_VERSION = 6, // File version.
+ EI_OSABI = 7, // OS/ABI identification.
+ EI_ABIVERSION = 8, // ABI version.
+ EI_PAD = 9, // Start of padding bytes.
+ EI_NIDENT = 16 // Number of bytes in e_ident.
+};
+
+struct Elf32_Ehdr {
+ unsigned char e_ident[EI_NIDENT]; // ELF Identification bytes
+ Elf32_Half e_type; // Type of file (see ET_* below)
+ Elf32_Half e_machine; // Required architecture for this file (see EM_*)
+ Elf32_Word e_version; // Must be equal to 1
+ Elf32_Addr e_entry; // Address to jump to in order to start program
+ Elf32_Off e_phoff; // Program header table's file offset, in bytes
+ Elf32_Off e_shoff; // Section header table's file offset, in bytes
+ Elf32_Word e_flags; // Processor-specific flags
+ Elf32_Half e_ehsize; // Size of ELF header, in bytes
+ Elf32_Half e_phentsize; // Size of an entry in the program header table
+ Elf32_Half e_phnum; // Number of entries in the program header table
+ Elf32_Half e_shentsize; // Size of an entry in the section header table
+ Elf32_Half e_shnum; // Number of entries in the section header table
+ Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
+ bool checkMagic() const {
+ return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
+ }
+ unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
+ unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
+};
+
+// 64-bit ELF header. Fields are the same as for ELF32, but with different
+// types (see above).
+struct Elf64_Ehdr {
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+ bool checkMagic() const {
+ return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
+ }
+ unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
+ unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
+};
+
+// File types
+enum {
+ ET_NONE = 0, // No file type
+ ET_REL = 1, // Relocatable file
+ ET_EXEC = 2, // Executable file
+ ET_DYN = 3, // Shared object file
+ ET_CORE = 4, // Core file
+ ET_LOPROC = 0xff00, // Beginning of processor-specific codes
+ ET_HIPROC = 0xffff // Processor-specific
+};
+
+// Versioning
+enum {
+ EV_NONE = 0,
+ EV_CURRENT = 1
+};
+
+// Machine architectures
+enum {
+ 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_S370 = 9, // IBM System/370
+ EM_MIPS_RS3_LE = 10, // MIPS RS3000 Little-endian
+ EM_PARISC = 15, // Hewlett-Packard PA-RISC
+ EM_VPP500 = 17, // Fujitsu VPP500
+ EM_SPARC32PLUS = 18, // Enhanced instruction set SPARC
+ EM_960 = 19, // Intel 80960
+ EM_PPC = 20, // PowerPC
+ EM_PPC64 = 21, // PowerPC64
+ EM_S390 = 22, // IBM System/390
+ EM_SPU = 23, // IBM SPU/SPC
+ EM_V800 = 36, // NEC V800
+ EM_FR20 = 37, // Fujitsu FR20
+ EM_RH32 = 38, // TRW RH-32
+ EM_RCE = 39, // Motorola RCE
+ EM_ARM = 40, // ARM
+ EM_ALPHA = 41, // DEC Alpha
+ EM_SH = 42, // Hitachi SH
+ EM_SPARCV9 = 43, // SPARC V9
+ EM_TRICORE = 44, // Siemens TriCore
+ EM_ARC = 45, // Argonaut RISC Core
+ EM_H8_300 = 46, // Hitachi H8/300
+ EM_H8_300H = 47, // Hitachi H8/300H
+ EM_H8S = 48, // Hitachi H8S
+ EM_H8_500 = 49, // Hitachi H8/500
+ EM_IA_64 = 50, // Intel IA-64 processor architecture
+ EM_MIPS_X = 51, // Stanford MIPS-X
+ EM_COLDFIRE = 52, // Motorola ColdFire
+ EM_68HC12 = 53, // Motorola M68HC12
+ EM_MMA = 54, // Fujitsu MMA Multimedia Accelerator
+ EM_PCP = 55, // Siemens PCP
+ EM_NCPU = 56, // Sony nCPU embedded RISC processor
+ EM_NDR1 = 57, // Denso NDR1 microprocessor
+ EM_STARCORE = 58, // Motorola Star*Core processor
+ EM_ME16 = 59, // Toyota ME16 processor
+ EM_ST100 = 60, // STMicroelectronics ST100 processor
+ EM_TINYJ = 61, // Advanced Logic Corp. TinyJ embedded processor family
+ EM_X86_64 = 62, // AMD x86-64 architecture
+ EM_PDSP = 63, // Sony DSP Processor
+ EM_PDP10 = 64, // Digital Equipment Corp. PDP-10
+ EM_PDP11 = 65, // Digital Equipment Corp. PDP-11
+ EM_FX66 = 66, // Siemens FX66 microcontroller
+ EM_ST9PLUS = 67, // STMicroelectronics ST9+ 8/16 bit microcontroller
+ EM_ST7 = 68, // STMicroelectronics ST7 8-bit microcontroller
+ EM_68HC16 = 69, // Motorola MC68HC16 Microcontroller
+ EM_68HC11 = 70, // Motorola MC68HC11 Microcontroller
+ EM_68HC08 = 71, // Motorola MC68HC08 Microcontroller
+ EM_68HC05 = 72, // Motorola MC68HC05 Microcontroller
+ EM_SVX = 73, // Silicon Graphics SVx
+ EM_ST19 = 74, // STMicroelectronics ST19 8-bit microcontroller
+ EM_VAX = 75, // Digital VAX
+ EM_CRIS = 76, // Axis Communications 32-bit embedded processor
+ EM_JAVELIN = 77, // Infineon Technologies 32-bit embedded processor
+ EM_FIREPATH = 78, // Element 14 64-bit DSP Processor
+ EM_ZSP = 79, // LSI Logic 16-bit DSP Processor
+ EM_MMIX = 80, // Donald Knuth's educational 64-bit processor
+ EM_HUANY = 81, // Harvard University machine-independent object files
+ EM_PRISM = 82, // SiTera Prism
+ EM_AVR = 83, // Atmel AVR 8-bit microcontroller
+ EM_FR30 = 84, // Fujitsu FR30
+ EM_D10V = 85, // Mitsubishi D10V
+ EM_D30V = 86, // Mitsubishi D30V
+ EM_V850 = 87, // NEC v850
+ EM_M32R = 88, // Mitsubishi M32R
+ EM_MN10300 = 89, // Matsushita MN10300
+ EM_MN10200 = 90, // Matsushita MN10200
+ EM_PJ = 91, // picoJava
+ EM_OPENRISC = 92, // OpenRISC 32-bit embedded processor
+ EM_ARC_COMPACT = 93, // ARC International ARCompact processor (old
+ // spelling/synonym: EM_ARC_A5)
+ EM_XTENSA = 94, // Tensilica Xtensa Architecture
+ EM_VIDEOCORE = 95, // Alphamosaic VideoCore processor
+ EM_TMM_GPP = 96, // Thompson Multimedia General Purpose Processor
+ EM_NS32K = 97, // National Semiconductor 32000 series
+ EM_TPC = 98, // Tenor Network TPC processor
+ EM_SNP1K = 99, // Trebia SNP 1000 processor
+ EM_ST200 = 100, // STMicroelectronics (www.st.com) ST200
+ EM_IP2K = 101, // Ubicom IP2xxx microcontroller family
+ EM_MAX = 102, // MAX Processor
+ EM_CR = 103, // National Semiconductor CompactRISC microprocessor
+ EM_F2MC16 = 104, // Fujitsu F2MC16
+ EM_MSP430 = 105, // Texas Instruments embedded microcontroller msp430
+ EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP) processor
+ EM_SE_C33 = 107, // S1C33 Family of Seiko Epson processors
+ EM_SEP = 108, // Sharp embedded microprocessor
+ EM_ARCA = 109, // Arca RISC Microprocessor
+ EM_UNICORE = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC
+ // of Peking University
+ EM_EXCESS = 111, // eXcess: 16/32/64-bit configurable embedded CPU
+ EM_DXP = 112, // Icera Semiconductor Inc. Deep Execution Processor
+ EM_ALTERA_NIOS2 = 113, // Altera Nios II soft-core processor
+ EM_CRX = 114, // National Semiconductor CompactRISC CRX
+ EM_XGATE = 115, // Motorola XGATE embedded processor
+ EM_C166 = 116, // Infineon C16x/XC16x processor
+ EM_M16C = 117, // Renesas M16C series microprocessors
+ EM_DSPIC30F = 118, // Microchip Technology dsPIC30F Digital Signal
+ // Controller
+ EM_CE = 119, // Freescale Communication Engine RISC core
+ EM_M32C = 120, // Renesas M32C series microprocessors
+ EM_TSK3000 = 131, // Altium TSK3000 core
+ EM_RS08 = 132, // Freescale RS08 embedded processor
+ EM_SHARC = 133, // Analog Devices SHARC family of 32-bit DSP
+ // processors
+ EM_ECOG2 = 134, // Cyan Technology eCOG2 microprocessor
+ EM_SCORE7 = 135, // Sunplus S+core7 RISC processor
+ EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP Processor
+ EM_VIDEOCORE3 = 137, // Broadcom VideoCore III processor
+ EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture
+ EM_SE_C17 = 139, // Seiko Epson C17 family
+ EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP family
+ EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP family
+ EM_TI_C5500 = 142, // The Texas Instruments TMS320C55x DSP family
+ EM_MMDSP_PLUS = 160, // STMicroelectronics 64bit VLIW Data Signal Processor
+ EM_CYPRESS_M8C = 161, // Cypress M8C microprocessor
+ EM_R32C = 162, // Renesas R32C series microprocessors
+ EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture family
+ EM_QDSP6 = 164, // QUALCOMM DSP6 Processor
+ EM_8051 = 165, // Intel 8051 and variants
+ EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable
+ // and extensible RISC processors
+ EM_NDS32 = 167, // Andes Technology compact code size embedded RISC
+ // processor family
+ EM_ECOG1 = 168, // Cyan Technology eCOG1X family
+ EM_ECOG1X = 168, // Cyan Technology eCOG1X family
+ EM_MAXQ30 = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers
+ EM_XIMO16 = 170, // New Japan Radio (NJR) 16-bit DSP Processor
+ EM_MANIK = 171, // M2000 Reconfigurable RISC Microprocessor
+ EM_CRAYNV2 = 172, // Cray Inc. NV2 vector architecture
+ EM_RX = 173, // Renesas RX family
+ EM_METAG = 174, // Imagination Technologies META processor
+ // architecture
+ EM_MCST_ELBRUS = 175, // MCST Elbrus general purpose hardware architecture
+ EM_ECOG16 = 176, // Cyan Technology eCOG16 family
+ EM_CR16 = 177, // National Semiconductor CompactRISC CR16 16-bit
+ // microprocessor
+ EM_ETPU = 178, // Freescale Extended Time Processing Unit
+ EM_SLE9X = 179, // Infineon Technologies SLE9X core
+ EM_L10M = 180, // Intel L10M
+ EM_K10M = 181, // Intel K10M
+ EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family
+ EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
+ EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
+ EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family
+ EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core
+ EM_CUDA = 190, // NVIDIA CUDA architecture
+ EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family
+ EM_CLOUDSHIELD = 192, // CloudShield architecture family
+ EM_COREA_1ST = 193, // KIPO-KAIST Core-A 1st generation processor family
+ EM_COREA_2ND = 194, // KIPO-KAIST Core-A 2nd generation processor family
+ EM_ARC_COMPACT2 = 195, // Synopsys ARCompact V2
+ EM_OPEN8 = 196, // Open8 8-bit RISC soft processor core
+ EM_RL78 = 197, // Renesas RL78 family
+ EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
+ EM_78KOR = 199, // Renesas 78KOR family
+ EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC)
+ EM_MBLAZE = 47787 // Xilinx MicroBlaze
+};
+
+// Object file classes.
+enum {
+ ELFCLASSNONE = 0,
+ ELFCLASS32 = 1, // 32-bit object file
+ ELFCLASS64 = 2 // 64-bit object file
+};
+
+// Object file byte orderings.
+enum {
+ ELFDATANONE = 0, // Invalid data encoding.
+ ELFDATA2LSB = 1, // Little-endian object file
+ ELFDATA2MSB = 2 // Big-endian object file
+};
+
+// OS ABI identification.
+enum {
+ ELFOSABI_NONE = 0, // UNIX System V ABI
+ ELFOSABI_HPUX = 1, // HP-UX operating system
+ ELFOSABI_NETBSD = 2, // NetBSD
+ ELFOSABI_LINUX = 3, // GNU/Linux
+ ELFOSABI_HURD = 4, // GNU/Hurd
+ ELFOSABI_SOLARIS = 6, // Solaris
+ ELFOSABI_AIX = 7, // AIX
+ ELFOSABI_IRIX = 8, // IRIX
+ ELFOSABI_FREEBSD = 9, // FreeBSD
+ ELFOSABI_TRU64 = 10, // TRU64 UNIX
+ ELFOSABI_MODESTO = 11, // Novell Modesto
+ ELFOSABI_OPENBSD = 12, // OpenBSD
+ ELFOSABI_OPENVMS = 13, // OpenVMS
+ ELFOSABI_NSK = 14, // Hewlett-Packard Non-Stop Kernel
+ ELFOSABI_AROS = 15, // AROS
+ ELFOSABI_FENIXOS = 16, // FenixOS
+ ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
+ ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000
+ ELFOSABI_ARM = 97, // ARM
+ ELFOSABI_STANDALONE = 255 // Standalone (embedded) application
+};
+
+// X86_64 relocations.
+enum {
+ R_X86_64_NONE = 0,
+ R_X86_64_64 = 1,
+ R_X86_64_PC32 = 2,
+ R_X86_64_GOT32 = 3,
+ R_X86_64_PLT32 = 4,
+ R_X86_64_COPY = 5,
+ R_X86_64_GLOB_DAT = 6,
+ R_X86_64_JUMP_SLOT = 7,
+ R_X86_64_RELATIVE = 8,
+ R_X86_64_GOTPCREL = 9,
+ R_X86_64_32 = 10,
+ R_X86_64_32S = 11,
+ R_X86_64_16 = 12,
+ R_X86_64_PC16 = 13,
+ R_X86_64_8 = 14,
+ R_X86_64_PC8 = 15,
+ R_X86_64_DTPMOD64 = 16,
+ R_X86_64_DTPOFF64 = 17,
+ R_X86_64_TPOFF64 = 18,
+ R_X86_64_TLSGD = 19,
+ R_X86_64_TLSLD = 20,
+ R_X86_64_DTPOFF32 = 21,
+ R_X86_64_GOTTPOFF = 22,
+ R_X86_64_TPOFF32 = 23,
+ R_X86_64_PC64 = 24,
+ R_X86_64_GOTOFF64 = 25,
+ R_X86_64_GOTPC32 = 26,
+ R_X86_64_GOT64 = 27,
+ R_X86_64_GOTPCREL64 = 28,
+ R_X86_64_GOTPC64 = 29,
+ R_X86_64_GOTPLT64 = 30,
+ R_X86_64_PLTOFF64 = 31,
+ R_X86_64_SIZE32 = 32,
+ R_X86_64_SIZE64 = 33,
+ R_X86_64_GOTPC32_TLSDESC = 34,
+ R_X86_64_TLSDESC_CALL = 35,
+ R_X86_64_TLSDESC = 36
+};
+
+// i386 relocations.
+// TODO: this is just a subset
+enum {
+ R_386_NONE = 0,
+ R_386_32 = 1,
+ R_386_PC32 = 2,
+ R_386_GOT32 = 3,
+ R_386_PLT32 = 4,
+ R_386_COPY = 5,
+ R_386_GLOB_DAT = 6,
+ R_386_JUMP_SLOT = 7,
+ R_386_RELATIVE = 8,
+ R_386_GOTOFF = 9,
+ R_386_GOTPC = 10,
+ R_386_32PLT = 11,
+ R_386_TLS_TPOFF = 14,
+ R_386_TLS_IE = 15,
+ R_386_TLS_GOTIE = 16,
+ R_386_TLS_LE = 17,
+ R_386_TLS_GD = 18,
+ R_386_TLS_LDM = 19,
+ R_386_16 = 20,
+ R_386_PC16 = 21,
+ R_386_8 = 22,
+ R_386_PC8 = 23,
+ R_386_TLS_GD_32 = 24,
+ R_386_TLS_GD_PUSH = 25,
+ R_386_TLS_GD_CALL = 26,
+ R_386_TLS_GD_POP = 27,
+ R_386_TLS_LDM_32 = 28,
+ R_386_TLS_LDM_PUSH = 29,
+ R_386_TLS_LDM_CALL = 30,
+ R_386_TLS_LDM_POP = 31,
+ R_386_TLS_LDO_32 = 32,
+ R_386_TLS_IE_32 = 33,
+ R_386_TLS_LE_32 = 34,
+ R_386_TLS_DTPMOD32 = 35,
+ R_386_TLS_DTPOFF32 = 36,
+ R_386_TLS_TPOFF32 = 37,
+ R_386_TLS_GOTDESC = 39,
+ R_386_TLS_DESC_CALL = 40,
+ R_386_TLS_DESC = 41,
+ R_386_IRELATIVE = 42,
+ R_386_NUM = 43
+};
+
+// MBlaze relocations.
+enum {
+ R_MICROBLAZE_NONE = 0,
+ R_MICROBLAZE_32 = 1,
+ R_MICROBLAZE_32_PCREL = 2,
+ R_MICROBLAZE_64_PCREL = 3,
+ R_MICROBLAZE_32_PCREL_LO = 4,
+ R_MICROBLAZE_64 = 5,
+ R_MICROBLAZE_32_LO = 6,
+ R_MICROBLAZE_SRO32 = 7,
+ R_MICROBLAZE_SRW32 = 8,
+ R_MICROBLAZE_64_NONE = 9,
+ R_MICROBLAZE_32_SYM_OP_SYM = 10,
+ R_MICROBLAZE_GNU_VTINHERIT = 11,
+ R_MICROBLAZE_GNU_VTENTRY = 12,
+ R_MICROBLAZE_GOTPC_64 = 13,
+ R_MICROBLAZE_GOT_64 = 14,
+ R_MICROBLAZE_PLT_64 = 15,
+ R_MICROBLAZE_REL = 16,
+ R_MICROBLAZE_JUMP_SLOT = 17,
+ R_MICROBLAZE_GLOB_DAT = 18,
+ R_MICROBLAZE_GOTOFF_64 = 19,
+ R_MICROBLAZE_GOTOFF_32 = 20,
+ R_MICROBLAZE_COPY = 21
+};
+
+enum {
+ R_PPC_NONE = 0, /* No relocation. */
+ R_PPC_ADDR32 = 1,
+ R_PPC_ADDR24 = 2,
+ R_PPC_ADDR16 = 3,
+ R_PPC_ADDR16_LO = 4,
+ R_PPC_ADDR16_HI = 5,
+ R_PPC_ADDR16_HA = 6,
+ R_PPC_ADDR14 = 7,
+ R_PPC_ADDR14_BRTAKEN = 8,
+ R_PPC_ADDR14_BRNTAKEN = 9,
+ R_PPC_REL24 = 10,
+ R_PPC_REL14 = 11,
+ R_PPC_REL14_BRTAKEN = 12,
+ R_PPC_REL14_BRNTAKEN = 13,
+ R_PPC_REL32 = 26
+};
+
+// ARM Specific e_flags
+enum { EF_ARM_EABIMASK = 0xFF000000U };
+
+// ELF Relocation types for ARM
+// Meets 2.08 ABI Specs.
+
+enum {
+ R_ARM_NONE = 0x00,
+ R_ARM_PC24 = 0x01,
+ R_ARM_ABS32 = 0x02,
+ R_ARM_REL32 = 0x03,
+ R_ARM_LDR_PC_G0 = 0x04,
+ R_ARM_ABS16 = 0x05,
+ R_ARM_ABS12 = 0x06,
+ R_ARM_THM_ABS5 = 0x07,
+ R_ARM_ABS8 = 0x08,
+ R_ARM_SBREL32 = 0x09,
+ R_ARM_THM_CALL = 0x0a,
+ R_ARM_THM_PC8 = 0x0b,
+ R_ARM_BREL_ADJ = 0x0c,
+ R_ARM_TLS_DESC = 0x0d,
+ R_ARM_THM_SWI8 = 0x0e,
+ R_ARM_XPC25 = 0x0f,
+ R_ARM_THM_XPC22 = 0x10,
+ R_ARM_TLS_DTPMOD32 = 0x11,
+ R_ARM_TLS_DTPOFF32 = 0x12,
+ R_ARM_TLS_TPOFF32 = 0x13,
+ R_ARM_COPY = 0x14,
+ R_ARM_GLOB_DAT = 0x15,
+ R_ARM_JUMP_SLOT = 0x16,
+ R_ARM_RELATIVE = 0x17,
+ R_ARM_GOTOFF32 = 0x18,
+ R_ARM_BASE_PREL = 0x19,
+ R_ARM_GOT_BREL = 0x1a,
+ R_ARM_PLT32 = 0x1b,
+ R_ARM_CALL = 0x1c,
+ R_ARM_JUMP24 = 0x1d,
+ R_ARM_THM_JUMP24 = 0x1e,
+ R_ARM_BASE_ABS = 0x1f,
+ R_ARM_ALU_PCREL_7_0 = 0x20,
+ R_ARM_ALU_PCREL_15_8 = 0x21,
+ R_ARM_ALU_PCREL_23_15 = 0x22,
+ R_ARM_LDR_SBREL_11_0_NC = 0x23,
+ R_ARM_ALU_SBREL_19_12_NC = 0x24,
+ R_ARM_ALU_SBREL_27_20_CK = 0x25,
+ R_ARM_TARGET1 = 0x26,
+ R_ARM_SBREL31 = 0x27,
+ R_ARM_V4BX = 0x28,
+ R_ARM_TARGET2 = 0x29,
+ R_ARM_PREL31 = 0x2a,
+ R_ARM_MOVW_ABS_NC = 0x2b,
+ R_ARM_MOVT_ABS = 0x2c,
+ R_ARM_MOVW_PREL_NC = 0x2d,
+ R_ARM_MOVT_PREL = 0x2e,
+ R_ARM_THM_MOVW_ABS_NC = 0x2f,
+ R_ARM_THM_MOVT_ABS = 0x30,
+ R_ARM_THM_MOVW_PREL_NC = 0x31,
+ R_ARM_THM_MOVT_PREL = 0x32,
+ R_ARM_THM_JUMP19 = 0x33,
+ R_ARM_THM_JUMP6 = 0x34,
+ R_ARM_THM_ALU_PREL_11_0 = 0x35,
+ R_ARM_THM_PC12 = 0x36,
+ R_ARM_ABS32_NOI = 0x37,
+ R_ARM_REL32_NOI = 0x38,
+ R_ARM_ALU_PC_G0_NC = 0x39,
+ R_ARM_ALU_PC_G0 = 0x3a,
+ R_ARM_ALU_PC_G1_NC = 0x3b,
+ R_ARM_ALU_PC_G1 = 0x3c,
+ R_ARM_ALU_PC_G2 = 0x3d,
+ R_ARM_LDR_PC_G1 = 0x3e,
+ R_ARM_LDR_PC_G2 = 0x3f,
+ R_ARM_LDRS_PC_G0 = 0x40,
+ R_ARM_LDRS_PC_G1 = 0x41,
+ R_ARM_LDRS_PC_G2 = 0x42,
+ R_ARM_LDC_PC_G0 = 0x43,
+ R_ARM_LDC_PC_G1 = 0x44,
+ R_ARM_LDC_PC_G2 = 0x45,
+ R_ARM_ALU_SB_G0_NC = 0x46,
+ R_ARM_ALU_SB_G0 = 0x47,
+ R_ARM_ALU_SB_G1_NC = 0x48,
+ R_ARM_ALU_SB_G1 = 0x49,
+ R_ARM_ALU_SB_G2 = 0x4a,
+ R_ARM_LDR_SB_G0 = 0x4b,
+ R_ARM_LDR_SB_G1 = 0x4c,
+ R_ARM_LDR_SB_G2 = 0x4d,
+ R_ARM_LDRS_SB_G0 = 0x4e,
+ R_ARM_LDRS_SB_G1 = 0x4f,
+ R_ARM_LDRS_SB_G2 = 0x50,
+ R_ARM_LDC_SB_G0 = 0x51,
+ R_ARM_LDC_SB_G1 = 0x52,
+ R_ARM_LDC_SB_G2 = 0x53,
+ R_ARM_MOVW_BREL_NC = 0x54,
+ R_ARM_MOVT_BREL = 0x55,
+ R_ARM_MOVW_BREL = 0x56,
+ R_ARM_THM_MOVW_BREL_NC = 0x57,
+ R_ARM_THM_MOVT_BREL = 0x58,
+ R_ARM_THM_MOVW_BREL = 0x59,
+ R_ARM_TLS_GOTDESC = 0x5a,
+ R_ARM_TLS_CALL = 0x5b,
+ R_ARM_TLS_DESCSEQ = 0x5c,
+ R_ARM_THM_TLS_CALL = 0x5d,
+ R_ARM_PLT32_ABS = 0x5e,
+ R_ARM_GOT_ABS = 0x5f,
+ R_ARM_GOT_PREL = 0x60,
+ R_ARM_GOT_BREL12 = 0x61,
+ R_ARM_GOTOFF12 = 0x62,
+ R_ARM_GOTRELAX = 0x63,
+ R_ARM_GNU_VTENTRY = 0x64,
+ R_ARM_GNU_VTINHERIT = 0x65,
+ R_ARM_THM_JUMP11 = 0x66,
+ R_ARM_THM_JUMP8 = 0x67,
+ R_ARM_TLS_GD32 = 0x68,
+ R_ARM_TLS_LDM32 = 0x69,
+ R_ARM_TLS_LDO32 = 0x6a,
+ R_ARM_TLS_IE32 = 0x6b,
+ R_ARM_TLS_LE32 = 0x6c,
+ R_ARM_TLS_LDO12 = 0x6d,
+ R_ARM_TLS_LE12 = 0x6e,
+ R_ARM_TLS_IE12GP = 0x6f,
+ R_ARM_PRIVATE_0 = 0x70,
+ R_ARM_PRIVATE_1 = 0x71,
+ R_ARM_PRIVATE_2 = 0x72,
+ R_ARM_PRIVATE_3 = 0x73,
+ R_ARM_PRIVATE_4 = 0x74,
+ R_ARM_PRIVATE_5 = 0x75,
+ R_ARM_PRIVATE_6 = 0x76,
+ R_ARM_PRIVATE_7 = 0x77,
+ R_ARM_PRIVATE_8 = 0x78,
+ R_ARM_PRIVATE_9 = 0x79,
+ R_ARM_PRIVATE_10 = 0x7a,
+ R_ARM_PRIVATE_11 = 0x7b,
+ R_ARM_PRIVATE_12 = 0x7c,
+ R_ARM_PRIVATE_13 = 0x7d,
+ R_ARM_PRIVATE_14 = 0x7e,
+ R_ARM_PRIVATE_15 = 0x7f,
+ R_ARM_ME_TOO = 0x80,
+ R_ARM_THM_TLS_DESCSEQ16 = 0x81,
+ R_ARM_THM_TLS_DESCSEQ32 = 0x82
+};
+
+// Mips Specific e_flags
+enum {
+ EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
+ EF_MIPS_PIC = 0x00000002, // Position independent code
+ EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
+ EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set
+ EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set
+ EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set
+ EF_MIPS_ARCH_4 = 0x30000000, // MIPS4 instruction set
+ EF_MIPS_ARCH_5 = 0x40000000, // MIPS5 instruction set
+ EF_MIPS_ARCH_32 = 0x50000000, // MIPS32 instruction set per linux not elf.h
+ EF_MIPS_ARCH_64 = 0x60000000, // MIPS64 instruction set per linux not elf.h
+ EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
+ EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2
+ EF_MIPS_ARCH = 0xf0000000 // Mask for applying EF_MIPS_ARCH_ variant
+};
+
+// ELF Relocation types for Mips
+// .
+enum {
+ R_MIPS_NONE = 0,
+ R_MIPS_16 = 1,
+ R_MIPS_32 = 2,
+ R_MIPS_REL32 = 3,
+ R_MIPS_26 = 4,
+ R_MIPS_HI16 = 5,
+ R_MIPS_LO16 = 6,
+ R_MIPS_GPREL16 = 7,
+ R_MIPS_LITERAL = 8,
+ R_MIPS_GOT16 = 9,
+ R_MIPS_GOT = 9,
+ R_MIPS_PC16 = 10,
+ R_MIPS_CALL16 = 11,
+ R_MIPS_GPREL32 = 12,
+ R_MIPS_SHIFT5 = 16,
+ R_MIPS_SHIFT6 = 17,
+ R_MIPS_64 = 18,
+ R_MIPS_GOT_DISP = 19,
+ R_MIPS_GOT_PAGE = 20,
+ R_MIPS_GOT_OFST = 21,
+ R_MIPS_GOT_HI16 = 22,
+ R_MIPS_GOT_LO16 = 23,
+ R_MIPS_SUB = 24,
+ R_MIPS_INSERT_A = 25,
+ R_MIPS_INSERT_B = 26,
+ R_MIPS_DELETE = 27,
+ R_MIPS_HIGHER = 28,
+ R_MIPS_HIGHEST = 29,
+ R_MIPS_CALL_HI16 = 30,
+ R_MIPS_CALL_LO16 = 31,
+ R_MIPS_SCN_DISP = 32,
+ R_MIPS_REL16 = 33,
+ R_MIPS_ADD_IMMEDIATE = 34,
+ R_MIPS_PJUMP = 35,
+ R_MIPS_RELGOT = 36,
+ R_MIPS_JALR = 37,
+ R_MIPS_TLS_DTPMOD32 = 38,
+ R_MIPS_TLS_DTPREL32 = 39,
+ R_MIPS_TLS_DTPMOD64 = 40,
+ R_MIPS_TLS_DTPREL64 = 41,
+ R_MIPS_TLS_GD = 42,
+ R_MIPS_TLS_LDM = 43,
+ R_MIPS_TLS_DTPREL_HI16 = 44,
+ R_MIPS_TLS_DTPREL_LO16 = 45,
+ R_MIPS_TLS_GOTTPREL = 46,
+ R_MIPS_TLS_TPREL32 = 47,
+ R_MIPS_TLS_TPREL64 = 48,
+ R_MIPS_TLS_TPREL_HI16 = 49,
+ R_MIPS_TLS_TPREL_LO16 = 50,
+ R_MIPS_GLOB_DAT = 51,
+ R_MIPS_COPY = 126,
+ R_MIPS_JUMP_SLOT = 127,
+ R_MIPS_NUM = 218
+};
+
+// Section header.
+struct Elf32_Shdr {
+ Elf32_Word sh_name; // Section name (index into string table)
+ Elf32_Word sh_type; // Section type (SHT_*)
+ Elf32_Word sh_flags; // Section flags (SHF_*)
+ Elf32_Addr sh_addr; // Address where section is to be loaded
+ Elf32_Off sh_offset; // File offset of section data, in bytes
+ Elf32_Word sh_size; // Size of section, in bytes
+ Elf32_Word sh_link; // Section type-specific header table index link
+ Elf32_Word sh_info; // Section type-specific extra information
+ Elf32_Word sh_addralign; // Section address alignment
+ Elf32_Word sh_entsize; // Size of records contained within the section
+};
+
+// Section header for ELF64 - same fields as ELF32, different types.
+struct Elf64_Shdr {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+};
+
+// Special section indices.
+enum {
+ SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless
+ SHN_LORESERVE = 0xff00, // Lowest reserved index
+ SHN_LOPROC = 0xff00, // Lowest processor-specific index
+ SHN_HIPROC = 0xff1f, // Highest processor-specific index
+ SHN_LOOS = 0xff20, // Lowest operating system-specific index
+ SHN_HIOS = 0xff3f, // Highest operating system-specific index
+ SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation
+ SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables
+ SHN_XINDEX = 0xffff, // Mark that the index is >= SHN_LORESERVE
+ SHN_HIRESERVE = 0xffff // Highest reserved index
+};
+
+// Section types.
+enum {
+ SHT_NULL = 0, // No associated section (inactive entry).
+ SHT_PROGBITS = 1, // Program-defined contents.
+ SHT_SYMTAB = 2, // Symbol table.
+ SHT_STRTAB = 3, // String table.
+ SHT_RELA = 4, // Relocation entries; explicit addends.
+ SHT_HASH = 5, // Symbol hash table.
+ SHT_DYNAMIC = 6, // Information for dynamic linking.
+ SHT_NOTE = 7, // Information about the file.
+ SHT_NOBITS = 8, // Data occupies no space in the file.
+ SHT_REL = 9, // Relocation entries; no explicit addends.
+ SHT_SHLIB = 10, // Reserved.
+ SHT_DYNSYM = 11, // Symbol table.
+ SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
+ SHT_FINI_ARRAY = 15, // Pointers to termination functions.
+ SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
+ SHT_GROUP = 17, // Section group.
+ SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
+ SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
+ SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
+ SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
+ SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
+ SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
+ // Fixme: All this is duplicated in MCSectionELF. Why??
+ // Exception Index table
+ SHT_ARM_EXIDX = 0x70000001U,
+ // BPABI DLL dynamic linking pre-emption map
+ SHT_ARM_PREEMPTMAP = 0x70000002U,
+ // Object file compatibility attributes
+ SHT_ARM_ATTRIBUTES = 0x70000003U,
+ SHT_ARM_DEBUGOVERLAY = 0x70000004U,
+ SHT_ARM_OVERLAYSECTION = 0x70000005U,
+
+ SHT_X86_64_UNWIND = 0x70000001, // Unwind information
+
+ SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
+ SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
+ SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
+};
+
+// Section flags.
+enum {
+ // Section data should be writable during execution.
+ SHF_WRITE = 0x1,
+
+ // Section occupies memory during program execution.
+ SHF_ALLOC = 0x2,
+
+ // Section contains executable machine instructions.
+ SHF_EXECINSTR = 0x4,
+
+ // The data in this section may be merged.
+ SHF_MERGE = 0x10,
+
+ // The data in this section is null-terminated strings.
+ SHF_STRINGS = 0x20,
+
+ // A field in this section holds a section header table index.
+ SHF_INFO_LINK = 0x40U,
+
+ // Adds special ordering requirements for link editors.
+ SHF_LINK_ORDER = 0x80U,
+
+ // This section requires special OS-specific processing to avoid incorrect
+ // behavior.
+ SHF_OS_NONCONFORMING = 0x100U,
+
+ // This section is a member of a section group.
+ SHF_GROUP = 0x200U,
+
+ // This section holds Thread-Local Storage.
+ SHF_TLS = 0x400U,
+
+ // Start of target-specific flags.
+
+ /// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
+ /// together by the linker to form the constant pool and the cp register is
+ /// set to the start of the constant pool by the boot code.
+ XCORE_SHF_CP_SECTION = 0x800U,
+
+ /// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
+ /// together by the linker to form the data section and the dp register is
+ /// set to the start of the section by the boot code.
+ XCORE_SHF_DP_SECTION = 0x1000U,
+
+ SHF_MASKOS = 0x0ff00000,
+
+ // Bits indicating processor-specific flags.
+ SHF_MASKPROC = 0xf0000000,
+
+ // If an object file section does not have this flag set, then it may not hold
+ // more than 2GB and can be freely referred to in objects using smaller code
+ // models. Otherwise, only objects using larger code models can refer to them.
+ // For example, a medium code model object can refer to data in a section that
+ // sets this flag besides being able to refer to data in a section that does
+ // not set it; likewise, a small code model object can refer only to code in a
+ // section that does not set this flag.
+ SHF_X86_64_LARGE = 0x10000000
+};
+
+// Section Group Flags
+enum {
+ GRP_COMDAT = 0x1,
+ GRP_MASKOS = 0x0ff00000,
+ GRP_MASKPROC = 0xf0000000
+};
+
+// Symbol table entries for ELF32.
+struct Elf32_Sym {
+ Elf32_Word st_name; // Symbol name (index into string table)
+ Elf32_Addr st_value; // Value or address associated with the symbol
+ Elf32_Word st_size; // Size of the symbol
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf32_Half st_shndx; // Which section (header table index) it's defined in
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding() const { return st_info >> 4; }
+ unsigned char getType() const { return st_info & 0x0f; }
+ void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+ void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+ void setBindingAndType(unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+};
+
+// Symbol table entries for ELF64.
+struct Elf64_Sym {
+ Elf64_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
+ Elf64_Half st_shndx; // Which section (header table index) it's defined in
+ Elf64_Addr st_value; // Value or address associated with the symbol
+ Elf64_Xword st_size; // Size of the symbol
+
+ // These accessors and mutators are identical to those defined for ELF32
+ // symbol table entries.
+ unsigned char getBinding() const { return st_info >> 4; }
+ unsigned char getType() const { return st_info & 0x0f; }
+ void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+ void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+ void setBindingAndType(unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+};
+
+// The size (in bytes) of symbol table entries.
+enum {
+ SYMENTRY_SIZE32 = 16, // 32-bit symbol entry size
+ SYMENTRY_SIZE64 = 24 // 64-bit symbol entry size.
+};
+
+// Symbol bindings.
+enum {
+ STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def
+ STB_GLOBAL = 1, // Global symbol, visible to all object files being combined
+ STB_WEAK = 2, // Weak symbol, like global but lower-precedence
+ STB_LOOS = 10, // Lowest operating system-specific binding type
+ STB_HIOS = 12, // Highest operating system-specific binding type
+ STB_LOPROC = 13, // Lowest processor-specific binding type
+ STB_HIPROC = 15 // Highest processor-specific binding type
+};
+
+// Symbol types.
+enum {
+ STT_NOTYPE = 0, // Symbol's type is not specified
+ STT_OBJECT = 1, // Symbol is a data object (variable, array, etc.)
+ STT_FUNC = 2, // Symbol is executable code (function, etc.)
+ STT_SECTION = 3, // Symbol refers to a section
+ STT_FILE = 4, // Local, absolute symbol that refers to a file
+ STT_COMMON = 5, // An uninitialized common block
+ STT_TLS = 6, // Thread local data object
+ STT_LOOS = 7, // Lowest operating system-specific symbol type
+ STT_HIOS = 8, // Highest operating system-specific symbol type
+ STT_GNU_IFUNC = 10, // GNU indirect function
+ STT_LOPROC = 13, // Lowest processor-specific symbol type
+ STT_HIPROC = 15 // Highest processor-specific symbol type
+};
+
+enum {
+ STV_DEFAULT = 0, // Visibility is specified by binding type
+ STV_INTERNAL = 1, // Defined by processor supplements
+ STV_HIDDEN = 2, // Not visible to other components
+ STV_PROTECTED = 3 // Visible in other components but not preemptable
+};
+
+// Relocation entry, without explicit addend.
+struct Elf32_Rel {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol() const { return (r_info >> 8); }
+ unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
+ void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ }
+};
+
+// Relocation entry with explicit addend.
+struct Elf32_Rela {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+ Elf32_Sword r_addend; // Compute value for relocatable field by adding this
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol() const { return (r_info >> 8); }
+ unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
+ void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ }
+};
+
+// Relocation entry, without explicit addend.
+struct Elf64_Rel {
+ Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
+ Elf64_Xword r_info; // Symbol table index and type of relocation to apply.
+
+ // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+ // and ELF64_R_INFO macros defined in the ELF specification:
+ Elf64_Xword getSymbol() const { return (r_info >> 32); }
+ unsigned char getType() const {
+ return (unsigned char) (r_info & 0xffffffffL);
+ }
+ void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
+ void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf64_Xword s, unsigned char t) {
+ r_info = (s << 32) + (t&0xffffffffL);
+ }
+};
+
+// Relocation entry with explicit addend.
+struct Elf64_Rela {
+ Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
+ Elf64_Xword r_info; // Symbol table index and type of relocation to apply.
+ Elf64_Sxword r_addend; // Compute value for relocatable field by adding this.
+
+ // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+ // and ELF64_R_INFO macros defined in the ELF specification:
+ Elf64_Xword getSymbol() const { return (r_info >> 32); }
+ unsigned char getType() const {
+ return (unsigned char) (r_info & 0xffffffffL);
+ }
+ void setSymbol(Elf64_Xword s) { setSymbolAndType(s, getType()); }
+ void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf64_Xword s, unsigned char t) {
+ r_info = (s << 32) + (t&0xffffffffL);
+ }
+};
+
+// Program header for ELF32.
+struct Elf32_Phdr {
+ Elf32_Word p_type; // Type of segment
+ Elf32_Off p_offset; // File offset where segment is located, in bytes
+ Elf32_Addr p_vaddr; // Virtual address of beginning of segment
+ Elf32_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf32_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf32_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf32_Word p_flags; // Segment flags
+ Elf32_Word p_align; // Segment alignment constraint
+};
+
+// Program header for ELF64.
+struct Elf64_Phdr {
+ Elf64_Word p_type; // Type of segment
+ Elf64_Word p_flags; // Segment flags
+ Elf64_Off p_offset; // File offset where segment is located, in bytes
+ Elf64_Addr p_vaddr; // Virtual address of beginning of segment
+ Elf64_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf64_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf64_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf64_Xword p_align; // Segment alignment constraint
+};
+
+// Segment types.
+enum {
+ PT_NULL = 0, // Unused segment.
+ PT_LOAD = 1, // Loadable segment.
+ PT_DYNAMIC = 2, // Dynamic linking information.
+ PT_INTERP = 3, // Interpreter pathname.
+ PT_NOTE = 4, // Auxiliary information.
+ PT_SHLIB = 5, // Reserved.
+ 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.
+
+ // x86-64 program header types.
+ // These all contain stack unwind tables.
+ PT_GNU_EH_FRAME = 0x6474e550,
+ PT_SUNW_EH_FRAME = 0x6474e550,
+ PT_SUNW_UNWIND = 0x6464e550,
+
+ 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.
+};
+
+// Segment flag bits.
+enum {
+ PF_X = 1, // Execute
+ PF_W = 2, // Write
+ PF_R = 4, // Read
+ PF_MASKOS = 0x0ff00000,// Bits for operating system-specific semantics.
+ PF_MASKPROC = 0xf0000000 // Bits for processor-specific semantics.
+};
+
+// Dynamic table entry for ELF32.
+struct Elf32_Dyn
+{
+ Elf32_Sword d_tag; // Type of dynamic table entry.
+ union
+ {
+ Elf32_Word d_val; // Integer value of entry.
+ Elf32_Addr d_ptr; // Pointer value of entry.
+ } d_un;
+};
+
+// Dynamic table entry for ELF64.
+struct Elf64_Dyn
+{
+ Elf64_Sxword d_tag; // Type of dynamic table entry.
+ union
+ {
+ Elf64_Xword d_val; // Integer value of entry.
+ Elf64_Addr d_ptr; // Pointer value of entry.
+ } d_un;
+};
+
+// Dynamic table entry tags.
+enum {
+ DT_NULL = 0, // Marks end of dynamic array.
+ DT_NEEDED = 1, // String table offset of needed library.
+ DT_PLTRELSZ = 2, // Size of relocation entries in PLT.
+ DT_PLTGOT = 3, // Address associated with linkage table.
+ DT_HASH = 4, // Address of symbolic hash table.
+ DT_STRTAB = 5, // Address of dynamic string table.
+ DT_SYMTAB = 6, // Address of dynamic symbol table.
+ DT_RELA = 7, // Address of relocation table (Rela entries).
+ DT_RELASZ = 8, // Size of Rela relocation table.
+ DT_RELAENT = 9, // Size of a Rela relocation entry.
+ DT_STRSZ = 10, // Total size of the string table.
+ DT_SYMENT = 11, // Size of a symbol table entry.
+ DT_INIT = 12, // Address of initialization function.
+ DT_FINI = 13, // Address of termination function.
+ DT_SONAME = 14, // String table offset of a shared objects name.
+ DT_RPATH = 15, // String table offset of library search path.
+ DT_SYMBOLIC = 16, // Changes symbol resolution algorithm.
+ DT_REL = 17, // Address of relocation table (Rel entries).
+ DT_RELSZ = 18, // Size of Rel relocation table.
+ DT_RELENT = 19, // Size of a Rel relocation entry.
+ DT_PLTREL = 20, // Type of relocation entry used for linking.
+ DT_DEBUG = 21, // Reserved for debugger.
+ DT_TEXTREL = 22, // Relocations exist for non-writable segments.
+ DT_JMPREL = 23, // Address of relocations associated with PLT.
+ DT_BIND_NOW = 24, // Process all relocations before execution.
+ DT_INIT_ARRAY = 25, // Pointer to array of initialization functions.
+ DT_FINI_ARRAY = 26, // Pointer to array of termination functions.
+ DT_INIT_ARRAYSZ = 27, // Size of DT_INIT_ARRAY.
+ DT_FINI_ARRAYSZ = 28, // Size of DT_FINI_ARRAY.
+ DT_RUNPATH = 29, // String table offset of lib search path.
+ DT_FLAGS = 30, // Flags.
+ DT_ENCODING = 32, // Values from here to DT_LOOS follow the rules
+ // for the interpretation of the d_un union.
+
+ DT_PREINIT_ARRAY = 32, // Pointer to array of preinit functions.
+ DT_PREINIT_ARRAYSZ = 33, // Size of the DT_PREINIT_ARRAY array.
+
+ DT_LOOS = 0x60000000, // Start of environment specific tags.
+ DT_HIOS = 0x6FFFFFFF, // End of environment specific tags.
+ DT_LOPROC = 0x70000000, // Start of processor specific tags.
+ DT_HIPROC = 0x7FFFFFFF // End of processor specific tags.
+};
+
+// DT_FLAGS values.
+enum {
+ DF_ORIGIN = 0x01, // The object may reference $ORIGIN.
+ DF_SYMBOLIC = 0x02, // Search the shared lib before searching the exe.
+ DF_TEXTREL = 0x04, // Relocations may modify a non-writable segment.
+ DF_BIND_NOW = 0x08, // Process all relocations on load.
+ DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically.
+};
+
+// ElfXX_VerDef structure version (GNU versioning)
+enum {
+ VER_DEF_NONE = 0,
+ VER_DEF_CURRENT = 1
+};
+
+// VerDef Flags (ElfXX_VerDef::vd_flags)
+enum {
+ VER_FLG_BASE = 0x1,
+ VER_FLG_WEAK = 0x2,
+ VER_FLG_INFO = 0x4
+};
+
+// Special constants for the version table. (SHT_GNU_versym/.gnu.version)
+enum {
+ VER_NDX_LOCAL = 0, // Unversioned local symbol
+ VER_NDX_GLOBAL = 1, // Unversioned global symbol
+ VERSYM_VERSION = 0x7fff, // Version Index mask
+ VERSYM_HIDDEN = 0x8000 // Hidden bit (non-default version)
+};
+
+// ElfXX_VerNeed structure version (GNU versioning)
+enum {
+ VER_NEED_NONE = 0,
+ VER_NEED_CURRENT = 1
+};
+
+} // end namespace ELF
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Endian.h b/contrib/llvm/include/llvm/Support/Endian.h
new file mode 100644
index 000000000000..733ab7548fca
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Endian.h
@@ -0,0 +1,224 @@
+//===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares generic functions to read and write endian specific data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ENDIAN_H
+#define LLVM_SUPPORT_ENDIAN_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};
+enum alignment {unaligned, aligned};
+
+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)
+
+} // end namespace detail
+
+namespace endian {
+ template<typename value_type, alignment align>
+ static 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>
+ static 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, alignment align>
+ static 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, alignment align>
+ static 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;
+ }
+}
+
+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:
+ operator value_type() const {
+ return endian::read_be<value_type, unaligned>(Value);
+ }
+ 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);
+ }
+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;
+};
+
+} // end namespace detail
+
+typedef detail::packed_endian_specific_integral
+ <uint8_t, little, unaligned> ulittle8_t;
+typedef detail::packed_endian_specific_integral
+ <uint16_t, little, unaligned> ulittle16_t;
+typedef detail::packed_endian_specific_integral
+ <uint32_t, little, unaligned> ulittle32_t;
+typedef detail::packed_endian_specific_integral
+ <uint64_t, little, unaligned> ulittle64_t;
+
+typedef detail::packed_endian_specific_integral
+ <int8_t, little, unaligned> little8_t;
+typedef detail::packed_endian_specific_integral
+ <int16_t, little, unaligned> little16_t;
+typedef detail::packed_endian_specific_integral
+ <int32_t, little, unaligned> little32_t;
+typedef detail::packed_endian_specific_integral
+ <int64_t, little, unaligned> little64_t;
+
+typedef detail::packed_endian_specific_integral
+ <uint8_t, little, aligned> aligned_ulittle8_t;
+typedef detail::packed_endian_specific_integral
+ <uint16_t, little, aligned> aligned_ulittle16_t;
+typedef detail::packed_endian_specific_integral
+ <uint32_t, little, aligned> aligned_ulittle32_t;
+typedef detail::packed_endian_specific_integral
+ <uint64_t, little, aligned> aligned_ulittle64_t;
+
+typedef detail::packed_endian_specific_integral
+ <int8_t, little, aligned> aligned_little8_t;
+typedef detail::packed_endian_specific_integral
+ <int16_t, little, aligned> aligned_little16_t;
+typedef detail::packed_endian_specific_integral
+ <int32_t, little, aligned> aligned_little32_t;
+typedef detail::packed_endian_specific_integral
+ <int64_t, little, aligned> aligned_little64_t;
+
+typedef detail::packed_endian_specific_integral
+ <uint8_t, big, unaligned> ubig8_t;
+typedef detail::packed_endian_specific_integral
+ <uint16_t, big, unaligned> ubig16_t;
+typedef detail::packed_endian_specific_integral
+ <uint32_t, big, unaligned> ubig32_t;
+typedef detail::packed_endian_specific_integral
+ <uint64_t, big, unaligned> ubig64_t;
+
+typedef detail::packed_endian_specific_integral
+ <int8_t, big, unaligned> big8_t;
+typedef detail::packed_endian_specific_integral
+ <int16_t, big, unaligned> big16_t;
+typedef detail::packed_endian_specific_integral
+ <int32_t, big, unaligned> big32_t;
+typedef detail::packed_endian_specific_integral
+ <int64_t, big, unaligned> big64_t;
+
+typedef detail::packed_endian_specific_integral
+ <uint8_t, big, aligned> aligned_ubig8_t;
+typedef detail::packed_endian_specific_integral
+ <uint16_t, big, aligned> aligned_ubig16_t;
+typedef detail::packed_endian_specific_integral
+ <uint32_t, big, aligned> aligned_ubig32_t;
+typedef detail::packed_endian_specific_integral
+ <uint64_t, big, aligned> aligned_ubig64_t;
+
+typedef detail::packed_endian_specific_integral
+ <int8_t, big, aligned> aligned_big8_t;
+typedef detail::packed_endian_specific_integral
+ <int16_t, big, aligned> aligned_big16_t;
+typedef detail::packed_endian_specific_integral
+ <int32_t, big, aligned> aligned_big32_t;
+typedef detail::packed_endian_specific_integral
+ <int64_t, big, aligned> aligned_big64_t;
+
+} // end namespace llvm
+} // end namespace support
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Errno.h b/contrib/llvm/include/llvm/Support/Errno.h
new file mode 100644
index 000000000000..150bdb701626
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Errno.h
@@ -0,0 +1,34 @@
+//===- llvm/Support/Errno.h - Portable+convenient errno handling -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares some portable and convenient functions to deal with errno.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ERRNO_H
+#define LLVM_SYSTEM_ERRNO_H
+
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// Returns a string representation of the errno value, using whatever
+/// thread-safe variant of strerror() is available. Be sure to call this
+/// immediately after the function that set errno, or errno may have been
+/// overwritten by an intervening call.
+std::string StrError();
+
+/// Like the no-argument version above, but uses \p errnum instead of errno.
+std::string StrError(int errnum);
+
+} // namespace sys
+} // namespace llvm
+
+#endif // LLVM_SYSTEM_ERRNO_H
diff --git a/contrib/llvm/include/llvm/Support/ErrorHandling.h b/contrib/llvm/include/llvm/Support/ErrorHandling.h
new file mode 100644
index 000000000000..95b01095c1b2
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ErrorHandling.h
@@ -0,0 +1,106 @@
+//===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an API used to indicate fatal error conditions. Non-fatal
+// errors (most of them) should be handled through LLVMContext.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERRORHANDLING_H
+#define LLVM_SUPPORT_ERRORHANDLING_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+ class Twine;
+
+ /// An error handler callback.
+ typedef void (*fatal_error_handler_t)(void *user_data,
+ const std::string& reason);
+
+ /// install_fatal_error_handler - Installs a new error handler to be used
+ /// whenever a serious (non-recoverable) error is encountered by LLVM.
+ ///
+ /// If you are using llvm_start_multithreaded, you should register the handler
+ /// before doing that.
+ ///
+ /// If no error handler is installed the default is to print the error message
+ /// to stderr, and call exit(1). If an error handler is installed then it is
+ /// the handler's responsibility to log the message, it will no longer be
+ /// printed to stderr. If the error handler returns, then exit(1) will be
+ /// called.
+ ///
+ /// It is dangerous to naively use an error handler which throws an exception.
+ /// Even though some applications desire to gracefully recover from arbitrary
+ /// faults, blindly throwing exceptions through unfamiliar code isn't a way to
+ /// achieve this.
+ ///
+ /// \param user_data - An argument which will be passed to the install error
+ /// handler.
+ void install_fatal_error_handler(fatal_error_handler_t handler,
+ void *user_data = 0);
+
+ /// Restores default error handling behaviour.
+ /// This must not be called between llvm_start_multithreaded() and
+ /// llvm_stop_multithreaded().
+ void remove_fatal_error_handler();
+
+ /// ScopedFatalErrorHandler - This is a simple helper class which just
+ /// calls install_fatal_error_handler in its constructor and
+ /// remove_fatal_error_handler in its destructor.
+ struct ScopedFatalErrorHandler {
+ explicit ScopedFatalErrorHandler(fatal_error_handler_t handler,
+ void *user_data = 0) {
+ install_fatal_error_handler(handler, user_data);
+ }
+
+ ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); }
+ };
+
+ /// Reports a serious error, calling any installed error handler. These
+ /// functions are intended to be used for error conditions which are outside
+ /// the control of the compiler (I/O errors, invalid user input, etc.)
+ ///
+ /// If no error handler is installed the default is to print the message to
+ /// standard error, followed by a newline.
+ /// After the error handler is called this function will call exit(1), it
+ /// does not return.
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason);
+ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason);
+
+ /// This function calls abort(), and prints the optional message to stderr.
+ /// Use the llvm_unreachable macro (that adds location info), instead of
+ /// calling this function directly.
+ LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=0,
+ const char *file=0,
+ unsigned line=0);
+}
+
+/// Marks that the current location is not supposed to be reachable.
+/// In !NDEBUG builds, prints the message and location info to stderr.
+/// In NDEBUG builds, becomes an optimizer hint that the current location
+/// is not supposed to be reachable. On compilers that don't support
+/// such hints, prints a reduced message instead.
+///
+/// Use this instead of assert(0). It conveys intent more clearly and
+/// allows compilers to omit some unnecessary code.
+#ifndef NDEBUG
+#define llvm_unreachable(msg) \
+ ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
+#elif defined(LLVM_BUILTIN_UNREACHABLE)
+#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
+#else
+#define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
+#endif
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/FEnv.h b/contrib/llvm/include/llvm/Support/FEnv.h
new file mode 100644
index 000000000000..f6f43337bd29
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/FEnv.h
@@ -0,0 +1,56 @@
+//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- 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 an operating system independent interface to
+// floating-point exception interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_FENV_H
+#define LLVM_SYSTEM_FENV_H
+
+#include "llvm/Config/config.h"
+#include <cerrno>
+#ifdef HAVE_FENV_H
+#include <fenv.h>
+#endif
+
+// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
+// fenv.h; see PR6907 for details.
+#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
+#undef HAVE_FENV_H
+#endif
+
+namespace llvm {
+namespace sys {
+
+/// llvm_fenv_clearexcept - Clear the floating-point exception state.
+static inline void llvm_fenv_clearexcept() {
+#ifdef HAVE_FENV_H
+ feclearexcept(FE_ALL_EXCEPT);
+#endif
+ errno = 0;
+}
+
+/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
+static inline bool llvm_fenv_testexcept() {
+ int errno_val = errno;
+ if (errno_val == ERANGE || errno_val == EDOM)
+ return true;
+#ifdef HAVE_FENV_H
+ if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
+ return true;
+#endif
+ return false;
+}
+
+} // End sys namespace
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/FileSystem.h b/contrib/llvm/include/llvm/Support/FileSystem.h
new file mode 100644
index 000000000000..e6f9926af6f8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/FileSystem.h
@@ -0,0 +1,720 @@
+//===- llvm/Support/FileSystem.h - File System OS Concept -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::fs namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+// All functions return an error_code and their actual work via the last out
+// argument. The out argument is defined if and only if errc::success is
+// returned. A function may return any error code in the generic or system
+// category. However, they shall be equivalent to any error conditions listed
+// in each functions respective documentation if the condition applies. [ note:
+// this does not guarantee that error_code will be in the set of explicitly
+// listed codes, but it does guarantee that if any of the explicitly listed
+// errors occur, the correct error_code will be used ]. All functions may
+// return errc::not_enough_memory if there is not enough memory to complete the
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILE_SYSTEM_H
+#define LLVM_SUPPORT_FILE_SYSTEM_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/system_error.h"
+#include <ctime>
+#include <iterator>
+#include <stack>
+#include <string>
+#include <vector>
+
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+namespace llvm {
+namespace sys {
+namespace fs {
+
+/// file_type - An "enum class" enumeration for the file system's view of the
+/// type.
+struct file_type {
+ enum _ {
+ status_error,
+ file_not_found,
+ regular_file,
+ directory_file,
+ symlink_file,
+ block_file,
+ character_file,
+ fifo_file,
+ socket_file,
+ type_unknown
+ };
+
+ file_type(_ v) : v_(v) {}
+ explicit file_type(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// copy_option - An "enum class" enumeration of copy semantics for copy
+/// operations.
+struct copy_option {
+ enum _ {
+ fail_if_exists,
+ overwrite_if_exists
+ };
+
+ copy_option(_ v) : v_(v) {}
+ explicit copy_option(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// space_info - Self explanatory.
+struct space_info {
+ uint64_t capacity;
+ uint64_t free;
+ uint64_t available;
+};
+
+/// file_status - Represents the result of a call to stat and friends. It has
+/// a platform specific member to store the result.
+class file_status
+{
+ #if defined(LLVM_ON_UNIX)
+ dev_t st_dev;
+ ino_t st_ino;
+ #elif defined (LLVM_ON_WIN32)
+ uint32_t LastWriteTimeHigh;
+ uint32_t LastWriteTimeLow;
+ uint32_t VolumeSerialNumber;
+ uint32_t FileSizeHigh;
+ uint32_t FileSizeLow;
+ uint32_t FileIndexHigh;
+ uint32_t FileIndexLow;
+ #endif
+ friend bool equivalent(file_status A, file_status B);
+ friend error_code status(const Twine &path, file_status &result);
+ file_type Type;
+public:
+ explicit file_status(file_type v=file_type::status_error)
+ : Type(v) {}
+
+ file_type type() const { return Type; }
+ void type(file_type v) { Type = v; }
+};
+
+/// file_magic - An "enum class" enumeration of file types based on magic (the first
+/// N bytes of the file).
+struct file_magic {
+ enum _ {
+ unknown = 0, ///< Unrecognized file
+ bitcode, ///< Bitcode file
+ archive, ///< ar style archive file
+ elf_relocatable, ///< ELF Relocatable object file
+ elf_executable, ///< ELF Executable image
+ elf_shared_object, ///< ELF dynamically linked shared lib
+ elf_core, ///< ELF core image
+ macho_object, ///< Mach-O Object file
+ macho_executable, ///< Mach-O Executable
+ macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
+ macho_core, ///< Mach-O Core File
+ macho_preload_executabl, ///< Mach-O Preloaded Executable
+ macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
+ macho_dynamic_linker, ///< The Mach-O dynamic linker
+ macho_bundle, ///< Mach-O Bundle file
+ macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
+ macho_dsym_companion, ///< Mach-O dSYM companion file
+ coff_object, ///< COFF object file
+ pecoff_executable ///< PECOFF executable file
+ };
+
+ bool is_object() const {
+ return v_ == unknown ? false : true;
+ }
+
+ file_magic() : v_(unknown) {}
+ file_magic(_ v) : v_(v) {}
+ explicit file_magic(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+
+private:
+ int v_;
+};
+
+/// @}
+/// @name Physical Operators
+/// @{
+
+/// @brief Make \a path an absolute path.
+///
+/// Makes \a path absolute using the current directory if it is not already. An
+/// empty \a path will result in the current directory.
+///
+/// /absolute/path => /absolute/path
+/// relative/../path => <current-directory>/relative/../path
+///
+/// @param path A path that is modified to be an absolute path.
+/// @returns errc::success if \a path has been made absolute, otherwise a
+/// platform specific error_code.
+error_code make_absolute(SmallVectorImpl<char> &path);
+
+/// @brief Copy the file at \a from to the path \a to.
+///
+/// @param from The path to copy the file from.
+/// @param to The path to copy the file to.
+/// @param copt Behavior if \a to already exists.
+/// @returns errc::success if the file has been successfully copied.
+/// errc::file_exists if \a to already exists and \a copt ==
+/// copy_option::fail_if_exists. Otherwise a platform specific
+/// error_code.
+error_code copy_file(const Twine &from, const Twine &to,
+ copy_option copt = copy_option::fail_if_exists);
+
+/// @brief Create all the non-existent directories in path.
+///
+/// @param path Directories to create.
+/// @param existed Set to true if \a path already existed, false otherwise.
+/// @returns errc::success if is_directory(path) and existed have been set,
+/// otherwise a platform specific error_code.
+error_code create_directories(const Twine &path, bool &existed);
+
+/// @brief Create the directory in path.
+///
+/// @param path Directory to create.
+/// @param existed Set to true if \a path already existed, false otherwise.
+/// @returns errc::success if is_directory(path) and existed have been set,
+/// otherwise a platform specific error_code.
+error_code create_directory(const Twine &path, bool &existed);
+
+/// @brief Create a hard link from \a from to \a to.
+///
+/// @param to The path to hard link to.
+/// @param from The path to hard link from. This is created.
+/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
+/// , otherwise a platform specific error_code.
+error_code create_hard_link(const Twine &to, const Twine &from);
+
+/// @brief Create a symbolic link from \a from to \a to.
+///
+/// @param to The path to symbolically link to.
+/// @param from The path to symbolically link from. This is created.
+/// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
+/// otherwise a platform specific error_code.
+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,
+/// otherwise a platform specific error_code.
+error_code current_path(SmallVectorImpl<char> &result);
+
+/// @brief Remove path. Equivalent to POSIX remove().
+///
+/// @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
+/// successfully set, otherwise a platform specific error_code.
+error_code remove(const Twine &path, bool &existed);
+
+/// @brief Recursively remove all files below \a path, then \a path. Files are
+/// removed as if by POSIX remove().
+///
+/// @param path Input path.
+/// @param num_removed Number of files removed.
+/// @results 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);
+
+/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
+///
+/// @param from The path to rename from.
+/// @param to The path to rename to. This is created.
+error_code rename(const Twine &from, const Twine &to);
+
+/// @brief Resize path to size. File is resized as if by POSIX truncate().
+///
+/// @param path Input path.
+/// @param size Size to resize to.
+/// @returns errc::success if \a path has been resized to \a size, otherwise a
+/// platform specific error_code.
+error_code resize_file(const Twine &path, uint64_t size);
+
+/// @}
+/// @name Physical Observers
+/// @{
+
+/// @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
+/// not.
+bool exists(file_status status);
+
+/// @brief Does file exist?
+///
+/// @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
+/// platform specific error_code.
+error_code exists(const Twine &path, bool &result);
+
+/// @brief Simpler version of exists for clients that don't need to
+/// differentiate between an error and false.
+inline bool exists(const Twine &path) {
+ bool result;
+ return !exists(path, result) && result;
+}
+
+/// @brief Do file_status's represent the same thing?
+///
+/// @param A Input file_status.
+/// @param B Input file_status.
+///
+/// assert(status_known(A) || status_known(B));
+///
+/// @results True if A and B both represent the same file system entity, false
+/// otherwise.
+bool equivalent(file_status A, file_status B);
+
+/// @brief Do paths represent the same thing?
+///
+/// assert(status_known(A) || status_known(B));
+///
+/// @param A Input path A.
+/// @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
+/// platform specific error_code.
+error_code equivalent(const Twine &A, const Twine &B, bool &result);
+
+/// @brief Get file size.
+///
+/// @param path Input path.
+/// @param result Set to the size of the file in \a path.
+/// @returns errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+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.
+bool is_directory(file_status status);
+
+/// @brief Is path a directory?
+///
+/// @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
+/// 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.
+bool is_regular_file(file_status status);
+
+/// @brief Is path a regular file?
+///
+/// @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
+/// platform specific error_code.
+error_code is_regular_file(const Twine &path, bool &result);
+
+/// @brief Does this status represent something that exists but is not a
+/// directory, regular file, or symlink?
+///
+/// @param status A file_status previously returned from status.
+/// @results exists(s) && !is_regular_file(s) && !is_directory(s) &&
+/// !is_symlink(s)
+bool is_other(file_status status);
+
+/// @brief Is path something that exists but is not a directory,
+/// regular file, or symlink?
+///
+/// @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
+/// platform specific error_code.
+error_code is_other(const Twine &path, bool &result);
+
+/// @brief Does status represent a symlink?
+///
+/// @param status A file_status previously returned from stat.
+/// @param result status.type() == symlink_file.
+bool is_symlink(file_status status);
+
+/// @brief Is path a symlink?
+///
+/// @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
+/// platform specific error_code.
+error_code is_symlink(const Twine &path, bool &result);
+
+/// @brief Get file status as if by POSIX stat().
+///
+/// @param path Input path.
+/// @param result Set to the file status.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code status(const Twine &path, file_status &result);
+
+/// @brief Is status available?
+///
+/// @param path Input path.
+/// @results 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
+/// platform specific error_code.
+error_code status_known(const Twine &path, bool &result);
+
+/// @brief Generate a unique path and open it as a file.
+///
+/// Generates a unique path suitable for a temporary file and then opens it as a
+/// file. The name is based on \a model with '%' replaced by a random char in
+/// [0-9a-f]. If \a model is not an absolute path, a suitable temporary
+/// directory will be prepended.
+///
+/// This is an atomic operation. Either the file is created and opened, or the
+/// file system is left untouched.
+///
+/// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s
+///
+/// @param model Name to base unique path off of.
+/// @param result_fs 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
+/// directory will be prepended.
+/// @results 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,
+ bool makeAbsolute = true);
+
+/// @brief Canonicalize path.
+///
+/// Sets result to the file system's idea of what path is. The result is always
+/// absolute and has the same capitalization as the file system.
+///
+/// @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
+/// platform specific error_code.
+error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @brief Are \a path's first bytes \a magic?
+///
+/// @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
+/// platform specific error_code.
+error_code has_magic(const Twine &path, const Twine &magic, bool &result);
+
+/// @brief Get \a path's first \a len bytes.
+///
+/// @param path Input path.
+/// @param len Number of magic bytes to get.
+/// @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,
+/// 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,
+ SmallVectorImpl<char> &result);
+
+/// @brief Identify the type of a binary file based on how magical it is.
+file_magic identify_magic(StringRef magic);
+
+/// @brief Get and identify \a path's type based on its content.
+///
+/// @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
+/// 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
+/// platform specific error_code.
+error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
+
+/// @brief Get bitcode library paths the system linker uses
+/// + 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
+/// platform specific error_code.
+error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
+
+/// @brief Find a library.
+///
+/// Find the path to a library using its short name. Use the system
+/// dependent library paths to locate the library.
+///
+/// c => /usr/lib/libc.so
+///
+/// @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
+/// platform specific error_code.
+error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
+
+/// @brief Get absolute path of main executable.
+///
+/// @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
+/// platform specific error_code.
+error_code GetMainExecutable(const char *argv0, void *MainAddr,
+ SmallVectorImpl<char> &result);
+
+/// @}
+/// @name Iterators
+/// @{
+
+/// directory_entry - A single entry in a directory. Caches the status either
+/// from the result of the iteration syscall, or the first time status is
+/// called.
+class directory_entry {
+ std::string Path;
+ mutable file_status Status;
+
+public:
+ explicit directory_entry(const Twine &path, file_status st = file_status())
+ : Path(path.str())
+ , Status(st) {}
+
+ directory_entry() {}
+
+ void assign(const Twine &path, file_status st = file_status()) {
+ Path = path.str();
+ Status = st;
+ }
+
+ void replace_filename(const Twine &filename, file_status st = file_status());
+
+ const std::string &path() const { return Path; }
+ error_code status(file_status &result) const;
+
+ bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
+ bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
+ bool operator< (const directory_entry& rhs) const;
+ bool operator<=(const directory_entry& rhs) const;
+ bool operator> (const directory_entry& rhs) const;
+ bool operator>=(const directory_entry& rhs) const;
+};
+
+namespace detail {
+ struct DirIterState;
+
+ error_code directory_iterator_construct(DirIterState&, StringRef);
+ error_code directory_iterator_increment(DirIterState&);
+ error_code directory_iterator_destruct(DirIterState&);
+
+ /// DirIterState - Keeps state for the directory_iterator. It is reference
+ /// counted in order to preserve InputIterator semantics on copy.
+ struct DirIterState : public RefCountedBase<DirIterState> {
+ DirIterState()
+ : IterationHandle(0) {}
+
+ ~DirIterState() {
+ directory_iterator_destruct(*this);
+ }
+
+ intptr_t IterationHandle;
+ directory_entry CurrentEntry;
+ };
+}
+
+/// directory_iterator - Iterates through the entries in path. There is no
+/// operator++ because we need an error_code. If it's really needed we can make
+/// it call report_fatal_error on error.
+class directory_iterator {
+ IntrusiveRefCntPtr<detail::DirIterState> State;
+
+public:
+ explicit directory_iterator(const Twine &path, error_code &ec) {
+ State = new detail::DirIterState;
+ SmallString<128> path_storage;
+ ec = detail::directory_iterator_construct(*State,
+ path.toStringRef(path_storage));
+ }
+
+ explicit directory_iterator(const directory_entry &de, error_code &ec) {
+ State = new detail::DirIterState;
+ ec = detail::directory_iterator_construct(*State, de.path());
+ }
+
+ /// Construct end iterator.
+ directory_iterator() : State(new detail::DirIterState) {}
+
+ // No operator++ because we need error_code.
+ directory_iterator &increment(error_code &ec) {
+ ec = directory_iterator_increment(*State);
+ return *this;
+ }
+
+ const directory_entry &operator*() const { return State->CurrentEntry; }
+ const directory_entry *operator->() const { return &State->CurrentEntry; }
+
+ bool operator==(const directory_iterator &RHS) const {
+ return State->CurrentEntry == RHS.State->CurrentEntry;
+ }
+
+ bool operator!=(const directory_iterator &RHS) const {
+ return !(*this == RHS);
+ }
+ // Other members as required by
+ // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+namespace detail {
+ /// RecDirIterState - Keeps state for the recursive_directory_iterator. It is
+ /// reference counted in order to preserve InputIterator semantics on copy.
+ struct RecDirIterState : public RefCountedBase<RecDirIterState> {
+ RecDirIterState()
+ : Level(0)
+ , HasNoPushRequest(false) {}
+
+ std::stack<directory_iterator, std::vector<directory_iterator> > Stack;
+ uint16_t Level;
+ bool HasNoPushRequest;
+ };
+}
+
+/// recursive_directory_iterator - Same as directory_iterator except for it
+/// recurses down into child directories.
+class recursive_directory_iterator {
+ IntrusiveRefCntPtr<detail::RecDirIterState> State;
+
+public:
+ recursive_directory_iterator() {}
+ explicit recursive_directory_iterator(const Twine &path, error_code &ec)
+ : State(new detail::RecDirIterState) {
+ State->Stack.push(directory_iterator(path, ec));
+ if (State->Stack.top() == directory_iterator())
+ State.reset();
+ }
+ // No operator++ because we need error_code.
+ recursive_directory_iterator &increment(error_code &ec) {
+ static const directory_iterator end_itr;
+
+ if (State->HasNoPushRequest)
+ State->HasNoPushRequest = false;
+ else {
+ file_status st;
+ if ((ec = State->Stack.top()->status(st))) return *this;
+ if (is_directory(st)) {
+ State->Stack.push(directory_iterator(*State->Stack.top(), ec));
+ if (ec) return *this;
+ if (State->Stack.top() != end_itr) {
+ ++State->Level;
+ return *this;
+ }
+ State->Stack.pop();
+ }
+ }
+
+ while (!State->Stack.empty()
+ && State->Stack.top().increment(ec) == end_itr) {
+ State->Stack.pop();
+ --State->Level;
+ }
+
+ // Check if we are done. If so, create an end iterator.
+ if (State->Stack.empty())
+ State.reset();
+
+ return *this;
+ }
+
+ const directory_entry &operator*() const { return *State->Stack.top(); }
+ const directory_entry *operator->() const { return &*State->Stack.top(); }
+
+ // observers
+ /// Gets the current level. Starting path is at level 0.
+ int level() const { return State->Level; }
+
+ /// Returns true if no_push has been called for this directory_entry.
+ bool no_push_request() const { return State->HasNoPushRequest; }
+
+ // modifiers
+ /// Goes up one level if Level > 0.
+ void pop() {
+ assert(State && "Cannot pop and end itertor!");
+ assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
+
+ static const directory_iterator end_itr;
+ error_code ec;
+ do {
+ if (ec)
+ report_fatal_error("Error incrementing directory iterator.");
+ State->Stack.pop();
+ --State->Level;
+ } while (!State->Stack.empty()
+ && State->Stack.top().increment(ec) == end_itr);
+
+ // Check if we are done. If so, create an end iterator.
+ if (State->Stack.empty())
+ State.reset();
+ }
+
+ /// Does not go down into the current directory_entry.
+ void no_push() { State->HasNoPushRequest = true; }
+
+ bool operator==(const recursive_directory_iterator &RHS) const {
+ return State == RHS.State;
+ }
+
+ bool operator!=(const recursive_directory_iterator &RHS) const {
+ return !(*this == RHS);
+ }
+ // Other members as required by
+ // C++ Std, 24.1.1 Input iterators [input.iterators]
+};
+
+/// @}
+
+} // end namespace fs
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/FileUtilities.h b/contrib/llvm/include/llvm/Support/FileUtilities.h
new file mode 100644
index 000000000000..5456eb730a17
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/FileUtilities.h
@@ -0,0 +1,80 @@
+//===- llvm/Support/FileUtilities.h - File System Utilities -----*- 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 family of utility functions which are useful for doing
+// various things with files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEUTILITIES_H
+#define LLVM_SUPPORT_FILEUTILITIES_H
+
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+
+ /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
+ /// the files match, 1 if they are different, and 2 if there is a file error.
+ /// This function allows you to specify an absolute and relative FP error that
+ /// is allowed to exist. If you specify a string to fill in for the error
+ /// option, it will set the string to an error message if an error occurs, or
+ /// if the files are different.
+ ///
+ int DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
+ const sys::PathWithStatus &FileB,
+ double AbsTol, double RelTol,
+ std::string *Error = 0);
+
+
+ /// FileRemover - This class is a simple object meant to be stack allocated.
+ /// If an exception is thrown from a region, the object removes the filename
+ /// specified (if deleteIt is true).
+ ///
+ class FileRemover {
+ SmallString<128> Filename;
+ bool DeleteIt;
+ public:
+ FileRemover() : DeleteIt(false) {}
+
+ explicit FileRemover(const Twine& filename, bool deleteIt = true)
+ : DeleteIt(deleteIt) {
+ filename.toVector(Filename);
+ }
+
+ ~FileRemover() {
+ if (DeleteIt) {
+ // Ignore problems deleting the file.
+ bool existed;
+ sys::fs::remove(Filename.str(), existed);
+ }
+ }
+
+ /// setFile - Give ownership of the file to the FileRemover so it will
+ /// be removed when the object is destroyed. If the FileRemover already
+ /// had ownership of a file, remove it first.
+ void setFile(const Twine& filename, bool deleteIt = true) {
+ if (DeleteIt) {
+ // Ignore problems deleting the file.
+ bool existed;
+ sys::fs::remove(Filename.str(), existed);
+ }
+
+ Filename.clear();
+ filename.toVector(Filename);
+ DeleteIt = deleteIt;
+ }
+
+ /// releaseFile - Take ownership of the file away from the FileRemover so it
+ /// will not be removed when the object is destroyed.
+ void releaseFile() { DeleteIt = false; }
+ };
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Format.h b/contrib/llvm/include/llvm/Support/Format.h
new file mode 100644
index 000000000000..59812d98f589
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Format.h
@@ -0,0 +1,216 @@
+//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the format() function, which can be used with other
+// LLVM subsystems to provide printf-style formatting. This gives all the power
+// and risk of printf. This can be used like this (with raw_ostreams as an
+// example):
+//
+// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
+//
+// Or if you prefer:
+//
+// OS << format("mynumber: %4.5f\n", 1234.412);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FORMAT_H
+#define LLVM_SUPPORT_FORMAT_H
+
+#include <cassert>
+#include <cstdio>
+#ifdef _MSC_VER
+// FIXME: This define is wrong:
+// - _snprintf does not guarantee that trailing null is always added - if
+// there is no space for null, it does not report any error.
+// - According to C++ standard, snprintf should be visible in the 'std'
+// namespace - this define makes this impossible.
+#define snprintf _snprintf
+#endif
+
+namespace llvm {
+
+/// format_object_base - This is a helper class used for handling formatted
+/// output. It is the abstract base class of a templated derived class.
+class format_object_base {
+protected:
+ const char *Fmt;
+ virtual void home(); // Out of line virtual method.
+
+ /// snprint - Call snprintf() for this object, on the given buffer and size.
+ virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
+
+public:
+ format_object_base(const char *fmt) : Fmt(fmt) {}
+ virtual ~format_object_base() {}
+
+ /// print - Format the object into the specified buffer. On success, this
+ /// returns the length of the formatted string. If the buffer is too small,
+ /// this returns a length to retry with, which will be larger than BufferSize.
+ unsigned print(char *Buffer, unsigned BufferSize) const {
+ assert(BufferSize && "Invalid buffer size!");
+
+ // Print the string, leaving room for the terminating null.
+ int N = snprint(Buffer, BufferSize);
+
+ // VC++ and old GlibC return negative on overflow, just double the size.
+ if (N < 0)
+ return BufferSize*2;
+
+ // Other impls yield number of bytes needed, not including the final '\0'.
+ if (unsigned(N) >= BufferSize)
+ return N+1;
+
+ // Otherwise N is the length of output (not including the final '\0').
+ return N;
+ }
+};
+
+/// format_object1 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T>
+class format_object1 : public format_object_base {
+ T Val;
+public:
+ format_object1(const char *fmt, const T &val)
+ : format_object_base(fmt), Val(val) {
+ }
+
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val);
+ }
+};
+
+/// format_object2 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T1, typename T2>
+class format_object2 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+public:
+ format_object2(const char *fmt, const T1 &val1, const T2 &val2)
+ : format_object_base(fmt), Val1(val1), Val2(val2) {
+ }
+
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
+ }
+};
+
+/// format_object3 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T1, typename T2, typename T3>
+class format_object3 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+ T3 Val3;
+public:
+ format_object3(const char *fmt, const T1 &val1, const T2 &val2,const T3 &val3)
+ : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
+ }
+
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
+ }
+};
+
+/// format_object4 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T1, typename T2, typename T3, typename T4>
+class format_object4 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+ T3 Val3;
+ T4 Val4;
+public:
+ format_object4(const char *fmt, const T1 &val1, const T2 &val2,
+ const T3 &val3, const T4 &val4)
+ : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
+ }
+
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
+ }
+};
+
+/// format_object5 - This is a templated helper class used by the format
+/// function that captures the object to be formated and the format string. When
+/// actually printed, this synthesizes the string into a temporary buffer
+/// provided and returns whether or not it is big enough.
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class format_object5 : public format_object_base {
+ T1 Val1;
+ T2 Val2;
+ T3 Val3;
+ T4 Val4;
+ T5 Val5;
+public:
+ format_object5(const char *fmt, const T1 &val1, const T2 &val2,
+ const T3 &val3, const T4 &val4, const T5 &val5)
+ : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4),
+ Val5(val5) {
+ }
+
+ virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
+ }
+};
+
+/// format - This is a helper function that is used to produce formatted output.
+/// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
+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';
+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';
+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';
+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,
+ const T4 &Val4) {
+ 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';
+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,
+ const T4 &Val4, const T5 &Val5) {
+ return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5);
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/FormattedStream.h b/contrib/llvm/include/llvm/Support/FormattedStream.h
new file mode 100644
index 000000000000..58a18851687c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/FormattedStream.h
@@ -0,0 +1,154 @@
+//===-- llvm/Support/FormattedStream.h - Formatted streams ------*- 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 raw_ostream implementations for streams to do
+// things like pretty-print comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
+#define LLVM_SUPPORT_FORMATTEDSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm
+{
+ /// formatted_raw_ostream - Formatted raw_fd_ostream to handle
+ /// asm-specific constructs.
+ ///
+ class formatted_raw_ostream : public raw_ostream {
+ public:
+ /// DELETE_STREAM - Tell the destructor to delete the held stream.
+ ///
+ static const bool DELETE_STREAM = true;
+
+ /// PRESERVE_STREAM - Tell the destructor to not delete the held
+ /// stream.
+ ///
+ static const bool PRESERVE_STREAM = false;
+
+ private:
+ /// TheStream - The real stream we output to. We set it to be
+ /// unbuffered, since we're already doing our own buffering.
+ ///
+ raw_ostream *TheStream;
+
+ /// DeleteStream - Do we need to delete TheStream in the
+ /// destructor?
+ ///
+ bool DeleteStream;
+
+ /// ColumnScanned - The current output column of the data that's
+ /// been flushed and the portion of the buffer that's been
+ /// scanned. The column scheme is zero-based.
+ ///
+ unsigned ColumnScanned;
+
+ /// Scanned - This points to one past the last character in the
+ /// buffer we've scanned.
+ ///
+ const char *Scanned;
+
+ virtual void write_impl(const char *Ptr, size_t Size);
+
+ /// 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();
+ }
+
+ /// ComputeColumn - Examine the given output buffer and figure out which
+ /// column we end up in after output.
+ ///
+ void ComputeColumn(const char *Ptr, size_t size);
+
+ public:
+ /// formatted_raw_ostream - Open the specified file for
+ /// writing. If an error occurs, information about the error is
+ /// put into ErrorInfo, and the stream should be immediately
+ /// destroyed; the string will be empty if no error occurred.
+ ///
+ /// As a side effect, the given Stream is set to be Unbuffered.
+ /// This is because formatted_raw_ostream does its own buffering,
+ /// so it doesn't want another layer of buffering to be happening
+ /// underneath it.
+ ///
+ formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
+ : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
+ setStream(Stream, Delete);
+ }
+ explicit formatted_raw_ostream()
+ : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
+ Scanned = 0;
+ }
+
+ ~formatted_raw_ostream() {
+ flush();
+ releaseStream();
+ }
+
+ void setStream(raw_ostream &Stream, bool Delete = false) {
+ releaseStream();
+
+ TheStream = &Stream;
+ DeleteStream = Delete;
+
+ // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
+ // own buffering, and it doesn't need or want TheStream to do another
+ // layer of buffering underneath. Resize the buffer to what TheStream
+ // had been using, and tell TheStream not to do its own buffering.
+ if (size_t BufferSize = TheStream->GetBufferSize())
+ SetBufferSize(BufferSize);
+ else
+ SetUnbuffered();
+ TheStream->SetUnbuffered();
+
+ Scanned = 0;
+ }
+
+ /// PadToColumn - Align the output to some column number. If the current
+ /// column is already equal to or more than NewCol, PadToColumn inserts one
+ /// space.
+ ///
+ /// \param NewCol - The column to move to.
+ formatted_raw_ostream &PadToColumn(unsigned NewCol);
+
+ private:
+ void releaseStream() {
+ // Delete the stream if needed. Otherwise, transfer the buffer
+ // settings from this raw_ostream back to the underlying stream.
+ if (!TheStream)
+ return;
+ if (DeleteStream)
+ delete TheStream;
+ else if (size_t BufferSize = GetBufferSize())
+ TheStream->SetBufferSize(BufferSize);
+ else
+ TheStream->SetUnbuffered();
+ }
+ };
+
+/// fouts() - This returns a reference to a formatted_raw_ostream for
+/// standard output. Use it like: fouts() << "foo" << "bar";
+formatted_raw_ostream &fouts();
+
+/// ferrs() - This returns a reference to a formatted_raw_ostream for
+/// standard error. Use it like: ferrs() << "foo" << "bar";
+formatted_raw_ostream &ferrs();
+
+/// fdbgs() - This returns a reference to a formatted_raw_ostream for
+/// debug output. Use it like: fdbgs() << "foo" << "bar";
+formatted_raw_ostream &fdbgs();
+
+} // end llvm namespace
+
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/GCOV.h b/contrib/llvm/include/llvm/Support/GCOV.h
new file mode 100644
index 000000000000..49cd87fc7b44
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/GCOV.h
@@ -0,0 +1,224 @@
+//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header provides the interface to read and write coverage files that
+// use 'gcov' format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GCOV_H
+#define LLVM_GCOV_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class GCOVFunction;
+class GCOVBlock;
+class GCOVLines;
+class FileInfo;
+
+enum GCOVFormat {
+ InvalidGCOV,
+ GCNO_402,
+ GCNO_404,
+ GCDA_402,
+ GCDA_404
+};
+
+/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
+/// read operations.
+class GCOVBuffer {
+public:
+ GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
+
+ /// readGCOVFormat - Read GCOV signature at the beginning of buffer.
+ enum GCOVFormat readGCOVFormat() {
+ StringRef Magic = Buffer->getBuffer().slice(0, 12);
+ Cursor = 12;
+ if (Magic == "oncg*404MVLL")
+ return GCNO_404;
+ else if (Magic == "oncg*204MVLL")
+ return GCNO_402;
+ else if (Magic == "adcg*404MVLL")
+ return GCDA_404;
+ else if (Magic == "adcg*204MVLL")
+ return GCDA_402;
+
+ Cursor = 0;
+ return InvalidGCOV;
+ }
+
+ /// readFunctionTag - If cursor points to a function tag then increment the
+ /// cursor and return true otherwise return false.
+ bool readFunctionTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\1') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ /// readBlockTag - If cursor points to a block tag then increment the
+ /// cursor and return true otherwise return false.
+ bool readBlockTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x41' || Tag[3] != '\x01') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ /// readEdgeTag - If cursor points to an edge tag then increment the
+ /// cursor and return true otherwise return false.
+ bool readEdgeTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x43' || Tag[3] != '\x01') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ /// readLineTag - If cursor points to a line tag then increment the
+ /// cursor and return true otherwise return false.
+ bool readLineTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x45' || Tag[3] != '\x01') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ /// readArcTag - If cursor points to an gcda arc tag then increment the
+ /// cursor and return true otherwise return false.
+ bool readArcTag() {
+ StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (Tag.empty() ||
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\xa1' || Tag[3] != '\1') {
+ return false;
+ }
+ Cursor += 4;
+ return true;
+ }
+
+ uint32_t readInt() {
+ uint32_t Result;
+ StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ assert (Str.empty() == false && "Unexpected memory buffer end!");
+ Cursor += 4;
+ Result = *(uint32_t *)(Str.data());
+ return Result;
+ }
+
+ uint64_t readInt64() {
+ uint64_t Lo = readInt();
+ uint64_t Hi = readInt();
+ uint64_t Result = Lo | (Hi << 32);
+ return Result;
+ }
+
+ StringRef readString() {
+ uint32_t Len = readInt() * 4;
+ StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len);
+ Cursor += Len;
+ return Str;
+ }
+
+ uint64_t getCursor() const { return Cursor; }
+private:
+ MemoryBuffer *Buffer;
+ uint64_t Cursor;
+};
+
+/// GCOVFile - Collects coverage information for one pair of coverage file
+/// (.gcno and .gcda).
+class GCOVFile {
+public:
+ GCOVFile() {}
+ ~GCOVFile();
+ bool read(GCOVBuffer &Buffer);
+ void dump();
+ void collectLineCounts(FileInfo &FI);
+private:
+ SmallVector<GCOVFunction *, 16> Functions;
+};
+
+/// GCOVFunction - Collects function information.
+class GCOVFunction {
+public:
+ GCOVFunction() : Ident(0), LineNumber(0) {}
+ ~GCOVFunction();
+ bool read(GCOVBuffer &Buffer, GCOVFormat Format);
+ void dump();
+ void collectLineCounts(FileInfo &FI);
+private:
+ uint32_t Ident;
+ uint32_t LineNumber;
+ StringRef Name;
+ StringRef Filename;
+ SmallVector<GCOVBlock *, 16> Blocks;
+};
+
+/// GCOVBlock - Collects block information.
+class GCOVBlock {
+public:
+ GCOVBlock(uint32_t N) : Number(N), Counter(0) {}
+ ~GCOVBlock();
+ void addEdge(uint32_t N) { Edges.push_back(N); }
+ void addLine(StringRef Filename, uint32_t LineNo);
+ void addCount(uint64_t N) { Counter = N; }
+ void dump();
+ void collectLineCounts(FileInfo &FI);
+private:
+ uint32_t Number;
+ uint64_t Counter;
+ SmallVector<uint32_t, 16> Edges;
+ StringMap<GCOVLines *> Lines;
+};
+
+/// GCOVLines - A wrapper around a vector of int to keep track of line nos.
+class GCOVLines {
+public:
+ ~GCOVLines() { Lines.clear(); }
+ void add(uint32_t N) { Lines.push_back(N); }
+ void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count);
+ void dump();
+
+private:
+ SmallVector<uint32_t, 4> Lines;
+};
+
+typedef SmallVector<uint32_t, 16> LineCounts;
+class FileInfo {
+public:
+ void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count);
+ void print();
+private:
+ StringMap<LineCounts> LineInfo;
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h b/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h
new file mode 100644
index 000000000000..ef92c95ee7e0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -0,0 +1,113 @@
+//===- llvm/Support/GetElementPtrTypeIterator.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 implements an iterator for walking through the types indexed by
+// getelementptr instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+
+#include "llvm/User.h"
+#include "llvm/DerivedTypes.h"
+
+namespace llvm {
+ template<typename ItTy = User::const_op_iterator>
+ class generic_gep_type_iterator
+ : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag,
+ Type *, ptrdiff_t> super;
+
+ ItTy OpIt;
+ Type *CurTy;
+ generic_gep_type_iterator() {}
+ public:
+
+ static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = Ty;
+ I.OpIt = It;
+ return I;
+ }
+ static generic_gep_type_iterator end(ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = 0;
+ I.OpIt = It;
+ return I;
+ }
+
+ bool operator==(const generic_gep_type_iterator& x) const {
+ return OpIt == x.OpIt;
+ }
+ bool operator!=(const generic_gep_type_iterator& x) const {
+ return !operator==(x);
+ }
+
+ Type *operator*() const {
+ return CurTy;
+ }
+
+ Type *getIndexedType() const {
+ CompositeType *CT = cast<CompositeType>(CurTy);
+ return CT->getTypeAtIndex(getOperand());
+ }
+
+ // This is a non-standard operator->. It allows you to call methods on the
+ // current type directly.
+ Type *operator->() const { return operator*(); }
+
+ Value *getOperand() const { return *OpIt; }
+
+ generic_gep_type_iterator& operator++() { // Preincrement
+ if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+ CurTy = CT->getTypeAtIndex(getOperand());
+ } else {
+ CurTy = 0;
+ }
+ ++OpIt;
+ return *this;
+ }
+
+ generic_gep_type_iterator operator++(int) { // Postincrement
+ generic_gep_type_iterator tmp = *this; ++*this; return tmp;
+ }
+ };
+
+ 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);
+ }
+ 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);
+ }
+ inline gep_type_iterator gep_type_end(const User &GEP) {
+ return gep_type_iterator::end(GEP.op_end());
+ }
+
+ template<typename T>
+ inline generic_gep_type_iterator<const T *>
+ gep_type_begin(Type *Op0, ArrayRef<T> A) {
+ return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
+ }
+
+ template<typename T>
+ inline generic_gep_type_iterator<const T *>
+ gep_type_end(Type *Op0, ArrayRef<T> A) {
+ return generic_gep_type_iterator<const T *>::end(A.end());
+ }
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/GraphWriter.h b/contrib/llvm/include/llvm/Support/GraphWriter.h
new file mode 100644
index 000000000000..ae32da59dc22
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/GraphWriter.h
@@ -0,0 +1,357 @@
+//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- 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 simple interface that can be used to print out generic
+// LLVM graphs to ".dot" files. "dot" is a tool that is part of the AT&T
+// graphviz package (http://www.research.att.com/sw/tools/graphviz/) which can
+// be used to turn the files output by this interface into a variety of
+// different graphics formats.
+//
+// Graphs do not need to implement any interface past what is already required
+// by the GraphTraits template, but they can choose to implement specializations
+// of the DOTGraphTraits template if they want to customize the graphs output in
+// any way.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Path.h"
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+
+namespace DOT { // Private functions...
+ std::string EscapeString(const std::string &Label);
+}
+
+namespace GraphProgram {
+ enum Name {
+ DOT,
+ FDP,
+ NEATO,
+ TWOPI,
+ CIRCO
+ };
+}
+
+void DisplayGraph(const sys::Path& Filename, bool wait=true, GraphProgram::Name program = GraphProgram::DOT);
+
+template<typename GraphType>
+class GraphWriter {
+ raw_ostream &O;
+ const GraphType &G;
+
+ typedef DOTGraphTraits<GraphType> DOTTraits;
+ typedef GraphTraits<GraphType> GTraits;
+ typedef typename GTraits::NodeType NodeType;
+ typedef typename GTraits::nodes_iterator node_iterator;
+ typedef typename GTraits::ChildIteratorType child_iterator;
+ DOTTraits DTraits;
+
+ // Writes the edge labels of the node to O and returns true if there are any
+ // edge labels not equal to the empty string "".
+ bool getEdgeSourceLabels(raw_ostream &O, NodeType *Node) {
+ child_iterator EI = GTraits::child_begin(Node);
+ child_iterator EE = GTraits::child_end(Node);
+ bool hasEdgeSourceLabels = false;
+
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
+ std::string label = DTraits.getEdgeSourceLabel(Node, EI);
+
+ if (label.empty())
+ continue;
+
+ hasEdgeSourceLabels = true;
+
+ if (i)
+ O << "|";
+
+ O << "<s" << i << ">" << DOT::EscapeString(label);
+ }
+
+ if (EI != EE && hasEdgeSourceLabels)
+ O << "|<s64>truncated...";
+
+ return hasEdgeSourceLabels;
+ }
+
+public:
+ GraphWriter(raw_ostream &o, const GraphType &g, bool SN) : O(o), G(g) {
+ DTraits = DOTTraits(SN);
+ }
+
+ void writeGraph(const std::string &Title = "") {
+ // Output the header for the graph...
+ writeHeader(Title);
+
+ // Emit all of the nodes in the graph...
+ writeNodes();
+
+ // Output any customizations on the graph
+ DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, *this);
+
+ // Output the end of the graph
+ writeFooter();
+ }
+
+ void writeHeader(const std::string &Title) {
+ std::string GraphName = DTraits.getGraphName(G);
+
+ if (!Title.empty())
+ O << "digraph \"" << DOT::EscapeString(Title) << "\" {\n";
+ else if (!GraphName.empty())
+ O << "digraph \"" << DOT::EscapeString(GraphName) << "\" {\n";
+ else
+ O << "digraph unnamed {\n";
+
+ if (DTraits.renderGraphFromBottomUp())
+ O << "\trankdir=\"BT\";\n";
+
+ if (!Title.empty())
+ O << "\tlabel=\"" << DOT::EscapeString(Title) << "\";\n";
+ else if (!GraphName.empty())
+ O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
+ O << DTraits.getGraphProperties(G);
+ O << "\n";
+ }
+
+ void writeFooter() {
+ // Finish off the graph
+ O << "}\n";
+ }
+
+ void writeNodes() {
+ // Loop over the graph, printing it out...
+ for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
+ I != E; ++I)
+ if (!isNodeHidden(*I))
+ writeNode(*I);
+ }
+
+ bool isNodeHidden(NodeType &Node) {
+ return isNodeHidden(&Node);
+ }
+
+ bool isNodeHidden(NodeType *const *Node) {
+ return isNodeHidden(*Node);
+ }
+
+ bool isNodeHidden(NodeType *Node) {
+ return DTraits.isNodeHidden(Node);
+ }
+
+ void writeNode(NodeType& Node) {
+ writeNode(&Node);
+ }
+
+ void writeNode(NodeType *const *Node) {
+ writeNode(*Node);
+ }
+
+ void writeNode(NodeType *Node) {
+ std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
+
+ O << "\tNode" << static_cast<const void*>(Node) << " [shape=record,";
+ if (!NodeAttributes.empty()) O << NodeAttributes << ",";
+ O << "label=\"{";
+
+ if (!DTraits.renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DTraits.hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ std::string edgeSourceLabels;
+ raw_string_ostream EdgeSourceLabels(edgeSourceLabels);
+ bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node);
+
+ if (hasEdgeSourceLabels) {
+ if (!DTraits.renderGraphFromBottomUp()) O << "|";
+
+ O << "{" << EdgeSourceLabels.str() << "}";
+
+ if (DTraits.renderGraphFromBottomUp()) O << "|";
+ }
+
+ if (DTraits.renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DTraits.getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DTraits.hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ if (DTraits.hasEdgeDestLabels()) {
+ O << "|{";
+
+ unsigned i = 0, e = DTraits.numEdgeDestLabels(Node);
+ for (; i != e && i != 64; ++i) {
+ if (i) O << "|";
+ O << "<d" << i << ">"
+ << DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i));
+ }
+
+ if (i != e)
+ O << "|<d64>truncated...";
+ O << "}";
+ }
+
+ O << "}\"];\n"; // Finish printing the "node" line
+
+ // Output all of the edges now
+ child_iterator EI = GTraits::child_begin(Node);
+ child_iterator EE = GTraits::child_end(Node);
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
+ if (!DTraits.isNodeHidden(*EI))
+ writeEdge(Node, i, EI);
+ for (; EI != EE; ++EI)
+ if (!DTraits.isNodeHidden(*EI))
+ writeEdge(Node, 64, EI);
+ }
+
+ void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
+ if (NodeType *TargetNode = *EI) {
+ int DestPort = -1;
+ if (DTraits.edgeTargetsEdgeSource(Node, EI)) {
+ child_iterator TargetIt = DTraits.getEdgeTarget(Node, EI);
+
+ // Figure out which edge this targets...
+ unsigned Offset =
+ (unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
+ DestPort = static_cast<int>(Offset);
+ }
+
+ if (DTraits.getEdgeSourceLabel(Node, EI).empty())
+ edgeidx = -1;
+
+ emitEdge(static_cast<const void*>(Node), edgeidx,
+ static_cast<const void*>(TargetNode), DestPort,
+ DTraits.getEdgeAttributes(Node, EI, G));
+ }
+ }
+
+ /// emitSimpleNode - Outputs a simple (non-record) node
+ void emitSimpleNode(const void *ID, const std::string &Attr,
+ const std::string &Label, unsigned NumEdgeSources = 0,
+ const std::vector<std::string> *EdgeSourceLabels = 0) {
+ O << "\tNode" << ID << "[ ";
+ if (!Attr.empty())
+ O << Attr << ",";
+ O << " label =\"";
+ if (NumEdgeSources) O << "{";
+ O << DOT::EscapeString(Label);
+ if (NumEdgeSources) {
+ O << "|{";
+
+ for (unsigned i = 0; i != NumEdgeSources; ++i) {
+ if (i) O << "|";
+ O << "<s" << i << ">";
+ if (EdgeSourceLabels) O << DOT::EscapeString((*EdgeSourceLabels)[i]);
+ }
+ O << "}}";
+ }
+ O << "\"];\n";
+ }
+
+ /// emitEdge - Output an edge from a simple node into the graph...
+ void emitEdge(const void *SrcNodeID, int SrcNodePort,
+ const void *DestNodeID, int DestNodePort,
+ const std::string &Attrs) {
+ if (SrcNodePort > 64) return; // Eminating from truncated part?
+ if (DestNodePort > 64) DestNodePort = 64; // Targeting the truncated part?
+
+ O << "\tNode" << SrcNodeID;
+ if (SrcNodePort >= 0)
+ O << ":s" << SrcNodePort;
+ O << " -> Node" << DestNodeID;
+ if (DestNodePort >= 0 && DTraits.hasEdgeDestLabels())
+ O << ":d" << DestNodePort;
+
+ if (!Attrs.empty())
+ O << "[" << Attrs << "]";
+ O << ";\n";
+ }
+
+ /// getOStream - Get the raw output stream into the graph file. Useful to
+ /// write fancy things using addCustomGraphFeatures().
+ raw_ostream &getOStream() {
+ return O;
+ }
+};
+
+template<typename GraphType>
+raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
+ bool ShortNames = false,
+ const Twine &Title = "") {
+ // Start the graph emission process...
+ GraphWriter<GraphType> W(O, G, ShortNames);
+
+ // Emit the graph.
+ W.writeGraph(Title.str());
+
+ return O;
+}
+
+template<typename GraphType>
+sys::Path WriteGraph(const GraphType &G, const Twine &Name,
+ bool ShortNames = false, const Twine &Title = "") {
+ std::string ErrMsg;
+ sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
+ if (Filename.isEmpty()) {
+ errs() << "Error: " << ErrMsg << "\n";
+ return Filename;
+ }
+ Filename.appendComponent((Name + ".dot").str());
+ if (Filename.makeUnique(true,&ErrMsg)) {
+ errs() << "Error: " << ErrMsg << "\n";
+ return sys::Path();
+ }
+
+ errs() << "Writing '" << Filename.str() << "'... ";
+
+ std::string ErrorInfo;
+ raw_fd_ostream O(Filename.c_str(), ErrorInfo);
+
+ if (ErrorInfo.empty()) {
+ llvm::WriteGraph(O, G, ShortNames, Title);
+ errs() << " done. \n";
+ } else {
+ errs() << "error opening file '" << Filename.str() << "' for writing!\n";
+ Filename.clear();
+ }
+
+ return Filename;
+}
+
+/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
+/// then cleanup. For use from the debugger.
+///
+template<typename GraphType>
+void ViewGraph(const GraphType &G, const Twine &Name,
+ bool ShortNames = false, const Twine &Title = "",
+ GraphProgram::Name Program = GraphProgram::DOT) {
+ sys::Path Filename = llvm::WriteGraph(G, Name, ShortNames, Title);
+
+ if (Filename.isEmpty())
+ return;
+
+ DisplayGraph(Filename, true, Program);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Host.h b/contrib/llvm/include/llvm/Support/Host.h
new file mode 100644
index 000000000000..b33101632268
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Host.h
@@ -0,0 +1,66 @@
+//===- llvm/Support/Host.h - Host machine characteristics --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods for querying the nature of the host machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_HOST_H
+#define LLVM_SYSTEM_HOST_H
+
+#include "llvm/ADT/StringMap.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ inline bool isLittleEndianHost() {
+ union {
+ int i;
+ char c;
+ };
+ i = 1;
+ return c;
+ }
+
+ inline bool isBigEndianHost() {
+ return !isLittleEndianHost();
+ }
+
+ /// getDefaultTargetTriple() - Return the default target triple the compiler
+ /// has been configured to produce code for.
+ ///
+ /// The target triple is a string in the format of:
+ /// CPU_TYPE-VENDOR-OPERATING_SYSTEM
+ /// or
+ /// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM
+ std::string getDefaultTargetTriple();
+
+ /// getHostCPUName - Get the LLVM name for the host CPU. The particular format
+ /// of the name is target dependent, and suitable for passing as -mcpu to the
+ /// target which matches the host.
+ ///
+ /// \return - The host CPU name, or empty if the CPU could not be determined.
+ std::string getHostCPUName();
+
+ /// getHostCPUFeatures - Get the LLVM names for the host CPU features.
+ /// The particular format of the names are target dependent, and suitable for
+ /// passing as -mattr to the target which matches the host.
+ ///
+ /// \param Features - A string mapping feature names to either
+ /// true (if enabled) or false (if disabled). This routine makes no guarantees
+ /// about exactly which features may appear in this map, except that they are
+ /// all valid LLVM feature names.
+ ///
+ /// \return - True on success.
+ bool getHostCPUFeatures(StringMap<bool> &Features);
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/IRBuilder.h b/contrib/llvm/include/llvm/Support/IRBuilder.h
new file mode 100644
index 000000000000..ef00e8ec24ed
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/IRBuilder.h
@@ -0,0 +1,1281 @@
+//===---- llvm/Support/IRBuilder.h - Builder for LLVM Instrs ----*- 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 IRBuilder class, which is used as a convenient way
+// to create LLVM instructions with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_IRBUILDER_H
+#define LLVM_SUPPORT_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/Support/ConstantFolder.h"
+
+namespace llvm {
+ class MDNode;
+
+/// IRBuilderDefaultInserter - This provides the default implementation of the
+/// IRBuilder 'InsertHelper' method that is called whenever an instruction is
+/// created by IRBuilder and needs to be inserted. By default, this inserts the
+/// instruction at the insertion point.
+template <bool preserveNames = true>
+class IRBuilderDefaultInserter {
+protected:
+ void InsertHelper(Instruction *I, const Twine &Name,
+ BasicBlock *BB, BasicBlock::iterator InsertPt) const {
+ if (BB) BB->getInstList().insert(InsertPt, I);
+ if (preserveNames)
+ I->setName(Name);
+ }
+};
+
+/// IRBuilderBase - Common base class shared among various IRBuilders.
+class IRBuilderBase {
+ DebugLoc CurDbgLocation;
+protected:
+ BasicBlock *BB;
+ BasicBlock::iterator InsertPt;
+ LLVMContext &Context;
+public:
+
+ IRBuilderBase(LLVMContext &context)
+ : Context(context) {
+ ClearInsertionPoint();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Builder configuration methods
+ //===--------------------------------------------------------------------===//
+
+ /// ClearInsertionPoint - Clear the insertion point: created instructions will
+ /// not be inserted into a block.
+ void ClearInsertionPoint() {
+ BB = 0;
+ }
+
+ BasicBlock *GetInsertBlock() const { return BB; }
+ BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
+ LLVMContext &getContext() const { return Context; }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// appended to the end of the specified block.
+ void SetInsertPoint(BasicBlock *TheBB) {
+ BB = TheBB;
+ InsertPt = BB->end();
+ }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// inserted before the specified instruction.
+ void SetInsertPoint(Instruction *I) {
+ BB = I->getParent();
+ InsertPt = I;
+ SetCurrentDebugLocation(I->getDebugLoc());
+ }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// inserted at the specified point.
+ void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
+ BB = TheBB;
+ InsertPt = IP;
+ }
+
+ /// SetInsertPoint(Use) - Find the nearest point that dominates this use, and
+ /// specify that created instructions should be inserted at this point.
+ void SetInsertPoint(Use &U) {
+ Instruction *UseInst = cast<Instruction>(U.getUser());
+ if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
+ BasicBlock *PredBB = Phi->getIncomingBlock(U);
+ assert(U != PredBB->getTerminator() && "critical edge not split");
+ SetInsertPoint(PredBB, PredBB->getTerminator());
+ return;
+ }
+ SetInsertPoint(UseInst);
+ }
+
+ /// SetCurrentDebugLocation - Set location information used by debugging
+ /// information.
+ void SetCurrentDebugLocation(const DebugLoc &L) {
+ CurDbgLocation = L;
+ }
+
+ /// getCurrentDebugLocation - Get location information used by debugging
+ /// information.
+ DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
+
+ /// SetInstDebugLocation - If this builder has a current debug location, set
+ /// it on the specified instruction.
+ void SetInstDebugLocation(Instruction *I) const {
+ if (!CurDbgLocation.isUnknown())
+ I->setDebugLoc(CurDbgLocation);
+ }
+
+ /// getCurrentFunctionReturnType - Get the return type of the current function
+ /// that we're emitting into.
+ Type *getCurrentFunctionReturnType() const;
+
+ /// InsertPoint - A saved insertion point.
+ class InsertPoint {
+ BasicBlock *Block;
+ BasicBlock::iterator Point;
+
+ public:
+ /// Creates a new insertion point which doesn't point to anything.
+ InsertPoint() : Block(0) {}
+
+ /// Creates a new insertion point at the given location.
+ InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint)
+ : Block(InsertBlock), Point(InsertPoint) {}
+
+ /// isSet - Returns true if this insert point is set.
+ bool isSet() const { return (Block != 0); }
+
+ llvm::BasicBlock *getBlock() const { return Block; }
+ llvm::BasicBlock::iterator getPoint() const { return Point; }
+ };
+
+ /// saveIP - Returns the current insert point.
+ InsertPoint saveIP() const {
+ return InsertPoint(GetInsertBlock(), GetInsertPoint());
+ }
+
+ /// saveAndClearIP - Returns the current insert point, clearing it
+ /// in the process.
+ InsertPoint saveAndClearIP() {
+ InsertPoint IP(GetInsertBlock(), GetInsertPoint());
+ ClearInsertionPoint();
+ return IP;
+ }
+
+ /// restoreIP - Sets the current insert point to a previously-saved
+ /// location.
+ void restoreIP(InsertPoint IP) {
+ if (IP.isSet())
+ SetInsertPoint(IP.getBlock(), IP.getPoint());
+ else
+ ClearInsertionPoint();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Miscellaneous creation methods.
+ //===--------------------------------------------------------------------===//
+
+ /// CreateGlobalString - Make a new global variable with an initializer that
+ /// has array of i8 type filled in with the nul terminated string value
+ /// specified. The new global variable will be marked mergable with any
+ /// others of the same contents. If Name is specified, it is the name of the
+ /// global variable created.
+ Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
+
+ /// getInt1 - Get a constant value representing either true or false.
+ ConstantInt *getInt1(bool V) {
+ return ConstantInt::get(getInt1Ty(), V);
+ }
+
+ /// getTrue - Get the constant value for i1 true.
+ ConstantInt *getTrue() {
+ return ConstantInt::getTrue(Context);
+ }
+
+ /// getFalse - Get the constant value for i1 false.
+ ConstantInt *getFalse() {
+ return ConstantInt::getFalse(Context);
+ }
+
+ /// getInt8 - Get a constant 8-bit value.
+ ConstantInt *getInt8(uint8_t C) {
+ return ConstantInt::get(getInt8Ty(), C);
+ }
+
+ /// getInt16 - Get a constant 16-bit value.
+ ConstantInt *getInt16(uint16_t C) {
+ return ConstantInt::get(getInt16Ty(), C);
+ }
+
+ /// getInt32 - Get a constant 32-bit value.
+ ConstantInt *getInt32(uint32_t C) {
+ return ConstantInt::get(getInt32Ty(), C);
+ }
+
+ /// getInt64 - Get a constant 64-bit value.
+ ConstantInt *getInt64(uint64_t C) {
+ return ConstantInt::get(getInt64Ty(), C);
+ }
+
+ /// getInt - Get a constant integer value.
+ ConstantInt *getInt(const APInt &AI) {
+ return ConstantInt::get(Context, AI);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Type creation methods
+ //===--------------------------------------------------------------------===//
+
+ /// getInt1Ty - Fetch the type representing a single bit
+ IntegerType *getInt1Ty() {
+ return Type::getInt1Ty(Context);
+ }
+
+ /// getInt8Ty - Fetch the type representing an 8-bit integer.
+ IntegerType *getInt8Ty() {
+ return Type::getInt8Ty(Context);
+ }
+
+ /// getInt16Ty - Fetch the type representing a 16-bit integer.
+ IntegerType *getInt16Ty() {
+ return Type::getInt16Ty(Context);
+ }
+
+ /// getInt32Ty - Fetch the type resepresenting a 32-bit integer.
+ IntegerType *getInt32Ty() {
+ return Type::getInt32Ty(Context);
+ }
+
+ /// getInt64Ty - Fetch the type representing a 64-bit integer.
+ IntegerType *getInt64Ty() {
+ return Type::getInt64Ty(Context);
+ }
+
+ /// getFloatTy - Fetch the type representing a 32-bit floating point value.
+ Type *getFloatTy() {
+ return Type::getFloatTy(Context);
+ }
+
+ /// getDoubleTy - Fetch the type representing a 64-bit floating point value.
+ Type *getDoubleTy() {
+ return Type::getDoubleTy(Context);
+ }
+
+ /// getVoidTy - Fetch the type representing void.
+ Type *getVoidTy() {
+ return Type::getVoidTy(Context);
+ }
+
+ PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
+ return Type::getInt8PtrTy(Context, AddrSpace);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Intrinsic creation methods
+ //===--------------------------------------------------------------------===//
+
+ /// CreateMemSet - Create and insert a memset to the specified pointer and the
+ /// specified value. If the pointer isn't an i8*, it will be converted. If a
+ /// TBAA tag is specified, it will be added to the instruction.
+ CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateMemCpy - Create and insert a memcpy between the specified pointers.
+ /// 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);
+ }
+
+ CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateMemMove - Create and insert a memmove between the specified
+ /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA
+ /// tag is specified, it will be added to the instruction.
+ CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0) {
+ return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
+ }
+
+ CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
+ bool isVolatile = false, MDNode *TBAATag = 0);
+
+ /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer
+ /// isn't i8* it will be converted.
+ CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0);
+
+ /// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer isn't
+ /// i8* it will be converted.
+ CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0);
+
+private:
+ Value *getCastedInt8PtrValue(Value *Ptr);
+};
+
+/// IRBuilder - This provides a uniform API for creating instructions and
+/// inserting them into a basic block: either at the end of a BasicBlock, or
+/// at a specific iterator location in a block.
+///
+/// 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.
+/// 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
+/// minimally folded constants. The fourth template argument allows clients to
+/// specify custom insertion hooks that are called on every newly created
+/// insertion.
+template<bool preserveNames = true, typename T = ConstantFolder,
+ typename Inserter = IRBuilderDefaultInserter<preserveNames> >
+class IRBuilder : public IRBuilderBase, public Inserter {
+ T Folder;
+ MDNode *DefaultFPMathTag;
+public:
+ IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(),
+ MDNode *FPMathTag = 0)
+ : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) {
+ }
+
+ explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C),
+ Folder(), DefaultFPMathTag(FPMathTag) {
+ }
+
+ explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(F),
+ DefaultFPMathTag(FPMathTag) {
+ SetInsertPoint(TheBB);
+ }
+
+ explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(),
+ DefaultFPMathTag(FPMathTag) {
+ SetInsertPoint(TheBB);
+ }
+
+ explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0)
+ : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
+ SetInsertPoint(IP);
+ SetCurrentDebugLocation(IP->getDebugLoc());
+ }
+
+ explicit IRBuilder(Use &U, MDNode *FPMathTag = 0)
+ : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
+ SetInsertPoint(U);
+ SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
+ }
+
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F,
+ MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(F),
+ DefaultFPMathTag(FPMathTag) {
+ SetInsertPoint(TheBB, IP);
+ }
+
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0)
+ : IRBuilderBase(TheBB->getContext()), Folder(),
+ DefaultFPMathTag(FPMathTag) {
+ SetInsertPoint(TheBB, IP);
+ }
+
+ /// getFolder - Get the constant folder being used.
+ const T &getFolder() { return Folder; }
+
+ /// getDefaultFPMathTag - Get the floating point math metadata being used.
+ MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
+
+ /// SetDefaultFPMathTag - Set the floating point math metadata to be used.
+ void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
+
+ /// isNamePreserving - Return true if this builder is configured to actually
+ /// add the requested names to IR created through it.
+ bool isNamePreserving() const { return preserveNames; }
+
+ /// Insert - Insert and return the specified instruction.
+ template<typename InstTy>
+ InstTy *Insert(InstTy *I, const Twine &Name = "") const {
+ this->InsertHelper(I, Name, BB, InsertPt);
+ if (!getCurrentDebugLocation().isUnknown())
+ this->SetInstDebugLocation(I);
+ return I;
+ }
+
+ /// Insert - No-op overload to handle constants.
+ Constant *Insert(Constant *C, const Twine& = "") const {
+ return C;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Terminators
+ //===--------------------------------------------------------------------===//
+
+ /// CreateRetVoid - Create a 'ret void' instruction.
+ ReturnInst *CreateRetVoid() {
+ return Insert(ReturnInst::Create(Context));
+ }
+
+ /// @verbatim
+ /// CreateRet - Create a 'ret <val>' instruction.
+ /// @endverbatim
+ ReturnInst *CreateRet(Value *V) {
+ return Insert(ReturnInst::Create(Context, V));
+ }
+
+ /// CreateAggregateRet - Create a sequence of N insertvalue instructions,
+ /// with one Value from the retVals array each, that build a aggregate
+ /// return value one value at a time, and a ret instruction to return
+ /// the resulting aggregate value. This is a convenience function for
+ /// code that uses aggregate return values as a vehicle for having
+ /// multiple return values.
+ ///
+ ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) {
+ Value *V = UndefValue::get(getCurrentFunctionReturnType());
+ for (unsigned i = 0; i != N; ++i)
+ V = CreateInsertValue(V, retVals[i], i, "mrv");
+ return Insert(ReturnInst::Create(Context, V));
+ }
+
+ /// CreateBr - Create an unconditional 'br label X' instruction.
+ BranchInst *CreateBr(BasicBlock *Dest) {
+ return Insert(BranchInst::Create(Dest));
+ }
+
+ /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
+ /// instruction.
+ BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
+ return Insert(BranchInst::Create(True, False, Cond));
+ }
+
+ /// CreateSwitch - Create a switch instruction with the specified value,
+ /// default dest, and with a hint for the number of cases that will be added
+ /// (for efficient allocation).
+ SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
+ return Insert(SwitchInst::Create(V, Dest, NumCases));
+ }
+
+ /// CreateIndirectBr - Create an indirect branch instruction with the
+ /// specified address operand, with an optional hint for the number of
+ /// destinations that will be added (for efficient allocation).
+ IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) {
+ return Insert(IndirectBrInst::Create(Addr, NumDests));
+ }
+
+ InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, const Twine &Name = "") {
+ return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
+ ArrayRef<Value *>()),
+ Name);
+ }
+ InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, Value *Arg1,
+ const Twine &Name = "") {
+ return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1),
+ Name);
+ }
+ InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, Value *Arg1,
+ Value *Arg2, Value *Arg3,
+ const Twine &Name = "") {
+ Value *Args[] = { Arg1, Arg2, Arg3 };
+ return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
+ Name);
+ }
+ /// CreateInvoke - Create an invoke instruction.
+ InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest, ArrayRef<Value *> Args,
+ const Twine &Name = "") {
+ return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
+ Name);
+ }
+
+ ResumeInst *CreateResume(Value *Exn) {
+ return Insert(ResumeInst::Create(Exn));
+ }
+
+ UnreachableInst *CreateUnreachable() {
+ return Insert(new UnreachableInst(Context));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Binary Operators
+ //===--------------------------------------------------------------------===//
+private:
+ BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc,
+ Value *LHS, Value *RHS,
+ const Twine &Name,
+ bool HasNUW, bool HasNSW) {
+ BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+
+ Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const {
+ if (!FPMathTag)
+ FPMathTag = DefaultFPMathTag;
+ if (FPMathTag)
+ I->setMetadata(LLVMContext::MD_fpmath, FPMathTag);
+ return I;
+ }
+public:
+ Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name,
+ HasNUW, HasNSW);
+ }
+ Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateAdd(LHS, RHS, Name, false, true);
+ }
+ Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateAdd(LHS, RHS, Name, true, false);
+ }
+ Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
+ 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);
+ }
+ Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateSub(LC, RC), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name,
+ HasNUW, HasNSW);
+ }
+ Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateSub(LHS, RHS, Name, false, true);
+ }
+ Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateSub(LHS, RHS, Name, true, false);
+ }
+ Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
+ 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);
+ }
+ Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateMul(LC, RC), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name,
+ HasNUW, HasNSW);
+ }
+ Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateMul(LHS, RHS, Name, false, true);
+ }
+ Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateMul(LHS, RHS, Name, true, false);
+ }
+ Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
+ 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);
+ }
+ Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateUDiv(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
+ }
+ Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateUDiv(LHS, RHS, Name, true);
+ }
+ Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateSDiv(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
+ }
+ Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateSDiv(LHS, RHS, Name, true);
+ }
+ Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
+ 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);
+ }
+ Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateURem(LC, RC), Name);
+ return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
+ }
+ Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateSRem(LC, RC), Name);
+ return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
+ }
+ Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "",
+ MDNode *FPMathTag = 0) {
+ 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);
+ }
+
+ Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name);
+ return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name,
+ HasNUW, HasNSW);
+ }
+ Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
+ HasNUW, HasNSW);
+ }
+ Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
+ HasNUW, HasNSW);
+ }
+
+ Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateLShr(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name);
+ }
+ Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+ }
+ Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+ }
+
+ Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "",
+ bool isExact = false) {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateAShr(LC, RC, isExact), Name);
+ if (!isExact)
+ return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
+ return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name);
+ }
+ Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+ }
+ Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
+ bool isExact = false) {
+ return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
+ }
+
+ Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *RC = dyn_cast<Constant>(RHS)) {
+ if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
+ return LHS; // LHS & -1 -> LHS
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ return Insert(Folder.CreateAnd(LC, RC), Name);
+ }
+ return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
+ }
+ Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
+ return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+ }
+ Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
+ return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+ }
+
+ Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *RC = dyn_cast<Constant>(RHS)) {
+ if (RC->isNullValue())
+ return LHS; // LHS | 0 -> LHS
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ return Insert(Folder.CreateOr(LC, RC), Name);
+ }
+ return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
+ }
+ Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
+ return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+ }
+ Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
+ return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+ }
+
+ Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateXor(LC, RC), Name);
+ return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
+ }
+ Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
+ return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+ }
+ Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
+ return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
+ }
+
+ Value *CreateBinOp(Instruction::BinaryOps Opc,
+ Value *LHS, Value *RHS, const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateBinOp(Opc, LC, RC), Name);
+ return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
+ }
+
+ Value *CreateNeg(Value *V, const Twine &Name = "",
+ bool HasNUW = false, bool HasNSW = false) {
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name);
+ BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
+ return CreateNeg(V, Name, false, true);
+ }
+ Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
+ return CreateNeg(V, Name, true, false);
+ }
+ 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);
+ }
+ Value *CreateNot(Value *V, const Twine &Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateNot(VC), Name);
+ return Insert(BinaryOperator::CreateNot(V), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0,
+ const Twine &Name = "") {
+ return Insert(new AllocaInst(Ty, ArraySize), Name);
+ }
+ // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
+ // converting the string to 'bool' for the isVolatile parameter.
+ LoadInst *CreateLoad(Value *Ptr, const char *Name) {
+ return Insert(new LoadInst(Ptr), Name);
+ }
+ LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") {
+ return Insert(new LoadInst(Ptr), Name);
+ }
+ LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") {
+ return Insert(new LoadInst(Ptr, 0, isVolatile), Name);
+ }
+ StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
+ return Insert(new StoreInst(Val, Ptr, isVolatile));
+ }
+ FenceInst *CreateFence(AtomicOrdering Ordering,
+ SynchronizationScope SynchScope = CrossThread) {
+ return Insert(new FenceInst(Context, Ordering, SynchScope));
+ }
+ AtomicCmpXchgInst *CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope = CrossThread) {
+ return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope));
+ }
+ AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope = CrossThread) {
+ return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SynchScope));
+ }
+ Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ size_t i, e;
+ for (i = 0, e = IdxList.size(); i != e; ++i)
+ if (!isa<Constant>(IdxList[i]))
+ break;
+ if (i == e)
+ return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
+ }
+ return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name);
+ }
+ Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ size_t i, e;
+ for (i = 0, e = IdxList.size(); i != e; ++i)
+ if (!isa<Constant>(IdxList[i]))
+ break;
+ if (i == e)
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
+ }
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
+ }
+ Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
+ return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ }
+ Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ }
+ Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+
+ return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ }
+ Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+ const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ }
+ Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const Twine &Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+
+ return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ }
+ Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+ const Twine &Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ }
+ Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
+
+ return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ }
+ Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
+ const Twine &Name = "") {
+ Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ }
+ Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ const Twine &Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt64Ty(Context), Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
+
+ return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ }
+ Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+ const Twine &Name = "") {
+ Value *Idxs[] = {
+ ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+ ConstantInt::get(Type::getInt64Ty(Context), Idx1)
+ };
+
+ if (Constant *PC = dyn_cast<Constant>(Ptr))
+ return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
+
+ return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ }
+ Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
+ return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
+ }
+
+ /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer
+ /// with "i8*" type instead of a pointer to array of i8.
+ Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
+ Value *gv = CreateGlobalString(Str, Name);
+ Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
+ Value *Args[] = { zero, zero };
+ return CreateInBoundsGEP(gv, Args, Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") {
+ return CreateCast(Instruction::Trunc, V, DestTy, Name);
+ }
+ Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") {
+ return CreateCast(Instruction::ZExt, V, DestTy, Name);
+ }
+ Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") {
+ return CreateCast(Instruction::SExt, V, DestTy, Name);
+ }
+ Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){
+ return CreateCast(Instruction::FPToUI, V, DestTy, Name);
+ }
+ Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){
+ return CreateCast(Instruction::FPToSI, V, DestTy, Name);
+ }
+ Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
+ return CreateCast(Instruction::UIToFP, V, DestTy, Name);
+ }
+ Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
+ return CreateCast(Instruction::SIToFP, V, DestTy, Name);
+ }
+ Value *CreateFPTrunc(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
+ }
+ Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") {
+ return CreateCast(Instruction::FPExt, V, DestTy, Name);
+ }
+ Value *CreatePtrToInt(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
+ }
+ Value *CreateIntToPtr(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
+ }
+ Value *CreateBitCast(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ return CreateCast(Instruction::BitCast, V, DestTy, Name);
+ }
+ Value *CreateZExtOrBitCast(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name);
+ return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name);
+ }
+ Value *CreateSExtOrBitCast(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name);
+ return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name);
+ }
+ Value *CreateTruncOrBitCast(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name);
+ return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name);
+ }
+ Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateCast(Op, VC, DestTy), Name);
+ return Insert(CastInst::Create(Op, V, DestTy), Name);
+ }
+ Value *CreatePointerCast(Value *V, Type *DestTy,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreatePointerCast(VC, DestTy), Name);
+ return Insert(CastInst::CreatePointerCast(V, DestTy), Name);
+ }
+ Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned,
+ const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
+ return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
+ }
+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
+public:
+ Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
+ if (V->getType() == DestTy)
+ return V;
+ if (Constant *VC = dyn_cast<Constant>(V))
+ return Insert(Folder.CreateFPCast(VC, DestTy), Name);
+ return Insert(CastInst::CreateFPCast(V, DestTy), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
+ }
+ Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
+ }
+ Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
+ }
+ Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
+ }
+ Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
+ }
+ Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
+ }
+ Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
+ }
+ Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
+ }
+ Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
+ }
+ Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
+ }
+
+ Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
+ }
+ Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
+ }
+ Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
+ return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
+ }
+
+ Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateICmp(P, LC, RC), Name);
+ return Insert(new ICmpInst(P, LHS, RHS), Name);
+ }
+ Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const Twine &Name = "") {
+ if (Constant *LC = dyn_cast<Constant>(LHS))
+ if (Constant *RC = dyn_cast<Constant>(RHS))
+ return Insert(Folder.CreateFCmp(P, LC, RC), Name);
+ return Insert(new FCmpInst(P, LHS, RHS), Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues,
+ const Twine &Name = "") {
+ return Insert(PHINode::Create(Ty, NumReservedValues), Name);
+ }
+
+ CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
+ return Insert(CallInst::Create(Callee), Name);
+ }
+ CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") {
+ return Insert(CallInst::Create(Callee, Arg), Name);
+ }
+ CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
+ const Twine &Name = "") {
+ Value *Args[] = { Arg1, Arg2 };
+ return Insert(CallInst::Create(Callee, Args), Name);
+ }
+ CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+ const Twine &Name = "") {
+ Value *Args[] = { Arg1, Arg2, Arg3 };
+ return Insert(CallInst::Create(Callee, Args), Name);
+ }
+ CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+ Value *Arg4, const Twine &Name = "") {
+ Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
+ return Insert(CallInst::Create(Callee, Args), Name);
+ }
+ CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
+ Value *Arg4, Value *Arg5, const Twine &Name = "") {
+ Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 };
+ return Insert(CallInst::Create(Callee, Args), Name);
+ }
+
+ CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
+ const Twine &Name = "") {
+ return Insert(CallInst::Create(Callee, Args), Name);
+ }
+
+ Value *CreateSelect(Value *C, Value *True, Value *False,
+ const Twine &Name = "") {
+ if (Constant *CC = dyn_cast<Constant>(C))
+ if (Constant *TC = dyn_cast<Constant>(True))
+ if (Constant *FC = dyn_cast<Constant>(False))
+ return Insert(Folder.CreateSelect(CC, TC, FC), Name);
+ return Insert(SelectInst::Create(C, True, False), Name);
+ }
+
+ VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") {
+ return Insert(new VAArgInst(List, Ty), Name);
+ }
+
+ Value *CreateExtractElement(Value *Vec, Value *Idx,
+ const Twine &Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(Vec))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Insert(Folder.CreateExtractElement(VC, IC), Name);
+ return Insert(ExtractElementInst::Create(Vec, Idx), Name);
+ }
+
+ Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
+ const Twine &Name = "") {
+ if (Constant *VC = dyn_cast<Constant>(Vec))
+ if (Constant *NC = dyn_cast<Constant>(NewElt))
+ if (Constant *IC = dyn_cast<Constant>(Idx))
+ return Insert(Folder.CreateInsertElement(VC, NC, IC), Name);
+ return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
+ }
+
+ Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
+ const Twine &Name = "") {
+ if (Constant *V1C = dyn_cast<Constant>(V1))
+ if (Constant *V2C = dyn_cast<Constant>(V2))
+ if (Constant *MC = dyn_cast<Constant>(Mask))
+ return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name);
+ return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
+ }
+
+ Value *CreateExtractValue(Value *Agg,
+ ArrayRef<unsigned> Idxs,
+ const Twine &Name = "") {
+ if (Constant *AggC = dyn_cast<Constant>(Agg))
+ return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
+ return Insert(ExtractValueInst::Create(Agg, Idxs), Name);
+ }
+
+ Value *CreateInsertValue(Value *Agg, Value *Val,
+ ArrayRef<unsigned> Idxs,
+ const Twine &Name = "") {
+ if (Constant *AggC = dyn_cast<Constant>(Agg))
+ if (Constant *ValC = dyn_cast<Constant>(Val))
+ return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
+ return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
+ }
+
+ LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
+ const Twine &Name = "") {
+ return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Utility creation methods
+ //===--------------------------------------------------------------------===//
+
+ /// CreateIsNull - Return an i1 value testing if \arg 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.
+ Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
+ return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
+ Name);
+ }
+
+ /// CreatePtrDiff - Return the i64 difference between two pointer values,
+ /// dividing out the size of the pointed-to objects. This is intended to
+ /// implement C-style pointer subtraction. As such, the pointers must be
+ /// appropriately aligned for their element types and pointing into the
+ /// same object.
+ Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
+ assert(LHS->getType() == RHS->getType() &&
+ "Pointer subtraction operand types must match!");
+ PointerType *ArgType = cast<PointerType>(LHS->getType());
+ Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
+ Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
+ Value *Difference = CreateSub(LHS_int, RHS_int);
+ return CreateExactSDiv(Difference,
+ ConstantExpr::getSizeOf(ArgType->getElementType()),
+ Name);
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/IRReader.h b/contrib/llvm/include/llvm/Support/IRReader.h
new file mode 100644
index 000000000000..6d8a9b30ae1f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/IRReader.h
@@ -0,0 +1,112 @@
+//===---- llvm/Support/IRReader.h - Reader for LLVM IR files ----*- 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 functions for reading LLVM IR. They support both
+// Bitcode and Assembly, automatically detecting the input format.
+//
+// These functions must be defined in a header file in order to avoid
+// library dependencies, since they reference both Bitcode and Assembly
+// functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_IRREADER_H
+#define LLVM_SUPPORT_IRREADER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/system_error.h"
+
+namespace llvm {
+
+ /// If the given MemoryBuffer holds a bitcode image, return a Module for it
+ /// which does lazy deserialization of function bodies. Otherwise, attempt to
+ /// parse it as LLVM Assembly and return a fully populated Module. This
+ /// function *always* takes ownership of the given MemoryBuffer.
+ inline Module *getLazyIRModule(MemoryBuffer *Buffer,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
+ (const unsigned char *)Buffer->getBufferEnd())) {
+ std::string ErrMsg;
+ Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
+ if (M == 0) {
+ Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
+ ErrMsg);
+ // ParseBitcodeFile does not take ownership of the Buffer in the
+ // case of an error.
+ delete Buffer;
+ }
+ return M;
+ }
+
+ return ParseAssembly(Buffer, 0, Err, Context);
+ }
+
+ /// If the given file holds a bitcode image, return a Module
+ /// for it which does lazy deserialization of function bodies. Otherwise,
+ /// attempt to parse it as LLVM Assembly and return a fully populated
+ /// Module.
+ inline Module *getLazyIRFileModule(const std::string &Filename,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ OwningPtr<MemoryBuffer> File;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
+ Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
+ "Could not open input file: " + ec.message());
+ return 0;
+ }
+
+ return getLazyIRModule(File.take(), Err, Context);
+ }
+
+ /// If the given MemoryBuffer holds a bitcode image, return a Module
+ /// for it. Otherwise, attempt to parse it as LLVM Assembly and return
+ /// a Module for it. This function *always* takes ownership of the given
+ /// MemoryBuffer.
+ inline Module *ParseIR(MemoryBuffer *Buffer,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ if (isBitcode((const unsigned char *)Buffer->getBufferStart(),
+ (const unsigned char *)Buffer->getBufferEnd())) {
+ std::string ErrMsg;
+ Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg);
+ if (M == 0)
+ Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
+ ErrMsg);
+ // ParseBitcodeFile does not take ownership of the Buffer.
+ delete Buffer;
+ return M;
+ }
+
+ return ParseAssembly(Buffer, 0, Err, Context);
+ }
+
+ /// If the given file holds a bitcode image, return a Module for it.
+ /// Otherwise, attempt to parse it as LLVM Assembly and return a Module
+ /// for it.
+ inline Module *ParseIRFile(const std::string &Filename,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ OwningPtr<MemoryBuffer> File;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
+ Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
+ "Could not open input file: " + ec.message());
+ return 0;
+ }
+
+ return ParseIR(File.take(), Err, Context);
+ }
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/IncludeFile.h b/contrib/llvm/include/llvm/Support/IncludeFile.h
new file mode 100644
index 000000000000..a9319725d477
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/IncludeFile.h
@@ -0,0 +1,79 @@
+//===- llvm/Support/IncludeFile.h - Ensure Linking Of Library ---*- 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 FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
+// macros.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_INCLUDEFILE_H
+#define LLVM_SYSTEM_INCLUDEFILE_H
+
+/// This macro is the public interface that IncludeFile.h exports. This gives
+/// us the option to implement the "link the definition" capability in any
+/// manner that we choose. All header files that depend on a specific .cpp
+/// file being linked at run time should use this macro instead of the
+/// IncludeFile class directly.
+///
+/// For example, foo.h would use:<br/>
+/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
+///
+/// And, foo.cp would use:<br/>
+/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
+#ifdef __GNUC__
+// If the `used' attribute is available, use it to create a variable
+// with an initializer that will force the linking of the defining file.
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+ namespace llvm { \
+ extern const char name ## LinkVar; \
+ __attribute__((used)) static const char *const name ## LinkObj = \
+ &name ## LinkVar; \
+ }
+#else
+// Otherwise use a constructor call.
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+ namespace llvm { \
+ extern const char name ## LinkVar; \
+ static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \
+ }
+#endif
+
+/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
+/// be used in a .cpp file to define the name referenced in a header file that
+/// will cause linkage of the .cpp file. It should only be used at extern level.
+#define DEFINING_FILE_FOR(name) \
+ namespace llvm { const char name ## LinkVar = 0; }
+
+namespace llvm {
+
+/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
+/// macro to make sure that the implementation of a header file is included
+/// into a tool that uses the header. This is solely
+/// to overcome problems linking .a files and not getting the implementation
+/// of compilation units we need. This is commonly an issue with the various
+/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
+/// they link faster and provide the smallest executables. However, sometimes
+/// those executables are too small, if the program doesn't reference something
+/// that might be needed, especially by a loaded share object. This little class
+/// helps to resolve that problem. The basic strategy is to use this class in
+/// a header file and pass the address of a variable to the constructor. If the
+/// variable is defined in the header file's corresponding .cpp file then all
+/// tools/libraries that \#include the header file will require the .cpp as
+/// well.
+/// For example:<br/>
+/// <tt>extern int LinkMyCodeStub;</tt><br/>
+/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
+/// @brief Class to ensure linking of corresponding object file.
+struct IncludeFile {
+ explicit IncludeFile(const void *);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/InstIterator.h b/contrib/llvm/include/llvm/Support/InstIterator.h
new file mode 100644
index 000000000000..7d3f8835098e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/InstIterator.h
@@ -0,0 +1,147 @@
+//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions of two iterators for iterating over the
+// instructions in a function. This is effectively a wrapper around a two level
+// iterator that can probably be genericized later.
+//
+// Note that this iterator gets invalidated any time that basic blocks or
+// instructions are moved around.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INSTITERATOR_H
+#define LLVM_SUPPORT_INSTITERATOR_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+
+namespace llvm {
+
+// This class implements inst_begin() & inst_end() for
+// inst_iterator and const_inst_iterator's.
+//
+template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
+class InstIterator {
+ typedef _BB_t BBty;
+ typedef _BB_i_t BBIty;
+ typedef _BI_t BIty;
+ typedef _II_t IIty;
+ _BB_t *BBs; // BasicBlocksType
+ _BB_i_t BB; // BasicBlocksType::iterator
+ _BI_t BI; // BasicBlock::iterator
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef IIty value_type;
+ typedef signed difference_type;
+ typedef IIty* pointer;
+ typedef IIty& reference;
+
+ // Default constructor
+ InstIterator() {}
+
+ // Copy constructor...
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(const InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<class M> InstIterator(M &m)
+ : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
+ if (BB != BBs->end()) {
+ BI = BB->begin();
+ advanceToNextBB();
+ }
+ }
+
+ template<class M> InstIterator(M &m, bool)
+ : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
+ }
+
+ // Accessors to get at the underlying iterators...
+ inline BBIty &getBasicBlockIterator() { return BB; }
+ inline BIty &getInstructionIterator() { return BI; }
+
+ inline reference operator*() const { return *BI; }
+ inline pointer operator->() const { return &operator*(); }
+
+ inline bool operator==(const InstIterator &y) const {
+ return BB == y.BB && (BB == BBs->end() || BI == y.BI);
+ }
+ inline bool operator!=(const InstIterator& y) const {
+ return !operator==(y);
+ }
+
+ InstIterator& operator++() {
+ ++BI;
+ advanceToNextBB();
+ return *this;
+ }
+ inline InstIterator operator++(int) {
+ InstIterator tmp = *this; ++*this; return tmp;
+ }
+
+ InstIterator& operator--() {
+ while (BB == BBs->end() || BI == BB->begin()) {
+ --BB;
+ BI = BB->end();
+ }
+ --BI;
+ return *this;
+ }
+ inline InstIterator operator--(int) {
+ InstIterator tmp = *this; --*this; return tmp;
+ }
+
+ inline bool atEnd() const { return BB == BBs->end(); }
+
+private:
+ inline void advanceToNextBB() {
+ // The only way that the II could be broken is if it is now pointing to
+ // the end() of the current BasicBlock and there are successor BBs.
+ while (BI == BB->end()) {
+ ++BB;
+ if (BB == BBs->end()) break;
+ BI = BB->begin();
+ }
+ }
+};
+
+
+typedef InstIterator<iplist<BasicBlock>,
+ Function::iterator, BasicBlock::iterator,
+ Instruction> inst_iterator;
+typedef InstIterator<const iplist<BasicBlock>,
+ Function::const_iterator,
+ BasicBlock::const_iterator,
+ const Instruction> const_inst_iterator;
+
+inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
+inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
+inline const_inst_iterator inst_begin(const Function *F) {
+ return const_inst_iterator(*F);
+}
+inline const_inst_iterator inst_end(const Function *F) {
+ return const_inst_iterator(*F, true);
+}
+inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
+inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
+inline const_inst_iterator inst_begin(const Function &F) {
+ return const_inst_iterator(F);
+}
+inline const_inst_iterator inst_end(const Function &F) {
+ return const_inst_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/InstVisitor.h b/contrib/llvm/include/llvm/Support/InstVisitor.h
new file mode 100644
index 000000000000..52de8f660dd1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/InstVisitor.h
@@ -0,0 +1,243 @@
+//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- 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_INSTVISITOR_H
+#define LLVM_SUPPORT_INSTVISITOR_H
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+// We operate on opaque instruction classes, so forward declare all instruction
+// types now...
+//
+#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
+#include "llvm/Instruction.def"
+
+#define DELEGATE(CLASS_TO_VISIT) \
+ return static_cast<SubClass*>(this)-> \
+ visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
+
+
+/// @brief Base class for instruction visitors
+///
+/// Instruction visitors are used when you want to perform different actions
+/// for different kinds of instructions without having to use lots of casts
+/// and a big switch statement (in your code, that is).
+///
+/// To define your own visitor, inherit from this class, specifying your
+/// new type for the 'SubClass' template parameter, and "override" visitXXX
+/// functions in your class. I say "override" because this class is defined
+/// in terms of statically resolved overloading, not virtual functions.
+///
+/// For example, here is a visitor that counts the number of malloc
+/// instructions processed:
+///
+/// /// Declare the class. Note that we derive from InstVisitor instantiated
+/// /// with _our new subclasses_ type.
+/// ///
+/// struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
+/// unsigned Count;
+/// CountAllocaVisitor() : Count(0) {}
+///
+/// void visitAllocaInst(AllocaInst &AI) { ++Count; }
+/// };
+///
+/// And this class would be used like this:
+/// CountAllocaVisitor CAV;
+/// CAV.visit(function);
+/// NumAllocas = CAV.Count;
+///
+/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
+/// Function, and Module, which recursively process all contained instructions.
+///
+/// Note that if you don't implement visitXXX for some instruction type,
+/// the visitXXX method for instruction superclass will be invoked. So
+/// if instructions are added in the future, they will be automatically
+/// supported, if you handle one of their superclasses.
+///
+/// The optional second template argument specifies the type that instruction
+/// visitation functions should return. If you specify this, you *MUST* provide
+/// an implementation of visitInstruction though!.
+///
+/// Note that this class is specifically designed as a template to avoid
+/// virtual function call overhead. Defining and using an InstVisitor is just
+/// as efficient as having your own switch statement over the instruction
+/// opcode.
+template<typename SubClass, typename RetTy=void>
+class InstVisitor {
+ //===--------------------------------------------------------------------===//
+ // Interface code - This is the public interface of the InstVisitor that you
+ // use to visit instructions...
+ //
+
+public:
+ // Generic visit method - Allow visitation to all instructions in a range
+ template<class Iterator>
+ void visit(Iterator Start, Iterator End) {
+ while (Start != End)
+ static_cast<SubClass*>(this)->visit(*Start++);
+ }
+
+ // Define visitors for functions and basic blocks...
+ //
+ void visit(Module &M) {
+ static_cast<SubClass*>(this)->visitModule(M);
+ visit(M.begin(), M.end());
+ }
+ void visit(Function &F) {
+ static_cast<SubClass*>(this)->visitFunction(F);
+ visit(F.begin(), F.end());
+ }
+ void visit(BasicBlock &BB) {
+ static_cast<SubClass*>(this)->visitBasicBlock(BB);
+ visit(BB.begin(), BB.end());
+ }
+
+ // Forwarding functions so that the user can visit with pointers AND refs.
+ void visit(Module *M) { visit(*M); }
+ void visit(Function *F) { visit(*F); }
+ void visit(BasicBlock *BB) { visit(*BB); }
+ RetTy visit(Instruction *I) { return visit(*I); }
+
+ // visit - Finally, code to visit an instruction...
+ //
+ RetTy visit(Instruction &I) {
+ switch (I.getOpcode()) {
+ default: llvm_unreachable("Unknown instruction type encountered!");
+ // Build the switch statement using the Instruction.def file...
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ case Instruction::OPCODE: return \
+ static_cast<SubClass*>(this)-> \
+ visit##OPCODE(static_cast<CLASS&>(I));
+#include "llvm/Instruction.def"
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Visitation functions... these functions provide default fallbacks in case
+ // the user does not specify what to do for a particular instruction type.
+ // The default behavior is to generalize the instruction type to its subtype
+ // and try visiting the subtype. All of this should be inlined perfectly,
+ // because there are no virtual functions to get in the way.
+ //
+
+ // When visiting a module, function or basic block directly, these methods get
+ // called to indicate when transitioning into a new unit.
+ //
+ void visitModule (Module &M) {}
+ void visitFunction (Function &F) {}
+ void visitBasicBlock(BasicBlock &BB) {}
+
+ // Define instruction specific visitor functions that can be overridden to
+ // handle SPECIFIC instructions. These functions automatically define
+ // visitMul to proxy to visitBinaryOperator for instance in case the user does
+ // not need this generality.
+ //
+ // The one problem case we have to handle here though is that the PHINode
+ // class and opcode name are the exact same. Because of this, we cannot
+ // define visitPHINode (the inst version) to forward to visitPHINode (the
+ // generic version) without multiply defined symbols and recursion. To handle
+ // this, we do not autoexpand "Other" instructions, we do it manually.
+ //
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+#include "llvm/Instruction.def"
+
+ // Specific Instruction type classes... note that all of the casts are
+ // necessary because we use the instruction classes as opaque types...
+ //
+ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);}
+ RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);}
+ RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);}
+ RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction);}
+ RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);}
+ RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction);}
+ RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst);}
+ RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst);}
+ RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst);}
+ RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst);}
+ RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);}
+ RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);}
+ RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);}
+ RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
+ RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
+ RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);}
+ RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
+ RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);}
+ RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);}
+ RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
+ RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
+ RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+
+ // Call and Invoke are slightly different as they delegate first through
+ // a generic CallSite visitor.
+ RetTy visitCallInst(CallInst &I) {
+ return static_cast<SubClass*>(this)->visitCallSite(&I);
+ }
+ RetTy visitInvokeInst(InvokeInst &I) {
+ return static_cast<SubClass*>(this)->visitCallSite(&I);
+ }
+
+ // Next level propagators: If the user does not overload a specific
+ // instruction type, they can overload one of these to get the whole class
+ // of instructions...
+ //
+ RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
+ RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
+ RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
+ RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction);}
+ RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
+
+ // Provide a special visitor for a 'callsite' that visits both calls and
+ // invokes. When unimplemented, properly delegates to either the terminator or
+ // regular instruction visitor.
+ RetTy visitCallSite(CallSite CS) {
+ assert(CS);
+ Instruction &I = *CS.getInstruction();
+ if (CS.isCall())
+ DELEGATE(Instruction);
+
+ assert(CS.isInvoke());
+ DELEGATE(TerminatorInst);
+ }
+
+ // If the user wants a 'default' case, they can choose to override this
+ // function. If this function is not overloaded in the user's subclass, then
+ // this instruction just gets ignored.
+ //
+ // Note that you MUST override this function if your return type is not void.
+ //
+ void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+};
+
+#undef DELEGATE
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/LeakDetector.h b/contrib/llvm/include/llvm/Support/LeakDetector.h
new file mode 100644
index 000000000000..501a9db72c15
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/LeakDetector.h
@@ -0,0 +1,92 @@
+//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- 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 class that can be used to provide very simple memory leak
+// checks for an API. Basically LLVM uses this to make sure that Instructions,
+// for example, are deleted when they are supposed to be, and not leaked away.
+//
+// When compiling with NDEBUG (Release build), this class does nothing, thus
+// adding no checking overhead to release builds. Note that this class is
+// implemented in a very simple way, requiring completely manual manipulation
+// and checking for garbage, but this is intentional: users should not be using
+// this API, only other APIs should.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
+#define LLVM_SUPPORT_LEAKDETECTOR_H
+
+#include <string>
+
+namespace llvm {
+
+class LLVMContext;
+class Value;
+
+struct LeakDetector {
+ /// addGarbageObject - Add a pointer to the internal set of "garbage" object
+ /// pointers. This should be called when objects are created, or if they are
+ /// taken out of an owning collection.
+ ///
+ static void addGarbageObject(void *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// removeGarbageObject - Remove a pointer from our internal representation of
+ /// our "garbage" objects. This should be called when an object is added to
+ /// an "owning" collection.
+ ///
+ static void removeGarbageObject(void *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// checkForGarbage - Traverse the internal representation of garbage
+ /// pointers. If there are any pointers that have been add'ed, but not
+ /// remove'd, big obnoxious warnings about memory leaks are issued.
+ ///
+ /// The specified message will be printed indicating when the check was
+ /// performed.
+ ///
+ static void checkForGarbage(LLVMContext &C, const std::string &Message) {
+#ifndef NDEBUG
+ checkForGarbageImpl(C, Message);
+#endif
+ }
+
+ /// Overload the normal methods to work better with Value*'s because they are
+ /// by far the most common in LLVM. This does not affect the actual
+ /// functioning of this class, it just makes the warning messages nicer.
+ ///
+ static void addGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+ static void removeGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+private:
+ // If we are debugging, the actual implementations will be called...
+ static void addGarbageObjectImpl(const Value *Object);
+ static void removeGarbageObjectImpl(const Value *Object);
+ static void addGarbageObjectImpl(void *Object);
+ static void removeGarbageObjectImpl(void *Object);
+ static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Locale.h b/contrib/llvm/include/llvm/Support/Locale.h
new file mode 100644
index 000000000000..b0f12958029f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Locale.h
@@ -0,0 +1,17 @@
+#ifndef LLVM_SUPPORT_LOCALE
+#define LLVM_SUPPORT_LOCALE
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+namespace sys {
+namespace locale {
+
+int columnWidth(StringRef s);
+bool isPrint(int c);
+
+}
+}
+}
+
+#endif // LLVM_SUPPORT_LOCALE
diff --git a/contrib/llvm/include/llvm/Support/LockFileManager.h b/contrib/llvm/include/llvm/Support/LockFileManager.h
new file mode 100644
index 000000000000..e2fa8ebc56e4
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/LockFileManager.h
@@ -0,0 +1,74 @@
+//===--- LockFileManager.h - File-level locking utility ---------*- 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_LOCKFILEMANAGER_H
+#define LLVM_SUPPORT_LOCKFILEMANAGER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/system_error.h"
+#include <utility> // for std::pair
+
+namespace llvm {
+
+/// \brief Class that manages the creation of a lock file to aid
+/// implicit coordination between different processes.
+///
+/// The implicit coordination works by creating a ".lock" file alongside
+/// the file that we're coordinating for, using the atomicity of the file
+/// system to ensure that only a single process can create that ".lock" file.
+/// When the lock file is removed, the owning process has finished the
+/// operation.
+class LockFileManager {
+public:
+ /// \brief Describes the state of a lock file.
+ enum LockFileState {
+ /// \brief The lock file has been created and is owned by this instance
+ /// of the object.
+ LFS_Owned,
+ /// \brief The lock file already exists and is owned by some other
+ /// instance.
+ LFS_Shared,
+ /// \brief An error occurred while trying to create or find the lock
+ /// file.
+ LFS_Error
+ };
+
+private:
+ SmallString<128> LockFileName;
+ SmallString<128> UniqueLockFileName;
+
+ Optional<std::pair<std::string, int> > Owner;
+ Optional<error_code> Error;
+
+ LockFileManager(const LockFileManager &);
+ LockFileManager &operator=(const LockFileManager &);
+
+ static Optional<std::pair<std::string, int> >
+ readLockFile(StringRef LockFileName);
+
+ static bool processStillExecuting(StringRef Hostname, int PID);
+
+public:
+
+ LockFileManager(StringRef FileName);
+ ~LockFileManager();
+
+ /// \brief Determine the state of the lock file.
+ LockFileState getState() const;
+
+ operator LockFileState() const { return getState(); }
+
+ /// \brief For a shared lock, wait until the owner releases the lock.
+ void waitForUnlock();
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
diff --git a/contrib/llvm/include/llvm/Support/MDBuilder.h b/contrib/llvm/include/llvm/Support/MDBuilder.h
new file mode 100644
index 000000000000..40f028a43274
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/MDBuilder.h
@@ -0,0 +1,118 @@
+//===---- llvm/Support/MDBuilder.h - Builder for LLVM metadata --*- 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 MDBuilder class, which is used as a convenient way to
+// create LLVM metadata with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MDBUILDER_H
+#define LLVM_SUPPORT_MDBUILDER_H
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Metadata.h"
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+ class MDBuilder {
+ LLVMContext &Context;
+
+ public:
+ MDBuilder(LLVMContext &context) : Context(context) {}
+
+ /// \brief Return the given string as metadata.
+ MDString *createString(StringRef Str) {
+ return MDString::get(Context, Str);
+ }
+
+ //===------------------------------------------------------------------===//
+ // FPMath metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata with the given settings. The special value 0.0
+ /// for the Accuracy parameter indicates the default (maximal precision)
+ /// setting.
+ MDNode *createFPMath(float Accuracy) {
+ if (Accuracy == 0.0)
+ return 0;
+ assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
+ Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy);
+ return MDNode::get(Context, Op);
+ }
+
+
+ //===------------------------------------------------------------------===//
+ // Range metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata describing the range [Lo, Hi).
+ MDNode *createRange(const APInt &Lo, const APInt &Hi) {
+ assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
+ // If the range is everything then it is useless.
+ if (Hi == Lo)
+ return 0;
+
+ // Return the range [Lo, Hi).
+ Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
+ Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) };
+ return MDNode::get(Context, Range);
+ }
+
+
+ //===------------------------------------------------------------------===//
+ // TBAA metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata appropriate for a TBAA root node. Each returned
+ /// node is distinct from all other metadata and will never be identified
+ /// (uniqued) with anything else.
+ MDNode *createAnonymousTBAARoot() {
+ // To ensure uniqueness the root node is self-referential.
+ MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>());
+ MDNode *Root = MDNode::get(Context, Dummy);
+ // At this point we have
+ // !0 = metadata !{} <- dummy
+ // !1 = metadata !{metadata !0} <- root
+ // Replace the dummy operand with the root node itself and delete the dummy.
+ Root->replaceOperandWith(0, Root);
+ MDNode::deleteTemporary(Dummy);
+ // We now have
+ // !1 = metadata !{metadata !1} <- self-referential root
+ return Root;
+ }
+
+ /// \brief Return metadata appropriate for a TBAA root node with the given
+ /// name. This may be identified (uniqued) with other roots with the same
+ /// name.
+ MDNode *createTBAARoot(StringRef Name) {
+ return MDNode::get(Context, createString(Name));
+ }
+
+ /// \brief Return metadata for a non-root TBAA node with the given name,
+ /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
+ MDNode *createTBAANode(StringRef Name, MDNode *Parent,
+ bool isConstant = false) {
+ if (isConstant) {
+ Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
+ Value *Ops[3] = { createString(Name), Parent, Flags };
+ return MDNode::get(Context, Ops);
+ } else {
+ Value *Ops[2] = { createString(Name), Parent };
+ return MDNode::get(Context, Ops);
+ }
+ }
+
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/MachO.h b/contrib/llvm/include/llvm/Support/MachO.h
new file mode 100644
index 000000000000..44a7a791c522
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/MachO.h
@@ -0,0 +1,714 @@
+//===-- llvm/Support/MachO.h - The MachO file format ------------*- 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 manifest constants for the MachO object file format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MACHO_H
+#define LLVM_SUPPORT_MACHO_H
+
+#include "llvm/Support/DataTypes.h"
+
+// NOTE: The enums in this file are intentially named to be different than those
+// in the headers in /usr/include/mach (on darwin systems) to avoid conflicts
+// with those macros.
+namespace llvm {
+ namespace MachO {
+ // Enums from <mach-o/loader.h>
+ enum {
+ // Constants for the "magic" field in llvm::MachO::mach_header and
+ // llvm::MachO::mach_header_64
+ HeaderMagic32 = 0xFEEDFACEu, // MH_MAGIC
+ HeaderMagic32Swapped = 0xCEFAEDFEu, // MH_CIGAM
+ HeaderMagic64 = 0xFEEDFACFu, // MH_MAGIC_64
+ HeaderMagic64Swapped = 0xCFFAEDFEu, // MH_CIGAM_64
+ UniversalMagic = 0xCAFEBABEu, // FAT_MAGIC
+ UniversalMagicSwapped = 0xBEBAFECAu, // FAT_CIGAM
+
+ // Constants for the "filetype" field in llvm::MachO::mach_header and
+ // llvm::MachO::mach_header_64
+ HeaderFileTypeObject = 0x1u, // MH_OBJECT
+ HeaderFileTypeExecutable = 0x2u, // MH_EXECUTE
+ HeaderFileTypeFixedVMShlib = 0x3u, // MH_FVMLIB
+ HeaderFileTypeCore = 0x4u, // MH_CORE
+ HeaderFileTypePreloadedExecutable = 0x5u, // MH_PRELOAD
+ HeaderFileTypeDynamicShlib = 0x6u, // MH_DYLIB
+ HeaderFileTypeDynamicLinkEditor = 0x7u, // MH_DYLINKER
+ HeaderFileTypeBundle = 0x8u, // MH_BUNDLE
+ HeaderFileTypeDynamicShlibStub = 0x9u, // MH_DYLIB_STUB
+ HeaderFileTypeDSYM = 0xAu, // MH_DSYM
+ HeaderFileTypeKextBundle = 0xBu, // MH_KEXT_BUNDLE
+
+ // Constant bits for the "flags" field in llvm::MachO::mach_header and
+ // llvm::MachO::mach_header_64
+ HeaderFlagBitNoUndefinedSymbols = 0x00000001u, // MH_NOUNDEFS
+ HeaderFlagBitIsIncrementalLinkObject= 0x00000002u, // MH_INCRLINK
+ HeaderFlagBitIsDynamicLinkObject = 0x00000004u, // MH_DYLDLINK
+ HeaderFlagBitBindAtLoad = 0x00000008u, // MH_BINDATLOAD
+ HeaderFlagBitPrebound = 0x00000010u, // MH_PREBOUND
+ HeaderFlagBitSplitSegments = 0x00000020u, // MH_SPLIT_SEGS
+ HeaderFlagBitLazyInit = 0x00000040u, // MH_LAZY_INIT
+ HeaderFlagBitTwoLevelNamespace = 0x00000080u, // MH_TWOLEVEL
+ HeaderFlagBitForceFlatNamespace = 0x00000100u, // MH_FORCE_FLAT
+ HeaderFlagBitNoMultipleDefintions = 0x00000200u, // MH_NOMULTIDEFS
+ HeaderFlagBitNoFixPrebinding = 0x00000400u, // MH_NOFIXPREBINDING
+ HeaderFlagBitPrebindable = 0x00000800u, // MH_PREBINDABLE
+ HeaderFlagBitAllModulesBound = 0x00001000u, // MH_ALLMODSBOUND
+ HeaderFlagBitSubsectionsViaSymbols = 0x00002000u, // MH_SUBSECTIONS_VIA_SYMBOLS
+ HeaderFlagBitCanonical = 0x00004000u, // MH_CANONICAL
+ HeaderFlagBitWeakDefines = 0x00008000u, // MH_WEAK_DEFINES
+ HeaderFlagBitBindsToWeak = 0x00010000u, // MH_BINDS_TO_WEAK
+ HeaderFlagBitAllowStackExecution = 0x00020000u, // MH_ALLOW_STACK_EXECUTION
+ HeaderFlagBitRootSafe = 0x00040000u, // MH_ROOT_SAFE
+ HeaderFlagBitSetUIDSafe = 0x00080000u, // MH_SETUID_SAFE
+ HeaderFlagBitNoReexportedDylibs = 0x00100000u, // MH_NO_REEXPORTED_DYLIBS
+ HeaderFlagBitPIE = 0x00200000u, // MH_PIE
+ HeaderFlagBitDeadStrippableDylib = 0x00400000u, // MH_DEAD_STRIPPABLE_DYLIB
+
+ // Constants for the "cmd" field in llvm::MachO::load_command
+ LoadCommandDynamicLinkerRequired = 0x80000000u, // LC_REQ_DYLD
+ LoadCommandSegment32 = 0x00000001u, // LC_SEGMENT
+ LoadCommandSymtab = 0x00000002u, // LC_SYMTAB
+ LoadCommandSymSeg = 0x00000003u, // LC_SYMSEG
+ LoadCommandThread = 0x00000004u, // LC_THREAD
+ LoadCommandUnixThread = 0x00000005u, // LC_UNIXTHREAD
+ LoadCommandFixedVMShlibLoad = 0x00000006u, // LC_LOADFVMLIB
+ LoadCommandFixedVMShlibIdent = 0x00000007u, // LC_IDFVMLIB
+ LoadCommandIdent = 0x00000008u, // LC_IDENT
+ LoadCommandFixedVMFileInclusion = 0x00000009u, // LC_FVMFILE
+ LoadCommandPrePage = 0x0000000Au, // LC_PREPAGE
+ LoadCommandDynamicSymtabInfo = 0x0000000Bu, // LC_DYSYMTAB
+ LoadCommandDylibLoad = 0x0000000Cu, // LC_LOAD_DYLIB
+ LoadCommandDylibIdent = 0x0000000Du, // LC_ID_DYLIB
+ LoadCommandDynamicLinkerLoad = 0x0000000Eu, // LC_LOAD_DYLINKER
+ LoadCommandDynamicLinkerIdent = 0x0000000Fu, // LC_ID_DYLINKER
+ LoadCommandDylibPrebound = 0x00000010u, // LC_PREBOUND_DYLIB
+ LoadCommandRoutines32 = 0x00000011u, // LC_ROUTINES
+ LoadCommandSubFramework = 0x00000012u, // LC_SUB_FRAMEWORK
+ LoadCommandSubUmbrella = 0x00000013u, // LC_SUB_UMBRELLA
+ LoadCommandSubClient = 0x00000014u, // LC_SUB_CLIENT
+ LoadCommandSubLibrary = 0x00000015u, // LC_SUB_LIBRARY
+ LoadCommandTwoLevelHints = 0x00000016u, // LC_TWOLEVEL_HINTS
+ LoadCommandPreBindChecksum = 0x00000017u, // LC_PREBIND_CKSUM
+ LoadCommandDylibLoadWeak = 0x80000018u, // LC_LOAD_WEAK_DYLIB
+ LoadCommandSegment64 = 0x00000019u, // LC_SEGMENT_64
+ LoadCommandRoutines64 = 0x0000001Au, // LC_ROUTINES_64
+ LoadCommandUUID = 0x0000001Bu, // LC_UUID
+ LoadCommandRunpath = 0x8000001Cu, // LC_RPATH
+ LoadCommandCodeSignature = 0x0000001Du, // LC_CODE_SIGNATURE
+ LoadCommandSegmentSplitInfo = 0x0000001Eu, // LC_SEGMENT_SPLIT_INFO
+ LoadCommandDylibReexport = 0x8000001Fu, // LC_REEXPORT_DYLIB
+ LoadCommandDylibLazyLoad = 0x00000020u, // LC_LAZY_LOAD_DYLIB
+ LoadCommandEncryptionInfo = 0x00000021u, // LC_ENCRYPTION_INFO
+ LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO
+ LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY
+ LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB
+ LoadCommandVersionMinMacOSX = 0x00000024u, // LC_VERSION_MIN_MACOSX
+ LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS
+ LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS
+ LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT
+ LoadCommandMain = 0x80000028u, // LC_MAIN
+ LoadCommandDataInCode = 0x00000029u, // LC_DATA_IN_CODE
+ LoadCommandSourceVersion = 0x0000002Au, // LC_SOURCE_VERSION
+ LoadCommandCodeSignDRs = 0x0000002Bu, // LC_DYLIB_CODE_SIGN_DRS
+
+ // Constant bits for the "flags" field in llvm::MachO::segment_command
+ SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM
+ SegmentCommandFlagBitFixedVMLibrary = 0x2u, // SG_FVMLIB
+ SegmentCommandFlagBitNoRelocations = 0x4u, // SG_NORELOC
+ SegmentCommandFlagBitProtectedVersion1 = 0x8u, // SG_PROTECTED_VERSION_1
+
+
+ // Constant masks for the "flags" field in llvm::MachO::section and
+ // llvm::MachO::section_64
+ SectionFlagMaskSectionType = 0x000000ffu, // SECTION_TYPE
+ SectionFlagMaskAllAttributes = 0xffffff00u, // SECTION_ATTRIBUTES
+ SectionFlagMaskUserAttributes = 0xff000000u, // SECTION_ATTRIBUTES_USR
+ SectionFlagMaskSystemAttributes = 0x00ffff00u, // SECTION_ATTRIBUTES_SYS
+
+ // Constant masks for the "flags[7:0]" field in llvm::MachO::section and
+ // llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
+ SectionTypeRegular = 0x00u, // S_REGULAR
+ SectionTypeZeroFill = 0x01u, // S_ZEROFILL
+ SectionTypeCStringLiterals = 0x02u, // S_CSTRING_LITERALS
+ SectionType4ByteLiterals = 0x03u, // S_4BYTE_LITERALS
+ SectionType8ByteLiterals = 0x04u, // S_8BYTE_LITERALS
+ SectionTypeLiteralPointers = 0x05u, // S_LITERAL_POINTERS
+ SectionTypeNonLazySymbolPointers = 0x06u, // S_NON_LAZY_SYMBOL_POINTERS
+ SectionTypeLazySymbolPointers = 0x07u, // S_LAZY_SYMBOL_POINTERS
+ SectionTypeSymbolStubs = 0x08u, // S_SYMBOL_STUBS
+ SectionTypeModuleInitFunctionPointers = 0x09u, // S_MOD_INIT_FUNC_POINTERS
+ SectionTypeModuleTermFunctionPointers = 0x0au, // S_MOD_TERM_FUNC_POINTERS
+ SectionTypeCoalesced = 0x0bu, // S_COALESCED
+ SectionTypeZeroFillLarge = 0x0cu, // S_GB_ZEROFILL
+ SectionTypeInterposing = 0x0du, // S_INTERPOSING
+ SectionType16ByteLiterals = 0x0eu, // S_16BYTE_LITERALS
+ SectionTypeDTraceObjectFormat = 0x0fu, // S_DTRACE_DOF
+ SectionTypeLazyDylibSymbolPointers = 0x10u, // S_LAZY_DYLIB_SYMBOL_POINTERS
+
+ // Constant masks for the "flags[31:24]" field in llvm::MachO::section and
+ // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
+ SectionAttrUserPureInstructions = 0x80000000u, // S_ATTR_PURE_INSTRUCTIONS
+ SectionAttrUserNoTableOfContents = 0x40000000u, // S_ATTR_NO_TOC
+ SectionAttrUserCanStripStaticSymbols = 0x20000000u, // S_ATTR_STRIP_STATIC_SYMS
+ SectionAttrUserNoDeadStrip = 0x10000000u, // S_ATTR_NO_DEAD_STRIP
+ SectionAttrUserLiveSupport = 0x08000000u, // S_ATTR_LIVE_SUPPORT
+ SectionAttrUserSelfModifyingCode = 0x04000000u, // S_ATTR_SELF_MODIFYING_CODE
+ SectionAttrUserDebug = 0x02000000u, // S_ATTR_DEBUG
+
+ // Constant masks for the "flags[23:8]" field in llvm::MachO::section and
+ // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
+ SectionAttrSytemSomeInstructions = 0x00000400u, // S_ATTR_SOME_INSTRUCTIONS
+ SectionAttrSytemHasExternalRelocations= 0x00000200u, // S_ATTR_EXT_RELOC
+ SectionAttrSytemHasLocalRelocations = 0x00000100u, // S_ATTR_LOC_RELOC
+
+ IndirectSymbolLocal = 0x80000000u, // INDIRECT_SYMBOL_LOCAL
+ IndirectSymbolAbsolute = 0x40000000u, // INDIRECT_SYMBOL_ABS
+
+ RebaseTypePointer = 1u, // REBASE_TYPE_POINTER
+ RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32
+ RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
+
+ RebaseOpcodeMask = 0xF0u, // REBASE_OPCODE_MASK
+ RebaseImmediateMask = 0x0Fu, // REBASE_IMMEDIATE_MASK
+ RebaseOpcodeDone = 0x00u, // REBASE_OPCODE_DONE
+ RebaseOpcodeSetTypeImmediate = 0x10u, // REBASE_OPCODE_SET_TYPE_IMM
+ RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+ RebaseOpcodeAddAddressULEB = 0x30u, // REBASE_OPCODE_ADD_ADDR_ULEB
+ RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
+ RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
+ RebaseOpcodeDoRebaseULEBTimes = 0x60u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES
+ RebaseOpcodeDoRebaseAddAddressULEB = 0x70u, // REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
+ RebaseOpcodeDoRebaseULEBTimesSkippingULEB = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
+
+
+ BindTypePointer = 1u, // BIND_TYPE_POINTER
+ BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
+ BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
+
+ BindSpecialDylibSelf = 0u, // BIND_SPECIAL_DYLIB_SELF
+ BindSpecialDylibMainExecutable = -1u, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
+ BindSpecialDylibFlatLookup = -2u, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
+
+ BindSymbolFlagsWeakImport = 0x1u, // BIND_SYMBOL_FLAGS_WEAK_IMPORT
+ BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
+
+ BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
+ BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
+ BindOpcodeDone = 0x00u, // BIND_OPCODE_DONE
+ BindOpcodeSetDylibOrdinalImmediate = 0x10u, // BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
+ BindOpcodeSetDylibOrdinalULEB = 0x20u, // BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
+ BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
+ BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+ BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
+ BindOpcodeSetAppendSLEB = 0x60u, // BIND_OPCODE_SET_ADDEND_SLEB
+ BindOpcodeSetSegmentAndOffsetULEB = 0x70u, // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+ BindOpcodeAddAddressULEB = 0x80u, // BIND_OPCODE_ADD_ADDR_ULEB
+ BindOpcodeDoBind = 0x90u, // BIND_OPCODE_DO_BIND
+ BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
+ BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
+ BindOpcodeDoBindULEBTimesSkippingULEB = 0xC0u, // BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
+
+ ExportSymbolFlagsKindMask = 0x03u, // EXPORT_SYMBOL_FLAGS_KIND_MASK
+ ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
+ ExportSymbolFlagsKindThreadLocal = 0x01u, // EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
+ ExportSymbolFlagsWeakDefinition = 0x04u, // EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
+ ExportSymbolFlagsIndirectDefinition = 0x08u, // EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION
+ ExportSymbolFlagsHasSpecializations = 0x10u, // EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS
+
+
+ // Constant masks for the "n_type" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ NlistMaskStab = 0xe0, // N_STAB
+ NlistMaskPrivateExternal = 0x10, // N_PEXT
+ NlistMaskType = 0x0e, // N_TYPE
+ NlistMaskExternal = 0x01, // N_EXT
+
+ // Constants for the "n_type & N_TYPE" llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ NListTypeUndefined = 0x0u, // N_UNDF
+ NListTypeAbsolute = 0x2u, // N_ABS
+ NListTypeSection = 0xeu, // N_SECT
+ NListTypePreboundUndefined = 0xcu, // N_PBUD
+ NListTypeIndirect = 0xau, // N_INDR
+
+ // Constant masks for the "n_sect" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64
+ NListSectionNoSection = 0u, // NO_SECT
+ NListSectionMaxSection = 0xffu, // MAX_SECT
+
+ NListDescWeakRef = 0x40u,
+ NListDescWeakDef = 0x80u,
+
+ // Constant values for the "n_type" field in llvm::MachO::nlist and
+ // llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
+ StabGlobalSymbol = 0x20u, // N_GSYM
+ StabFunctionName = 0x22u, // N_FNAME
+ StabFunction = 0x24u, // N_FUN
+ StabStaticSymbol = 0x26u, // N_STSYM
+ StabLocalCommon = 0x28u, // N_LCSYM
+ StabBeginSymbol = 0x2Eu, // N_BNSYM
+ StabSourceFileOptions = 0x3Cu, // N_OPT
+ StabRegisterSymbol = 0x40u, // N_RSYM
+ StabSourceLine = 0x44u, // N_SLINE
+ StabEndSymbol = 0x4Eu, // N_ENSYM
+ StabStructureType = 0x60u, // N_SSYM
+ StabSourceFileName = 0x64u, // N_SO
+ StabObjectFileName = 0x66u, // N_OSO
+ StabLocalSymbol = 0x80u, // N_LSYM
+ StabBeginIncludeFileName = 0x82u, // N_BINCL
+ StabIncludeFileName = 0x84u, // N_SOL
+ StabCompilerParameters = 0x86u, // N_PARAMS
+ StabCompilerVersion = 0x88u, // N_VERSION
+ StabCompilerOptLevel = 0x8Au, // N_OLEVEL
+ StabParameter = 0xA0u, // N_PSYM
+ StabEndIncludeFile = 0xA2u, // N_EINCL
+ StabAlternateEntry = 0xA4u, // N_ENTRY
+ StabLeftBracket = 0xC0u, // N_LBRAC
+ StabDeletedIncludeFile = 0xC2u, // N_EXCL
+ StabRightBracket = 0xE0u, // N_RBRAC
+ StabBeginCommon = 0xE2u, // N_BCOMM
+ StabEndCommon = 0xE4u, // N_ECOMM
+ StabEndCommonLocal = 0xE8u, // N_ECOML
+ StabLength = 0xFEu // N_LENG
+
+ };
+
+ // Structs from <mach-o/loader.h>
+
+ struct mach_header {
+ uint32_t magic;
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t filetype;
+ uint32_t ncmds;
+ uint32_t sizeofcmds;
+ uint32_t flags;
+ };
+
+ struct mach_header_64 {
+ uint32_t magic;
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t filetype;
+ uint32_t ncmds;
+ uint32_t sizeofcmds;
+ uint32_t flags;
+ uint32_t reserved;
+ };
+
+ struct load_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ };
+
+ struct segment_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ char segname[16];
+ uint32_t vmaddr;
+ uint32_t vmsize;
+ uint32_t fileoff;
+ uint32_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+ };
+
+ struct segment_command_64 {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ char segname[16];
+ uint64_t vmaddr;
+ uint64_t vmsize;
+ uint64_t fileoff;
+ uint64_t filesize;
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+ };
+
+ struct section {
+ char sectname[16];
+ char segname[16];
+ uint32_t addr;
+ uint32_t size;
+ uint32_t offset;
+ uint32_t align;
+ uint32_t reloff;
+ uint32_t nreloc;
+ uint32_t flags;
+ uint32_t reserved1;
+ uint32_t reserved2;
+ };
+
+ struct section_64 {
+ char sectname[16];
+ char segname[16];
+ uint64_t addr;
+ uint64_t size;
+ uint32_t offset;
+ uint32_t align;
+ uint32_t reloff;
+ uint32_t nreloc;
+ uint32_t flags;
+ uint32_t reserved1;
+ uint32_t reserved2;
+ uint32_t reserved3;
+ };
+
+ struct fvmlib {
+ uint32_t name;
+ uint32_t minor_version;
+ uint32_t header_addr;
+ };
+
+ struct fvmlib_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ struct fvmlib fvmlib;
+ };
+
+ struct dylib {
+ uint32_t name;
+ uint32_t timestamp;
+ uint32_t current_version;
+ uint32_t compatibility_version;
+ };
+
+ struct dylib_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ struct dylib dylib;
+ };
+
+ struct sub_framework_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t umbrella;
+ };
+
+ struct sub_client_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t client;
+ };
+
+ struct sub_umbrella_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t sub_umbrella;
+ };
+
+ struct sub_library_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t sub_library;
+ };
+
+ struct prebound_dylib_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t name;
+ uint32_t nmodules;
+ uint32_t linked_modules;
+ };
+
+ struct dylinker_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t name;
+ };
+
+ struct thread_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ };
+
+ struct routines_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t init_address;
+ uint32_t init_module;
+ uint32_t reserved1;
+ uint32_t reserved2;
+ uint32_t reserved3;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ uint32_t reserved6;
+ };
+
+ struct routines_command_64 {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint64_t init_address;
+ uint64_t init_module;
+ uint64_t reserved1;
+ uint64_t reserved2;
+ uint64_t reserved3;
+ uint64_t reserved4;
+ uint64_t reserved5;
+ uint64_t reserved6;
+ };
+
+ struct symtab_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t symoff;
+ uint32_t nsyms;
+ uint32_t stroff;
+ uint32_t strsize;
+ };
+
+ struct dysymtab_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t ilocalsym;
+ uint32_t nlocalsym;
+ uint32_t iextdefsym;
+ uint32_t nextdefsym;
+ uint32_t iundefsym;
+ uint32_t nundefsym;
+ uint32_t tocoff;
+ uint32_t ntoc;
+ uint32_t modtaboff;
+ uint32_t nmodtab;
+ uint32_t extrefsymoff;
+ uint32_t nextrefsyms;
+ uint32_t indirectsymoff;
+ uint32_t nindirectsyms;
+ uint32_t extreloff;
+ uint32_t nextrel;
+ uint32_t locreloff;
+ uint32_t nlocrel;
+ };
+
+ struct dylib_table_of_contents {
+ uint32_t symbol_index;
+ uint32_t module_index;
+ };
+
+ struct dylib_module {
+ uint32_t module_name;
+ uint32_t iextdefsym;
+ uint32_t nextdefsym;
+ uint32_t irefsym;
+ uint32_t nrefsym;
+ uint32_t ilocalsym;
+ uint32_t nlocalsym;
+ uint32_t iextrel;
+ uint32_t nextrel;
+ uint32_t iinit_iterm;
+ uint32_t ninit_nterm;
+ uint32_t objc_module_info_addr;
+ uint32_t objc_module_info_size;
+ };
+
+ struct dylib_module_64 {
+ uint32_t module_name;
+ uint32_t iextdefsym;
+ uint32_t nextdefsym;
+ uint32_t irefsym;
+ uint32_t nrefsym;
+ uint32_t ilocalsym;
+ uint32_t nlocalsym;
+ uint32_t iextrel;
+ uint32_t nextrel;
+ uint32_t iinit_iterm;
+ uint32_t ninit_nterm;
+ uint32_t objc_module_info_size;
+ uint64_t objc_module_info_addr;
+ };
+
+ struct dylib_reference {
+ uint32_t isym:24,
+ flags:8;
+ };
+
+
+ struct twolevel_hints_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t offset;
+ uint32_t nhints;
+ };
+
+ struct twolevel_hint {
+ uint32_t isub_image:8,
+ itoc:24;
+ };
+
+ struct prebind_cksum_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t cksum;
+ };
+
+ struct uuid_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint8_t uuid[16];
+ };
+
+ struct rpath_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t path;
+ };
+
+ struct linkedit_data_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t dataoff;
+ uint32_t datasize;
+ };
+
+ struct encryption_info_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t cryptoff;
+ uint32_t cryptsize;
+ uint32_t cryptid;
+ };
+
+ struct version_min_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t version;
+ uint32_t reserved;
+ };
+
+ struct dyld_info_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t rebase_off;
+ uint32_t rebase_size;
+ uint32_t bind_off;
+ uint32_t bind_size;
+ uint32_t weak_bind_off;
+ uint32_t weak_bind_size;
+ uint32_t lazy_bind_off;
+ uint32_t lazy_bind_size;
+ uint32_t export_off;
+ uint32_t export_size;
+ };
+
+ struct symseg_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t offset;
+ uint32_t size;
+ };
+
+ struct ident_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ };
+
+ struct fvmfile_command {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ uint32_t name;
+ uint32_t header_addr;
+ };
+
+
+ // Structs from <mach-o/fat.h>
+ struct fat_header {
+ uint32_t magic;
+ uint32_t nfat_arch;
+ };
+
+ struct fat_arch {
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t align;
+ };
+
+ // Structs from <mach-o/fat.h>
+ struct nlist {
+ uint32_t n_strx;
+ uint8_t n_type;
+ uint8_t n_sect;
+ int16_t n_desc;
+ uint32_t n_value;
+ };
+
+ struct nlist_64 {
+ uint32_t n_strx;
+ uint8_t n_type;
+ uint8_t n_sect;
+ uint16_t n_desc;
+ uint64_t n_value;
+ };
+
+ // Get/Set functions from <mach-o/nlist.h>
+
+ static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc)
+ {
+ return (((n_desc) >> 8u) & 0xffu);
+ }
+
+ static inline void SET_LIBRARY_ORDINAL(uint16_t &n_desc, uint8_t ordinal)
+ {
+ n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
+ }
+
+ static inline uint8_t GET_COMM_ALIGN (uint16_t n_desc)
+ {
+ return (n_desc >> 8u) & 0x0fu;
+ }
+
+ static inline void SET_COMM_ALIGN (uint16_t &n_desc, uint8_t align)
+ {
+ n_desc = ((n_desc & 0xf0ffu) | ((align & 0x0fu) << 8u));
+ }
+
+ // Enums from <mach/machine.h>
+ enum {
+ // Capability bits used in the definition of cpu_type.
+ CPUArchMask = 0xff000000, // Mask for architecture bits
+ CPUArchABI64 = 0x01000000, // 64 bit ABI
+
+ // Constants for the cputype field.
+ CPUTypeI386 = 7,
+ CPUTypeX86_64 = CPUTypeI386 | CPUArchABI64,
+ CPUTypeARM = 12,
+ CPUTypeSPARC = 14,
+ CPUTypePowerPC = 18,
+ CPUTypePowerPC64 = CPUTypePowerPC | CPUArchABI64,
+
+
+ // Constants for the cpusubtype field.
+
+ // X86
+ CPUSubType_I386_ALL = 3,
+ CPUSubType_X86_64_ALL = 3,
+
+ // ARM
+ CPUSubType_ARM_ALL = 0,
+ CPUSubType_ARM_V4T = 5,
+ CPUSubType_ARM_V5 = 7,
+ CPUSubType_ARM_V6 = 6,
+ CPUSubType_ARM_V7 = 9,
+
+ // PowerPC
+ CPUSubType_POWERPC_ALL = 0,
+
+ CPUSubType_SPARC_ALL = 0
+ };
+ } // end namespace MachO
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/ManagedStatic.h b/contrib/llvm/include/llvm/Support/ManagedStatic.h
new file mode 100644
index 000000000000..4171d1bec8dc
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ManagedStatic.h
@@ -0,0 +1,115 @@
+//===-- llvm/Support/ManagedStatic.h - Static Global 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 the ManagedStatic class and the llvm_shutdown() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
+#define LLVM_SUPPORT_MANAGED_STATIC_H
+
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Support/Valgrind.h"
+
+namespace llvm {
+
+/// object_creator - Helper method for ManagedStatic.
+template<class C>
+void* object_creator() {
+ return new C();
+}
+
+/// object_deleter - Helper method for ManagedStatic.
+///
+template<typename T> struct object_deleter {
+ static void call(void * Ptr) { delete (T*)Ptr; }
+};
+template<typename T, size_t N> struct object_deleter<T[N]> {
+ static void call(void * Ptr) { delete[] (T*)Ptr; }
+};
+
+/// ManagedStaticBase - Common base class for ManagedStatic instances.
+class ManagedStaticBase {
+protected:
+ // This should only be used as a static variable, which guarantees that this
+ // will be zero initialized.
+ mutable void *Ptr;
+ mutable void (*DeleterFn)(void*);
+ mutable const ManagedStaticBase *Next;
+
+ void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
+public:
+ /// isConstructed - Return true if this object has not been created yet.
+ bool isConstructed() const { return Ptr != 0; }
+
+ void destroy() const;
+};
+
+/// ManagedStatic - This transparently changes the behavior of global statics to
+/// be lazily constructed on demand (good for reducing startup times of dynamic
+/// libraries that link in LLVM components) and for making destruction be
+/// explicit through the llvm_shutdown() function call.
+///
+template<class C>
+class ManagedStatic : public ManagedStaticBase {
+public:
+
+ // Accessors.
+ C &operator*() {
+ void* tmp = Ptr;
+ if (llvm_is_multithreaded()) sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
+
+ return *static_cast<C*>(Ptr);
+ }
+ C *operator->() {
+ void* tmp = Ptr;
+ if (llvm_is_multithreaded()) sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
+
+ return static_cast<C*>(Ptr);
+ }
+ const C &operator*() const {
+ void* tmp = Ptr;
+ if (llvm_is_multithreaded()) sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
+
+ return *static_cast<C*>(Ptr);
+ }
+ const C *operator->() const {
+ void* tmp = Ptr;
+ if (llvm_is_multithreaded()) sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
+ TsanHappensAfter(this);
+
+ return static_cast<C*>(Ptr);
+ }
+};
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm_shutdown();
+
+
+/// llvm_shutdown_obj - This is a simple helper class that calls
+/// llvm_shutdown() when it is destroyed.
+struct llvm_shutdown_obj {
+ llvm_shutdown_obj() { }
+ explicit llvm_shutdown_obj(bool multithreaded) {
+ if (multithreaded) llvm_start_multithreaded();
+ }
+ ~llvm_shutdown_obj() { llvm_shutdown(); }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm/include/llvm/Support/MathExtras.h
new file mode 100644
index 000000000000..d085c94f2adc
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/MathExtras.h
@@ -0,0 +1,474 @@
+//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MATHEXTRAS_H
+#define LLVM_SUPPORT_MATHEXTRAS_H
+
+#include "llvm/Support/SwapByteOrder.h"
+
+namespace llvm {
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+inline uint32_t Hi_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value >> 32);
+}
+
+/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+inline uint32_t Lo_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value);
+}
+
+/// isInt - Checks if an integer fits into the given bit width.
+template<unsigned N>
+inline bool isInt(int64_t x) {
+ return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+}
+// Template specializations to get better code for common cases.
+template<>
+inline bool isInt<8>(int64_t x) {
+ return static_cast<int8_t>(x) == x;
+}
+template<>
+inline bool isInt<16>(int64_t x) {
+ return static_cast<int16_t>(x) == x;
+}
+template<>
+inline bool isInt<32>(int64_t x) {
+ return static_cast<int32_t>(x) == x;
+}
+
+/// isShiftedInt<N,S> - Checks if a signed integer is an N bit number shifted
+/// left by S.
+template<unsigned N, unsigned S>
+inline bool isShiftedInt(int64_t x) {
+ return isInt<N+S>(x) && (x % (1<<S) == 0);
+}
+
+/// isUInt - Checks if an unsigned integer fits into the given bit width.
+template<unsigned N>
+inline bool isUInt(uint64_t x) {
+ return N >= 64 || x < (UINT64_C(1)<<N);
+}
+// Template specializations to get better code for common cases.
+template<>
+inline bool isUInt<8>(uint64_t x) {
+ return static_cast<uint8_t>(x) == x;
+}
+template<>
+inline bool isUInt<16>(uint64_t x) {
+ return static_cast<uint16_t>(x) == x;
+}
+template<>
+inline bool isUInt<32>(uint64_t x) {
+ return static_cast<uint32_t>(x) == x;
+}
+
+/// isShiftedUInt<N,S> - Checks if a unsigned integer is an N bit number shifted
+/// left by S.
+template<unsigned N, unsigned S>
+inline bool isShiftedUInt(uint64_t x) {
+ return isUInt<N+S>(x) && (x % (1<<S) == 0);
+}
+
+/// isUIntN - Checks if an unsigned integer fits into the given (dynamic)
+/// bit width.
+inline bool isUIntN(unsigned N, uint64_t x) {
+ return x == (x & (~0ULL >> (64 - N)));
+}
+
+/// isIntN - Checks if an signed integer fits into the given (dynamic)
+/// bit width.
+inline bool isIntN(unsigned N, int64_t x) {
+ return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
+}
+
+/// isMask_32 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (32 bit
+/// version). Ex. isMask_32(0x0000FFFFU) == true.
+inline bool isMask_32(uint32_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isMask_64 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (64 bit
+/// version).
+inline bool isMask_64(uint64_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isShiftedMask_32 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (32 bit version.)
+/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+inline bool isShiftedMask_32(uint32_t Value) {
+ return isMask_32((Value - 1) | Value);
+}
+
+/// isShiftedMask_64 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (64 bit version.)
+inline bool isShiftedMask_64(uint64_t Value) {
+ return isMask_64((Value - 1) | Value);
+}
+
+/// isPowerOf2_32 - This function returns true if the argument is a power of
+/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+inline bool isPowerOf2_32(uint32_t Value) {
+ return Value && !(Value & (Value - 1));
+}
+
+/// isPowerOf2_64 - This function returns true if the argument is a power of two
+/// > 0 (64 bit edition.)
+inline bool isPowerOf2_64(uint64_t Value) {
+ return Value && !(Value & (Value - int64_t(1L)));
+}
+
+/// ByteSwap_16 - This function returns a byte-swapped representation of the
+/// 16-bit argument, Value.
+inline uint16_t ByteSwap_16(uint16_t Value) {
+ return sys::SwapByteOrder_16(Value);
+}
+
+/// ByteSwap_32 - This function returns a byte-swapped representation of the
+/// 32-bit argument, Value.
+inline uint32_t ByteSwap_32(uint32_t Value) {
+ return sys::SwapByteOrder_32(Value);
+}
+
+/// ByteSwap_64 - This function returns a byte-swapped representation of the
+/// 64-bit argument, Value.
+inline uint64_t ByteSwap_64(uint64_t Value) {
+ return sys::SwapByteOrder_64(Value);
+}
+
+/// CountLeadingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the most significant bit to the first one
+/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8.
+/// Returns 32 if the word is zero.
+inline unsigned CountLeadingZeros_32(uint32_t Value) {
+ unsigned Count; // result
+#if __GNUC__ >= 4
+ // PowerPC is defined for __builtin_clz(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+ if (!Value) return 32;
+#endif
+ Count = __builtin_clz(Value);
+#else
+ if (!Value) return 32;
+ Count = 0;
+ // bisection method for count leading zeros
+ for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) {
+ uint32_t Tmp = Value >> Shift;
+ if (Tmp) {
+ Value = Tmp;
+ } else {
+ Count |= Shift;
+ }
+ }
+#endif
+ return Count;
+}
+
+/// CountLeadingOnes_32 - this function performs the operation of
+/// counting the number of ones from the most significant bit to the first zero
+/// bit. Ex. CountLeadingOnes_32(0xFF0FFF00) == 8.
+/// Returns 32 if the word is all ones.
+inline unsigned CountLeadingOnes_32(uint32_t Value) {
+ return CountLeadingZeros_32(~Value);
+}
+
+/// CountLeadingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the most significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+inline unsigned CountLeadingZeros_64(uint64_t Value) {
+ unsigned Count; // result
+#if __GNUC__ >= 4
+ // PowerPC is defined for __builtin_clzll(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+ if (!Value) return 64;
+#endif
+ Count = __builtin_clzll(Value);
+#else
+ if (sizeof(long) == sizeof(int64_t)) {
+ if (!Value) return 64;
+ Count = 0;
+ // bisection method for count leading zeros
+ for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) {
+ uint64_t Tmp = Value >> Shift;
+ if (Tmp) {
+ Value = Tmp;
+ } else {
+ Count |= Shift;
+ }
+ }
+ } else {
+ // get hi portion
+ uint32_t Hi = Hi_32(Value);
+
+ // if some bits in hi portion
+ if (Hi) {
+ // leading zeros in hi portion plus all bits in lo portion
+ Count = CountLeadingZeros_32(Hi);
+ } else {
+ // get lo portion
+ uint32_t Lo = Lo_32(Value);
+ // same as 32 bit value
+ Count = CountLeadingZeros_32(Lo)+32;
+ }
+ }
+#endif
+ return Count;
+}
+
+/// CountLeadingOnes_64 - This function performs the operation
+/// of counting the number of ones from the most significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+inline unsigned CountLeadingOnes_64(uint64_t Value) {
+ return CountLeadingZeros_64(~Value);
+}
+
+/// CountTrailingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the least significant bit to the first one
+/// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8.
+/// Returns 32 if the word is zero.
+inline unsigned CountTrailingZeros_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return Value ? __builtin_ctz(Value) : 32;
+#else
+ static const unsigned Mod37BitPosition[] = {
+ 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
+ 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
+ 5, 20, 8, 19, 18
+ };
+ return Mod37BitPosition[(-Value & Value) % 37];
+#endif
+}
+
+/// CountTrailingOnes_32 - this function performs the operation of
+/// counting the number of ones from the least significant bit to the first zero
+/// bit. Ex. CountTrailingOnes_32(0x00FF00FF) == 8.
+/// Returns 32 if the word is all ones.
+inline unsigned CountTrailingOnes_32(uint32_t Value) {
+ return CountTrailingZeros_32(~Value);
+}
+
+/// CountTrailingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the least significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+inline unsigned CountTrailingZeros_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return Value ? __builtin_ctzll(Value) : 64;
+#else
+ static const unsigned Mod67Position[] = {
+ 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54,
+ 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55,
+ 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27,
+ 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
+ 7, 48, 35, 6, 34, 33, 0
+ };
+ return Mod67Position[(-Value & Value) % 67];
+#endif
+}
+
+/// CountTrailingOnes_64 - This function performs the operation
+/// of counting the number of ones from the least significant bit to the first
+/// zero bit (64 bit edition.)
+/// Returns 64 if the word is all ones.
+inline unsigned CountTrailingOnes_64(uint64_t Value) {
+ return CountTrailingZeros_64(~Value);
+}
+
+/// CountPopulation_32 - this function counts the number of set bits in a value.
+/// Ex. CountPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+inline unsigned CountPopulation_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcount(Value);
+#else
+ uint32_t v = Value - ((Value >> 1) & 0x55555555);
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+ return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+/// CountPopulation_64 - this function counts the number of set bits in a value,
+/// (64 bit edition.)
+inline unsigned CountPopulation_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcountll(Value);
+#else
+ uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
+#endif
+}
+
+/// Log2_32 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (32 bit edition.)
+/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+inline unsigned Log2_32(uint32_t Value) {
+ return 31 - CountLeadingZeros_32(Value);
+}
+
+/// Log2_64 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64(uint64_t Value) {
+ return 63 - CountLeadingZeros_64(Value);
+}
+
+/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 32 if the value is zero. (32 bit edition).
+/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+inline unsigned Log2_32_Ceil(uint32_t Value) {
+ return 32-CountLeadingZeros_32(Value-1);
+}
+
+/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 64 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64_Ceil(uint64_t Value) {
+ return 64-CountLeadingZeros_64(Value-1);
+}
+
+/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
+/// values using Euclid's algorithm.
+inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
+ while (B) {
+ uint64_t T = B;
+ B = A % B;
+ A = T;
+ }
+ return A;
+}
+
+/// BitsToDouble - This function takes a 64-bit integer and returns the bit
+/// equivalent double.
+inline double BitsToDouble(uint64_t Bits) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.L = Bits;
+ return T.D;
+}
+
+/// BitsToFloat - This function takes a 32-bit integer and returns the bit
+/// equivalent float.
+inline float BitsToFloat(uint32_t Bits) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.I = Bits;
+ return T.F;
+}
+
+/// DoubleToBits - This function takes a double and returns the bit
+/// equivalent 64-bit integer. Note that copying doubles around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+inline uint64_t DoubleToBits(double Double) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.D = Double;
+ return T.L;
+}
+
+/// FloatToBits - This function takes a float and returns the bit
+/// equivalent 32-bit integer. Note that copying floats around
+/// changes the bits of NaNs on some hosts, notably x86, so this
+/// routine cannot be used if these bits are needed.
+inline uint32_t FloatToBits(float Float) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.F = Float;
+ return T.I;
+}
+
+/// Platform-independent wrappers for the C99 isnan() function.
+int IsNAN(float f);
+int IsNAN(double d);
+
+/// Platform-independent wrappers for the C99 isinf() function.
+int IsInf(float f);
+int IsInf(double d);
+
+/// MinAlign - A and B are either alignments or offsets. Return the minimum
+/// alignment that may be assumed after adding the two together.
+static inline uint64_t MinAlign(uint64_t A, uint64_t B) {
+ // The largest power of 2 that divides both A and B.
+ return (A | B) & -(A | B);
+}
+
+/// NextPowerOf2 - Returns the next power of two (in 64-bits)
+/// that is strictly greater than A. Returns zero on overflow.
+static inline uint64_t NextPowerOf2(uint64_t A) {
+ A |= (A >> 1);
+ A |= (A >> 2);
+ A |= (A >> 4);
+ A |= (A >> 8);
+ A |= (A >> 16);
+ A |= (A >> 32);
+ 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.
+///
+/// Examples:
+/// RoundUpToAlignment(5, 8) = 8
+/// RoundUpToAlignment(17, 8) = 24
+/// RoundUpToAlignment(~0LL, 8) = 0
+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.
+inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
+ return RoundUpToAlignment(Value, Align) - Value;
+}
+
+/// abs64 - absolute value of a 64-bit int. Not all environments support
+/// "abs" on whatever their name for the 64-bit int type is. The absolute
+/// value of the largest negative number is undefined, as with "abs".
+inline int64_t abs64(int64_t x) {
+ return (x < 0) ? -x : x;
+}
+
+/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
+/// Usage int32_t r = SignExtend32<5>(x);
+template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
+ return int32_t(x << (32 - B)) >> (32 - B);
+}
+
+/// SignExtend64 - Sign extend B-bit number x to 64-bit int.
+/// Usage int64_t r = SignExtend64<5>(x);
+template <unsigned B> inline int64_t SignExtend64(uint64_t x) {
+ return int64_t(x << (64 - B)) >> (64 - B);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Memory.h b/contrib/llvm/include/llvm/Support/Memory.h
new file mode 100644
index 000000000000..37890e7e4af1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Memory.h
@@ -0,0 +1,96 @@
+//===- llvm/Support/Memory.h - Memory Support --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Memory class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MEMORY_H
+#define LLVM_SYSTEM_MEMORY_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ /// This class encapsulates the notion of a memory block which has an address
+ /// and a size. It is used by the Memory class (a friend) as the result of
+ /// various memory allocation operations.
+ /// @see Memory
+ /// @brief Memory block abstraction.
+ class MemoryBlock {
+ public:
+ MemoryBlock() : Address(0), Size(0) { }
+ MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
+ void *base() const { return Address; }
+ size_t size() const { return Size; }
+ private:
+ void *Address; ///< Address of first byte of memory area
+ size_t Size; ///< Size, in bytes of the memory area
+ friend class Memory;
+ };
+
+ /// This class provides various memory handling functions that manipulate
+ /// MemoryBlock instances.
+ /// @since 1.4
+ /// @brief An abstraction for memory operations.
+ class Memory {
+ public:
+ /// 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.
+ /// \p NearBlock may point to an existing allocation in which case
+ /// an attempt is made to allocate more memory near the existing block.
+ ///
+ /// On success, this returns a non-null memory block, otherwise it returns
+ /// a null memory block and fills in *ErrMsg.
+ ///
+ /// @brief Allocate Read/Write/Execute memory.
+ static MemoryBlock AllocateRWX(size_t NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg = 0);
+
+ /// This method releases a block of Read/Write/Execute memory that was
+ /// allocated with the AllocateRWX method. It should not be used to
+ /// release any memory block allocated any other way.
+ ///
+ /// On success, this returns false, otherwise it returns true and fills
+ /// in *ErrMsg.
+ /// @brief Release Read/Write/Execute memory.
+ static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
+
+
+ /// InvalidateInstructionCache - Before the JIT can run a block of code
+ /// that has been emitted it must invalidate the instruction cache on some
+ /// platforms.
+ static void InvalidateInstructionCache(const void *Addr, size_t Len);
+
+ /// setExecutable - Before the JIT can run a block of code, it has to be
+ /// given read and executable privilege. Return true if it is already r-x
+ /// or the system is able to change its previlege.
+ static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0);
+
+ /// setWritable - When adding to a block of code, the JIT may need
+ /// to mark a block of code as RW since the protections are on page
+ /// boundaries, and the JIT internal allocations are not page aligned.
+ static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0);
+
+ /// setRangeExecutable - Mark the page containing a range of addresses
+ /// as executable.
+ static bool setRangeExecutable(const void *Addr, size_t Size);
+
+ /// setRangeWritable - Mark the page containing a range of addresses
+ /// as writable.
+ static bool setRangeWritable(const void *Addr, size_t Size);
+ };
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/MemoryBuffer.h b/contrib/llvm/include/llvm/Support/MemoryBuffer.h
new file mode 100644
index 000000000000..06816de9716a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/MemoryBuffer.h
@@ -0,0 +1,141 @@
+//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
+#define LLVM_SUPPORT_MEMORYBUFFER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class error_code;
+template<class T> class OwningPtr;
+
+/// MemoryBuffer - This interface provides simple read-only access to a block
+/// of memory, and provides simple methods for reading files and standard input
+/// into a memory buffer. In addition to basic access to the characters in the
+/// file, this interface guarantees you can read one character past the end of
+/// the file, and that this character will read as '\0'.
+///
+/// The '\0' guarantee is needed to support an optimization -- it's intended to
+/// be more efficient for clients which are reading all the data to stop
+/// reading when they encounter a '\0' than to continually check the file
+/// position to see if it has reached the end of the file.
+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
+protected:
+ MemoryBuffer() {}
+ void init(const char *BufStart, const char *BufEnd,
+ bool RequiresNullTerminator);
+public:
+ virtual ~MemoryBuffer();
+
+ const char *getBufferStart() const { return BufferStart; }
+ const char *getBufferEnd() const { return BufferEnd; }
+ size_t getBufferSize() const { return BufferEnd-BufferStart; }
+
+ StringRef getBuffer() const {
+ return StringRef(BufferStart, getBufferSize());
+ }
+
+ /// getBufferIdentifier - Return an identifier for this buffer, typically the
+ /// filename it was read from.
+ virtual const char *getBufferIdentifier() const {
+ return "Unknown buffer";
+ }
+
+ /// getFile - Open the specified file as a MemoryBuffer, returning a new
+ /// MemoryBuffer if successful, otherwise returning null. If FileSize is
+ /// specified, this means that the client knows that the file exists and that
+ /// it has the specified size.
+ static error_code getFile(StringRef Filename, OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true);
+ static error_code getFile(const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true);
+
+ /// getOpenFile - Given an already-open file descriptor, read the file and
+ /// return a MemoryBuffer.
+ static error_code getOpenFile(int FD, const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ uint64_t FileSize = -1,
+ uint64_t MapSize = -1,
+ int64_t Offset = 0,
+ bool RequiresNullTerminator = true);
+
+ /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
+ /// that InputData must be null terminated if RequiresNullTerminator is true.
+ static MemoryBuffer *getMemBuffer(StringRef InputData,
+ StringRef BufferName = "",
+ bool RequiresNullTerminator = true);
+
+ /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
+ /// copying the contents and taking ownership of it. InputData does not
+ /// have to be null terminated.
+ static MemoryBuffer *getMemBufferCopy(StringRef InputData,
+ StringRef BufferName = "");
+
+ /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
+ /// is completely initialized to zeros. Note that the caller should
+ /// initialize the memory allocated by this method. The memory is owned by
+ /// the MemoryBuffer object.
+ static MemoryBuffer *getNewMemBuffer(size_t Size, StringRef BufferName = "");
+
+ /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
+ /// that is not initialized. Note that the caller should initialize the
+ /// memory allocated by this method. The memory is owned by the MemoryBuffer
+ /// object.
+ static MemoryBuffer *getNewUninitMemBuffer(size_t Size,
+ StringRef BufferName = "");
+
+ /// getSTDIN - Read all of stdin into a file buffer, and return it.
+ /// If an error occurs, this returns null and sets ec.
+ static error_code getSTDIN(OwningPtr<MemoryBuffer> &result);
+
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and sets
+ /// ec.
+ static error_code getFileOrSTDIN(StringRef Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
+ static error_code getFileOrSTDIN(const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ int64_t FileSize = -1);
+
+
+ //===--------------------------------------------------------------------===//
+ // Provided for performance analysis.
+ //===--------------------------------------------------------------------===//
+
+ /// The kind of memory backing used to support the MemoryBuffer.
+ enum BufferKind {
+ MemoryBuffer_Malloc,
+ MemoryBuffer_MMap
+ };
+
+ /// Return information on the memory mechanism used to support the
+ /// MemoryBuffer.
+ virtual BufferKind getBufferKind() const = 0;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/MemoryObject.h b/contrib/llvm/include/llvm/Support/MemoryObject.h
new file mode 100644
index 000000000000..b778b08de932
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/MemoryObject.h
@@ -0,0 +1,69 @@
+//===- MemoryObject.h - Abstract memory interface ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MEMORYOBJECT_H
+#define MEMORYOBJECT_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// MemoryObject - Abstract base class for contiguous addressable memory.
+/// Necessary for cases in which the memory is in another process, in a
+/// file, or on a remote machine.
+/// All size and offset parameters are uint64_ts, to allow 32-bit processes
+/// access to 64-bit address spaces.
+class MemoryObject {
+public:
+ /// Destructor - Override as necessary.
+ virtual ~MemoryObject();
+
+ /// getBase - Returns the lowest valid address in the region.
+ ///
+ /// @result - The lowest valid address.
+ virtual uint64_t getBase() const = 0;
+
+ /// getExtent - Returns the size of the region in bytes. (The region is
+ /// contiguous, so the highest valid address of the region
+ /// is getBase() + getExtent() - 1).
+ ///
+ /// @result - The size of the region.
+ virtual uint64_t getExtent() const = 0;
+
+ /// readByte - Tries to read a single byte from the region.
+ ///
+ /// @param address - The address of the byte, in the same space as getBase().
+ /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
+
+ /// readBytes - Tries to read a contiguous range of bytes from the
+ /// region, up to the end of the region.
+ /// You should override this function if there is a quicker
+ /// way than going back and forth with individual bytes.
+ ///
+ /// @param address - The address of the first byte, in the same space as
+ /// getBase().
+ /// @param size - The maximum number of bytes to copy.
+ /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
+ /// and large enough to hold size bytes.
+ /// @param copied - A pointer to a nunber that is filled in with the number
+ /// of bytes actually read. May be NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readBytes(uint64_t address,
+ uint64_t size,
+ uint8_t* buf,
+ uint64_t* copied) const;
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Mutex.h b/contrib/llvm/include/llvm/Support/Mutex.h
new file mode 100644
index 000000000000..42ea63060f66
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Mutex.h
@@ -0,0 +1,154 @@
+//===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MUTEX_H
+#define LLVM_SYSTEM_MUTEX_H
+
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic Mutex class.
+ class MutexImpl
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it. if \p recursive is set
+ /// to false, the lock will not be recursive which makes it cheaper but
+ /// also more likely to deadlock (same thread can't acquire more than
+ /// once).
+ /// @brief Default Constructor.
+ explicit MutexImpl(bool recursive = true);
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~MutexImpl();
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock. If the lock is held by
+ /// another thread, this method will wait until it can acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock.
+ bool acquire();
+
+ /// Attempts to release the lock. If the lock is held by the current
+ /// thread, the lock is released allowing other threads to acquire the
+ /// lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock.
+ bool release();
+
+ /// Attempts to acquire the lock without blocking. If the lock is not
+ /// available, this function returns false quickly (without blocking). If
+ /// the lock is available, it is acquired.
+ /// @returns false if any kind of error occurs or the lock is not
+ /// available, true otherwise.
+ /// @brief Try to acquire the lock.
+ bool tryacquire();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+ void* data_; ///< We don't know what the data will be
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ MutexImpl(const MutexImpl & original);
+ void operator=(const MutexImpl &);
+ /// @}
+ };
+
+
+ /// SmartMutex - A mutex with a compile time constant parameter that
+ /// indicates whether this mutex should become a no-op when we're not
+ /// running in multithreaded mode.
+ template<bool mt_only>
+ class SmartMutex : public MutexImpl {
+ unsigned acquired;
+ bool recursive;
+ public:
+ explicit SmartMutex(bool rec = true) :
+ MutexImpl(rec), acquired(0), recursive(rec) { }
+
+ bool acquire() {
+ if (!mt_only || llvm_is_multithreaded()) {
+ return MutexImpl::acquire();
+ } else {
+ // Single-threaded debugging code. This would be racy in
+ // multithreaded mode, but provides not sanity checks in single
+ // threaded mode.
+ assert((recursive || acquired == 0) && "Lock already acquired!!");
+ ++acquired;
+ return true;
+ }
+ }
+
+ bool release() {
+ if (!mt_only || llvm_is_multithreaded()) {
+ return MutexImpl::release();
+ } else {
+ // Single-threaded debugging code. This would be racy in
+ // multithreaded mode, but provides not sanity checks in single
+ // threaded mode.
+ assert(((recursive && acquired) || (acquired == 1)) &&
+ "Lock not acquired before release!");
+ --acquired;
+ return true;
+ }
+ }
+
+ bool tryacquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return MutexImpl::tryacquire();
+ else return true;
+ }
+
+ private:
+ SmartMutex(const SmartMutex<mt_only> & original);
+ void operator=(const SmartMutex<mt_only> &);
+ };
+
+ /// Mutex - A standard, always enforced mutex.
+ typedef SmartMutex<false> Mutex;
+
+ template<bool mt_only>
+ class SmartScopedLock {
+ SmartMutex<mt_only>& mtx;
+
+ public:
+ SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
+ mtx.acquire();
+ }
+
+ ~SmartScopedLock() {
+ mtx.release();
+ }
+ };
+
+ typedef SmartScopedLock<false> ScopedLock;
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/MutexGuard.h b/contrib/llvm/include/llvm/Support/MutexGuard.h
new file mode 100644
index 000000000000..cd13bfe6eeb0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/MutexGuard.h
@@ -0,0 +1,41 @@
+//===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- 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 guard for a block of code that ensures a Mutex is locked
+// upon construction and released upon destruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUTEXGUARD_H
+#define LLVM_SUPPORT_MUTEXGUARD_H
+
+#include "llvm/Support/Mutex.h"
+
+namespace llvm {
+ /// Instances of this class acquire a given Mutex Lock when constructed and
+ /// hold that lock until destruction. The intention is to instantiate one of
+ /// these on the stack at the top of some scope to be assured that C++
+ /// destruction of the object will always release the Mutex and thus avoid
+ /// a host of nasty multi-threading problems in the face of exceptions, etc.
+ /// @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
+ public:
+ MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
+ ~MutexGuard() { M.release(); }
+ /// holds - Returns true if this locker instance holds the specified lock.
+ /// This is mostly used in assertions to validate that the correct mutex
+ /// is held.
+ bool holds(const sys::Mutex& lock) const { return &M == &lock; }
+ };
+}
+
+#endif // LLVM_SUPPORT_MUTEXGUARD_H
diff --git a/contrib/llvm/include/llvm/Support/NoFolder.h b/contrib/llvm/include/llvm/Support/NoFolder.h
new file mode 100644
index 000000000000..75c1a79265e2
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/NoFolder.h
@@ -0,0 +1,286 @@
+//======-- llvm/Support/NoFolder.h - Constant folding helper -*- 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 NoFolder class, a helper for IRBuilder. It provides
+// IRBuilder with a set of methods for creating unfolded constants. This is
+// useful for learners trying to understand how LLVM IR works, and who don't
+// want details to be hidden by the constant folder. For general constant
+// creation and folding, use ConstantExpr and the routines in
+// llvm/Analysis/ConstantFolding.h.
+//
+// Note: since it is not actually possible to create unfolded constants, this
+// class returns instructions rather than constants.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_NOFOLDER_H
+#define LLVM_SUPPORT_NOFOLDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+
+/// NoFolder - Create "constants" (actually, instructions) with no folding.
+class NoFolder {
+public:
+ explicit NoFolder() {}
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Instruction *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNSWAdd(LHS, RHS);
+ }
+ Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNUWAdd(LHS, RHS);
+ }
+ Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFAdd(LHS, RHS);
+ }
+ Instruction *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNSWSub(LHS, RHS);
+ }
+ Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNUWSub(LHS, RHS);
+ }
+ Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFSub(LHS, RHS);
+ }
+ Instruction *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNSWMul(LHS, RHS);
+ }
+ Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateNUWMul(LHS, RHS);
+ }
+ Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFMul(LHS, RHS);
+ }
+ Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateUDiv(LHS, RHS);
+ return BinaryOperator::CreateExactUDiv(LHS, RHS);
+ }
+ Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateExactUDiv(LHS, RHS);
+ }
+ Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateSDiv(LHS, RHS);
+ return BinaryOperator::CreateExactSDiv(LHS, RHS);
+ }
+ Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateExactSDiv(LHS, RHS);
+ }
+ Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFDiv(LHS, RHS);
+ }
+ Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateURem(LHS, RHS);
+ }
+ Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateSRem(LHS, RHS);
+ }
+ Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateFRem(LHS, RHS);
+ }
+ Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
+ bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateLShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateLShr(LHS, RHS);
+ return BinaryOperator::CreateExactLShr(LHS, RHS);
+ }
+ Instruction *CreateAShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const {
+ if (!isExact)
+ return BinaryOperator::CreateAShr(LHS, RHS);
+ return BinaryOperator::CreateExactAShr(LHS, RHS);
+ }
+ Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateAnd(LHS, RHS);
+ }
+ Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateOr(LHS, RHS);
+ }
+ Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::CreateXor(LHS, RHS);
+ }
+
+ Instruction *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
+ return BinaryOperator::Create(Opc, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ Instruction *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const {
+ BinaryOperator *BO = BinaryOperator::CreateNeg(C);
+ if (HasNUW) BO->setHasNoUnsignedWrap();
+ if (HasNSW) BO->setHasNoSignedWrap();
+ return BO;
+ }
+ Instruction *CreateNSWNeg(Constant *C) const {
+ return BinaryOperator::CreateNSWNeg(C);
+ }
+ Instruction *CreateNUWNeg(Constant *C) const {
+ return BinaryOperator::CreateNUWNeg(C);
+ }
+ Instruction *CreateFNeg(Constant *C) const {
+ return BinaryOperator::CreateFNeg(C);
+ }
+ Instruction *CreateNot(Constant *C) const {
+ return BinaryOperator::CreateNot(C);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) const {
+ return ConstantExpr::getGetElementPtr(C, IdxList);
+ }
+ Instruction *CreateGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) const {
+ return GetElementPtrInst::Create(C, IdxList);
+ }
+
+ Constant *CreateInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) const {
+ return ConstantExpr::getInBoundsGetElementPtr(C, IdxList);
+ }
+ Instruction *CreateInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) const {
+ return GetElementPtrInst::CreateInBounds(C, IdxList);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
+ Type *DestTy) const {
+ return CastInst::Create(Op, C, DestTy);
+ }
+ Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
+ return CastInst::CreatePointerCast(C, DestTy);
+ }
+ Instruction *CreateIntCast(Constant *C, Type *DestTy,
+ bool isSigned) const {
+ return CastInst::CreateIntegerCast(C, DestTy, isSigned);
+ }
+ Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
+ return CastInst::CreateFPCast(C, DestTy);
+ }
+
+ Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::BitCast, C, DestTy);
+ }
+ Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::IntToPtr, C, DestTy);
+ }
+ Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::PtrToInt, C, DestTy);
+ }
+ Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+ return CastInst::CreateZExtOrBitCast(C, DestTy);
+ }
+ Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+ return CastInst::CreateSExtOrBitCast(C, DestTy);
+ }
+
+ Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+ return CastInst::CreateTruncOrBitCast(C, DestTy);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Instruction *CreateICmp(CmpInst::Predicate P,
+ Constant *LHS, Constant *RHS) const {
+ return new ICmpInst(P, LHS, RHS);
+ }
+ Instruction *CreateFCmp(CmpInst::Predicate P,
+ Constant *LHS, Constant *RHS) const {
+ return new FCmpInst(P, LHS, RHS);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ Instruction *CreateSelect(Constant *C,
+ Constant *True, Constant *False) const {
+ return SelectInst::Create(C, True, False);
+ }
+
+ Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ return ExtractElementInst::Create(Vec, Idx);
+ }
+
+ Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
+ return InsertElementInst::Create(Vec, NewElt, Idx);
+ }
+
+ Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
+ Constant *Mask) const {
+ return new ShuffleVectorInst(V1, V2, Mask);
+ }
+
+ Instruction *CreateExtractValue(Constant *Agg,
+ ArrayRef<unsigned> IdxList) const {
+ return ExtractValueInst::Create(Agg, IdxList);
+ }
+
+ Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
+ ArrayRef<unsigned> IdxList) const {
+ return InsertValueInst::Create(Agg, Val, IdxList);
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/OutputBuffer.h b/contrib/llvm/include/llvm/Support/OutputBuffer.h
new file mode 100644
index 000000000000..6b98e99e28e0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/OutputBuffer.h
@@ -0,0 +1,166 @@
+//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods to output values to a data buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
+#define LLVM_SUPPORT_OUTPUTBUFFER_H
+
+#include <cassert>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+ class OutputBuffer {
+ /// Output buffer.
+ std::vector<unsigned char> &Output;
+
+ /// is64Bit/isLittleEndian - This information is inferred from the target
+ /// machine directly, indicating what header values and flags to set.
+ bool is64Bit, isLittleEndian;
+ public:
+ OutputBuffer(std::vector<unsigned char> &Out,
+ bool is64bit, bool le)
+ : Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
+
+ // align - Emit padding into the file until the current output position is
+ // aligned to the specified power of two boundary.
+ void align(unsigned Boundary) {
+ assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
+ "Must align to 2^k boundary");
+ size_t Size = Output.size();
+
+ if (Size & (Boundary - 1)) {
+ // Add padding to get alignment to the correct place.
+ size_t Pad = Boundary - (Size & (Boundary - 1));
+ Output.resize(Size + Pad);
+ }
+ }
+
+ //===------------------------------------------------------------------===//
+ // Out Functions - Output the specified value to the data buffer.
+
+ void outbyte(unsigned char X) {
+ Output.push_back(X);
+ }
+ void outhalf(unsigned short X) {
+ if (isLittleEndian) {
+ Output.push_back(X & 255);
+ Output.push_back(X >> 8);
+ } else {
+ Output.push_back(X >> 8);
+ Output.push_back(X & 255);
+ }
+ }
+ void outword(unsigned X) {
+ if (isLittleEndian) {
+ Output.push_back((X >> 0) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 24) & 255);
+ } else {
+ Output.push_back((X >> 24) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 0) & 255);
+ }
+ }
+ void outxword(uint64_t X) {
+ if (isLittleEndian) {
+ Output.push_back(unsigned(X >> 0) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 56) & 255);
+ } else {
+ Output.push_back(unsigned(X >> 56) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 0) & 255);
+ }
+ }
+ void outaddr32(unsigned X) {
+ outword(X);
+ }
+ void outaddr64(uint64_t X) {
+ outxword(X);
+ }
+ void outaddr(uint64_t X) {
+ if (!is64Bit)
+ outword((unsigned)X);
+ else
+ outxword(X);
+ }
+ void outstring(const std::string &S, unsigned Length) {
+ unsigned len_to_copy = static_cast<unsigned>(S.length()) < Length
+ ? static_cast<unsigned>(S.length()) : Length;
+ unsigned len_to_fill = static_cast<unsigned>(S.length()) < Length
+ ? Length - static_cast<unsigned>(S.length()) : 0;
+
+ for (unsigned i = 0; i < len_to_copy; ++i)
+ outbyte(S[i]);
+
+ for (unsigned i = 0; i < len_to_fill; ++i)
+ outbyte(0);
+ }
+
+ //===------------------------------------------------------------------===//
+ // Fix Functions - Replace an existing entry at an offset.
+
+ void fixhalf(unsigned short X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
+ }
+ void fixword(unsigned X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
+ P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
+ P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
+ }
+ void fixxword(uint64_t X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 56)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 48)) & 255;
+ P[2] = (X >> (isLittleEndian ? 16 : 40)) & 255;
+ P[3] = (X >> (isLittleEndian ? 24 : 32)) & 255;
+ P[4] = (X >> (isLittleEndian ? 32 : 24)) & 255;
+ P[5] = (X >> (isLittleEndian ? 40 : 16)) & 255;
+ P[6] = (X >> (isLittleEndian ? 48 : 8)) & 255;
+ P[7] = (X >> (isLittleEndian ? 56 : 0)) & 255;
+ }
+ void fixaddr(uint64_t X, unsigned Offset) {
+ if (!is64Bit)
+ fixword((unsigned)X, Offset);
+ else
+ fixxword(X, Offset);
+ }
+
+ unsigned char &operator[](unsigned Index) {
+ return Output[Index];
+ }
+ const unsigned char &operator[](unsigned Index) const {
+ return Output[Index];
+ }
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_SUPPORT_OUTPUTBUFFER_H
diff --git a/contrib/llvm/include/llvm/Support/PassNameParser.h b/contrib/llvm/include/llvm/Support/PassNameParser.h
new file mode 100644
index 000000000000..a24a6f0c5e94
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PassNameParser.h
@@ -0,0 +1,137 @@
+//===- llvm/Support/PassNameParser.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 the PassNameParser and FilteredPassNameParser<> classes, which are
+// used to add command line arguments to a utility for all of the passes that
+// have been registered into the system.
+//
+// The PassNameParser class adds ALL passes linked into the system (that are
+// creatable) as command line arguments to the tool (when instantiated with the
+// appropriate command line option template). The FilteredPassNameParser<>
+// template is used for the same purposes as PassNameParser, except that it only
+// includes passes that have a PassType that are compatible with the filter
+// (which is the template argument).
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// PassNameParser class - Make use of the pass registration mechanism to
+// automatically add a command line argument to opt for each pass.
+//
+class PassNameParser : public PassRegistrationListener,
+ public cl::parser<const PassInfo*> {
+ cl::Option *Opt;
+public:
+ PassNameParser() : Opt(0) {}
+ virtual ~PassNameParser();
+
+ void initialize(cl::Option &O) {
+ Opt = &O;
+ cl::parser<const PassInfo*>::initialize(O);
+
+ // Add all of the passes to the map that got initialized before 'this' did.
+ enumeratePasses();
+ }
+
+ // ignorablePassImpl - Can be overriden in subclasses to refine the list of
+ // which passes we want to include.
+ //
+ virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
+
+ inline bool ignorablePass(const PassInfo *P) const {
+ // Ignore non-selectable and non-constructible passes! Ignore
+ // non-optimizations.
+ return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
+ P->getNormalCtor() == 0 || ignorablePassImpl(P);
+ }
+
+ // Implement the PassRegistrationListener callbacks used to populate our map
+ //
+ virtual void passRegistered(const PassInfo *P) {
+ if (ignorablePass(P) || !Opt) return;
+ if (findOption(P->getPassArgument()) != getNumOptions()) {
+ errs() << "Two passes with the same argument (-"
+ << P->getPassArgument() << ") attempted to be registered!\n";
+ llvm_unreachable(0);
+ }
+ addLiteralOption(P->getPassArgument(), P, P->getPassName());
+ }
+ virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
+
+ // printOptionInfo - Print out information about this option. Override the
+ // default implementation to sort the table before we print...
+ virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const {
+ PassNameParser *PNP = const_cast<PassNameParser*>(this);
+ array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
+ cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
+ }
+
+private:
+ // ValLessThan - Provide a sorting comparator for Values elements...
+ static int ValLessThan(const void *VT1, const void *VT2) {
+ typedef PassNameParser::OptionInfo ValType;
+ return std::strcmp(static_cast<const ValType *>(VT1)->Name,
+ static_cast<const ValType *>(VT2)->Name);
+ }
+};
+
+///===----------------------------------------------------------------------===//
+/// FilteredPassNameParser class - Make use of the pass registration
+/// mechanism to automatically add a command line argument to opt for
+/// each pass that satisfies a filter criteria. Filter should return
+/// true for passes to be registered as command-line options.
+///
+template<typename Filter>
+class FilteredPassNameParser : public PassNameParser {
+private:
+ Filter filter;
+
+public:
+ bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
+};
+
+///===----------------------------------------------------------------------===//
+/// PassArgFilter - A filter for use with PassNameFilterParser that only
+/// accepts a Pass whose Arg matches certain strings.
+///
+/// Use like this:
+///
+/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
+///
+/// static cl::list<
+/// const PassInfo*,
+/// bool,
+/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
+/// PassList(cl::desc("Passes available:"));
+///
+/// Only the -anders_aa and -dse options will be available to the user.
+///
+template<const char *Args>
+class PassArgFilter {
+public:
+ bool operator()(const PassInfo &P) const {
+ return(std::strstr(Args, P.getPassArgument()));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Path.h b/contrib/llvm/include/llvm/Support/Path.h
new file mode 100644
index 000000000000..196eecce8185
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Path.h
@@ -0,0 +1,16 @@
+//===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file currently includes both PathV1 and PathV2 to facilitate moving
+// clients over to the new interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/PathV1.h"
+#include "llvm/Support/PathV2.h"
diff --git a/contrib/llvm/include/llvm/Support/PathV1.h b/contrib/llvm/include/llvm/Support/PathV1.h
new file mode 100644
index 000000000000..f4bedf92c441
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PathV1.h
@@ -0,0 +1,743 @@
+//===- llvm/Support/PathV1.h - Path Operating System Concept ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PATH_H
+#define LLVM_SYSTEM_PATH_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/TimeValue.h"
+#include <set>
+#include <string>
+#include <vector>
+
+#define LLVM_PATH_DEPRECATED_MSG(replacement) \
+ "PathV1 has been deprecated and will be removed as soon as all LLVM and" \
+ " Clang clients have been moved over to PathV2. Please use `" #replacement \
+ "` from PathV2 instead."
+
+namespace llvm {
+namespace sys {
+
+ /// This structure provides basic file system information about a file. It
+ /// is patterned after the stat(2) Unix operating system call but made
+ /// platform independent and eliminates many of the unix-specific fields.
+ /// However, to support llvm-ar, the mode, user, and group fields are
+ /// retained. These pertain to unix security and may not have a meaningful
+ /// value on non-Unix platforms. However, the other fields should
+ /// always be applicable on all platforms. The structure is filled in by
+ /// the PathWithStatus class.
+ /// @brief File status structure
+ class FileStatus {
+ public:
+ uint64_t fileSize; ///< Size of the file in bytes
+ TimeValue modTime; ///< Time of file's modification
+ uint32_t mode; ///< Mode of the file, if applicable
+ uint32_t user; ///< User ID of owner, if applicable
+ uint32_t group; ///< Group ID of owner, if applicable
+ uint64_t uniqueID; ///< A number to uniquely ID this file
+ bool isDir : 1; ///< True if this is a directory.
+ bool isFile : 1; ///< True if this is a file.
+
+ FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999),
+ group(999), uniqueID(0), isDir(false), isFile(false) { }
+
+ TimeValue getTimestamp() const { return modTime; }
+ uint64_t getSize() const { return fileSize; }
+ uint32_t getMode() const { return mode; }
+ uint32_t getUser() const { return user; }
+ uint32_t getGroup() const { return group; }
+ uint64_t getUniqueID() const { return uniqueID; }
+ };
+
+ /// This class provides an abstraction for the path to a file or directory
+ /// in the operating system's filesystem and provides various basic operations
+ /// on it. Note that this class only represents the name of a path to a file
+ /// or directory which may or may not be valid for a given machine's file
+ /// system. The class is patterned after the java.io.File class with various
+ /// extensions and several omissions (not relevant to LLVM). A Path object
+ /// ensures that the path it encapsulates is syntactically valid for the
+ /// operating system it is running on but does not ensure correctness for
+ /// any particular file system. That is, a syntactically valid path might
+ /// specify path components that do not exist in the file system and using
+ /// such a Path to act on the file system could produce errors. There is one
+ /// invalid Path value which is permitted: the empty path. The class should
+ /// never allow a syntactically invalid non-empty path name to be assigned.
+ /// Empty paths are required in order to indicate an error result in some
+ /// situations. If the path is empty, the isValid operation will return
+ /// false. All operations will fail if isValid is false. Operations that
+ /// change the path will either return false if it would cause a syntactically
+ /// invalid path name (in which case the Path object is left unchanged) or
+ /// throw an std::string exception indicating the error. The methods are
+ /// grouped into four basic categories: Path Accessors (provide information
+ /// about the path without accessing disk), Disk Accessors (provide
+ /// information about the underlying file or directory), Path Mutators
+ /// (change the path information, not the disk), and Disk Mutators (change
+ /// the disk file/directory referenced by the path). The Disk Mutator methods
+ /// all have the word "disk" embedded in their method name to reinforce the
+ /// notion that the operation modifies the file system.
+ /// @since 1.4
+ /// @brief An abstraction for operating system paths.
+ class Path {
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a path to the root directory of the file system. The root
+ /// directory is a top level directory above which there are no more
+ /// directories. For example, on UNIX, the root directory is /. On Windows
+ /// it is file:///. Other operating systems may have different notions of
+ /// what the root directory is or none at all. In that case, a consistent
+ /// default root directory will be used.
+ LLVM_ATTRIBUTE_DEPRECATED(static Path GetRootDirectory(),
+ LLVM_PATH_DEPRECATED_MSG(NOTHING));
+
+ /// Construct a path to a unique temporary directory that is created in
+ /// a "standard" place for the operating system. The directory is
+ /// guaranteed to be created on exit from this function. If the directory
+ /// cannot be created, the function will throw an exception.
+ /// @returns an invalid path (empty) on error
+ /// @param ErrMsg Optional place for an error message if an error occurs
+ /// @brief Construct a path to an new, unique, existing temporary
+ /// directory.
+ static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
+
+ /// Construct a vector of sys::Path that contains the "standard" system
+ /// library paths suitable for linking into programs.
+ /// @brief Construct a path to the system library directory
+ static void GetSystemLibraryPaths(std::vector<sys::Path>& Paths);
+
+ /// Construct a vector of sys::Path that contains the "standard" bitcode
+ /// library paths suitable for linking into an llvm program. This function
+ /// *must* return the value of LLVM_LIB_SEARCH_PATH as well as the value
+ /// of LLVM_LIBDIR. It also must provide the System library paths as
+ /// returned by GetSystemLibraryPaths.
+ /// @see GetSystemLibraryPaths
+ /// @brief Construct a list of directories in which bitcode could be
+ /// found.
+ static void GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths);
+
+ /// Find the path to a library using its short name. Use the system
+ /// dependent library paths to locate the library.
+ /// @brief Find a library.
+ static Path FindLibrary(std::string& short_name);
+
+ /// Construct a path to the current user's home directory. The
+ /// implementation must use an operating system specific mechanism for
+ /// determining the user's home directory. For example, the environment
+ /// variable "HOME" could be used on Unix. If a given operating system
+ /// does not have the concept of a user's home directory, this static
+ /// constructor must provide the same result as GetRootDirectory.
+ /// @brief Construct a path to the current user's "home" directory
+ static Path GetUserHomeDirectory();
+
+ /// Construct a path to the current directory for the current process.
+ /// @returns The current working directory.
+ /// @brief Returns the current working directory.
+ static Path GetCurrentDirectory();
+
+ /// Return the suffix commonly used on file names that contain an
+ /// executable.
+ /// @returns The executable file suffix for the current platform.
+ /// @brief Return the executable file suffix.
+ static StringRef GetEXESuffix();
+
+ /// Return the suffix commonly used on file names that contain a shared
+ /// object, shared archive, or dynamic link library. Such files are
+ /// linked at runtime into a process and their code images are shared
+ /// between processes.
+ /// @returns The dynamic link library suffix for the current platform.
+ /// @brief Return the dynamic link library suffix.
+ static StringRef GetDLLSuffix();
+
+ /// GetMainExecutable - Return the path to the main executable, given the
+ /// value of argv[0] from program startup and the address of main itself.
+ /// In extremis, this function may fail and return an empty path.
+ static Path GetMainExecutable(const char *argv0, void *MainAddr);
+
+ /// This is one of the very few ways in which a path can be constructed
+ /// with a syntactically invalid name. The only *legal* invalid name is an
+ /// empty one. Other invalid names are not permitted. Empty paths are
+ /// provided so that they can be used to indicate null or error results in
+ /// other lib/System functionality.
+ /// @brief Construct an empty (and invalid) path.
+ Path() : path() {}
+ Path(const Path &that) : path(that.path) {}
+
+ /// This constructor will accept a char* or std::string as a path. No
+ /// checking is done on this path to determine if it is valid. To
+ /// determine validity of the path, use the isValid method.
+ /// @param p The path to assign.
+ /// @brief Construct a Path from a string.
+ explicit Path(StringRef p);
+
+ /// This constructor will accept a character range as a path. No checking
+ /// is done on this path to determine if it is valid. To determine
+ /// validity of the path, use the isValid method.
+ /// @param StrStart A pointer to the first character of the path name
+ /// @param StrLen The length of the path name at StrStart
+ /// @brief Construct a Path from a string.
+ Path(const char *StrStart, unsigned StrLen);
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ Path &operator=(const Path &that) {
+ path = that.path;
+ return *this;
+ }
+
+ /// Makes a copy of \p that to \p this.
+ /// @param that A StringRef denoting the path
+ /// @returns \p this
+ /// @brief Assignment Operator
+ Path &operator=(StringRef that);
+
+ /// Compares \p this Path with \p that Path for equality.
+ /// @returns true if \p this and \p that refer to the same thing.
+ /// @brief Equality Operator
+ bool operator==(const Path &that) const;
+
+ /// Compares \p this Path with \p that Path for inequality.
+ /// @returns true if \p this and \p that refer to different things.
+ /// @brief Inequality Operator
+ bool operator!=(const Path &that) const { return !(*this == that); }
+
+ /// Determines if \p this Path is less than \p that Path. This is required
+ /// so that Path objects can be placed into ordered collections (e.g.
+ /// std::map). The comparison is done lexicographically as defined by
+ /// the std::string::compare method.
+ /// @returns true if \p this path is lexicographically less than \p that.
+ /// @brief Less Than Operator
+ bool operator<(const Path& that) const;
+
+ /// @}
+ /// @name Path Accessors
+ /// @{
+ public:
+ /// This function will use an operating system specific algorithm to
+ /// determine if the current value of \p this is a syntactically valid
+ /// path name for the operating system. The path name does not need to
+ /// exist, validity is simply syntactical. Empty paths are always invalid.
+ /// @returns true iff the path name is syntactically legal for the
+ /// host operating system.
+ /// @brief Determine if a path is syntactically valid or not.
+ bool isValid() const;
+
+ /// This function determines if the contents of the path name are empty.
+ /// That is, the path name has a zero length. This does NOT determine if
+ /// if the file is empty. To get the length of the file itself, Use the
+ /// PathWithStatus::getFileStatus() method and then the getSize() method
+ /// on the returned FileStatus object.
+ /// @returns true iff the path is empty.
+ /// @brief Determines if the path name is empty (invalid).
+ bool isEmpty() const { return path.empty(); }
+
+ /// This function returns the last component of the path name. The last
+ /// component is the file or directory name occurring after the last
+ /// directory separator. If no directory separator is present, the entire
+ /// path name is returned (i.e. same as toString).
+ /// @returns StringRef containing the last component of the path name.
+ /// @brief Returns the last component of the path name.
+ LLVM_ATTRIBUTE_DEPRECATED(
+ StringRef getLast() const,
+ LLVM_PATH_DEPRECATED_MSG(path::filename));
+
+ /// This function strips off the path and suffix of the file or directory
+ /// name and returns just the basename. For example /a/foo.bar would cause
+ /// this function to return "foo".
+ /// @returns StringRef containing the basename of the path
+ /// @brief Get the base name of the path
+ LLVM_ATTRIBUTE_DEPRECATED(StringRef getBasename() const,
+ LLVM_PATH_DEPRECATED_MSG(path::stem));
+
+ /// This function strips off the suffix of the path beginning with the
+ /// path separator ('/' on Unix, '\' on Windows) and returns the result.
+ LLVM_ATTRIBUTE_DEPRECATED(StringRef getDirname() const,
+ LLVM_PATH_DEPRECATED_MSG(path::parent_path));
+
+ /// This function strips off the path and basename(up to and
+ /// including the last dot) of the file or directory name and
+ /// returns just the suffix. For example /a/foo.bar would cause
+ /// this function to return "bar".
+ /// @returns StringRef containing the suffix of the path
+ /// @brief Get the suffix of the path
+ LLVM_ATTRIBUTE_DEPRECATED(StringRef getSuffix() const,
+ LLVM_PATH_DEPRECATED_MSG(path::extension));
+
+ /// Obtain a 'C' string for the path name.
+ /// @returns a 'C' string containing the path name.
+ /// @brief Returns the path as a C string.
+ const char *c_str() const { return path.c_str(); }
+ const std::string &str() const { return path; }
+
+
+ /// size - Return the length in bytes of this path name.
+ size_t size() const { return path.size(); }
+
+ /// empty - Returns true if the path is empty.
+ unsigned empty() const { return path.empty(); }
+
+ /// @}
+ /// @name Disk Accessors
+ /// @{
+ public:
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @brief Determine if the path is absolute.
+ LLVM_ATTRIBUTE_DEPRECATED(
+ bool isAbsolute() const,
+ LLVM_PATH_DEPRECATED_MSG(path::is_absolute));
+
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @brief Determine if the path is absolute.
+ LLVM_ATTRIBUTE_DEPRECATED(
+ static bool isAbsolute(const char *NameStart, unsigned NameLen),
+ LLVM_PATH_DEPRECATED_MSG(path::is_absolute));
+
+ /// This function opens the file associated with the path name provided by
+ /// the Path object and reads its magic number. If the magic number at the
+ /// start of the file matches \p magic, true is returned. In all other
+ /// cases (file not found, file not accessible, etc.) it returns false.
+ /// @returns true if the magic number of the file matches \p magic.
+ /// @brief Determine if file has a specific magic number
+ LLVM_ATTRIBUTE_DEPRECATED(bool hasMagicNumber(StringRef magic) const,
+ LLVM_PATH_DEPRECATED_MSG(fs::has_magic));
+
+ /// This function retrieves the first \p len bytes of the file associated
+ /// with \p this. These bytes are returned as the "magic number" in the
+ /// \p Magic parameter.
+ /// @returns true if the Path is a file and the magic number is retrieved,
+ /// false otherwise.
+ /// @brief Get the file's magic number.
+ bool getMagicNumber(std::string& Magic, unsigned len) const;
+
+ /// This function determines if the path name in the object references an
+ /// archive file by looking at its magic number.
+ /// @returns true if the file starts with the magic number for an archive
+ /// file.
+ /// @brief Determine if the path references an archive file.
+ bool isArchive() const;
+
+ /// This function determines if the path name in the object references an
+ /// LLVM Bitcode file by looking at its magic number.
+ /// @returns true if the file starts with the magic number for LLVM
+ /// bitcode files.
+ /// @brief Determine if the path references a bitcode file.
+ bool isBitcodeFile() const;
+
+ /// This function determines if the path name in the object references a
+ /// native Dynamic Library (shared library, shared object) by looking at
+ /// the file's magic number. The Path object must reference a file, not a
+ /// directory.
+ /// @returns true if the file starts with the magic number for a native
+ /// shared library.
+ /// @brief Determine if the path references a dynamic library.
+ bool isDynamicLibrary() const;
+
+ /// This function determines if the path name in the object references a
+ /// native object file by looking at it's magic number. The term object
+ /// file is defined as "an organized collection of separate, named
+ /// sequences of binary data." This covers the obvious file formats such
+ /// as COFF and ELF, but it also includes llvm ir bitcode, archives,
+ /// libraries, etc...
+ /// @returns true if the file starts with the magic number for an object
+ /// file.
+ /// @brief Determine if the path references an object file.
+ bool isObjectFile() const;
+
+ /// This function determines if the path name references an existing file
+ /// or directory in the file system.
+ /// @returns true if the pathname references an existing file or
+ /// directory.
+ /// @brief Determines if the path is a file or directory in
+ /// the file system.
+ LLVM_ATTRIBUTE_DEPRECATED(bool exists() const,
+ LLVM_PATH_DEPRECATED_MSG(fs::exists));
+
+ /// This function determines if the path name references an
+ /// existing directory.
+ /// @returns true if the pathname references an existing directory.
+ /// @brief Determines if the path is a directory in the file system.
+ LLVM_ATTRIBUTE_DEPRECATED(bool isDirectory() const,
+ LLVM_PATH_DEPRECATED_MSG(fs::is_directory));
+
+ /// This function determines if the path name references an
+ /// existing symbolic link.
+ /// @returns true if the pathname references an existing symlink.
+ /// @brief Determines if the path is a symlink in the file system.
+ LLVM_ATTRIBUTE_DEPRECATED(bool isSymLink() const,
+ LLVM_PATH_DEPRECATED_MSG(fs::is_symlink));
+
+ /// This function determines if the path name references a readable file
+ /// or directory in the file system. This function checks for
+ /// the existence and readability (by the current program) of the file
+ /// or directory.
+ /// @returns true if the pathname references a readable file.
+ /// @brief Determines if the path is a readable file or directory
+ /// in the file system.
+ bool canRead() const;
+
+ /// This function determines if the path name references a writable file
+ /// or directory in the file system. This function checks for the
+ /// existence and writability (by the current program) of the file or
+ /// directory.
+ /// @returns true if the pathname references a writable file.
+ /// @brief Determines if the path is a writable file or directory
+ /// in the file system.
+ bool canWrite() const;
+
+ /// This function checks that what we're trying to work only on a regular
+ /// file. Check for things like /dev/null, any block special file, or
+ /// other things that aren't "regular" regular files.
+ /// @returns true if the file is S_ISREG.
+ /// @brief Determines if the file is a regular file
+ bool isRegularFile() const;
+
+ /// This function determines if the path name references an executable
+ /// file in the file system. This function checks for the existence and
+ /// executability (by the current program) of the file.
+ /// @returns true if the pathname references an executable file.
+ /// @brief Determines if the path is an executable file in the file
+ /// system.
+ bool canExecute() const;
+
+ /// This function builds a list of paths that are the names of the
+ /// files and directories in a directory.
+ /// @returns true if an error occurs, true otherwise
+ /// @brief Build a list of directory's contents.
+ bool getDirectoryContents(
+ std::set<Path> &paths, ///< The resulting list of file & directory names
+ std::string* ErrMsg ///< Optional place to return an error message.
+ ) const;
+
+ /// @}
+ /// @name Path Mutators
+ /// @{
+ public:
+ /// The path name is cleared and becomes empty. This is an invalid
+ /// path name but is the *only* invalid path name. This is provided
+ /// so that path objects can be used to indicate the lack of a
+ /// valid path being found.
+ /// @brief Make the path empty.
+ void clear() { path.clear(); }
+
+ /// This method sets the Path object to \p unverified_path. This can fail
+ /// if the \p unverified_path does not pass the syntactic checks of the
+ /// isValid() method. If verification fails, the Path object remains
+ /// unchanged and false is returned. Otherwise true is returned and the
+ /// Path object takes on the path value of \p unverified_path
+ /// @returns true if the path was set, false otherwise.
+ /// @param unverified_path The path to be set in Path object.
+ /// @brief Set a full path from a StringRef
+ bool set(StringRef unverified_path);
+
+ /// One path component is removed from the Path. If only one component is
+ /// present in the path, the Path object becomes empty. If the Path object
+ /// is empty, no change is made.
+ /// @returns false if the path component could not be removed.
+ /// @brief Removes the last directory component of the Path.
+ bool eraseComponent();
+
+ /// The \p component is added to the end of the Path if it is a legal
+ /// name for the operating system. A directory separator will be added if
+ /// needed.
+ /// @returns false if the path component could not be added.
+ /// @brief Appends one path component to the Path.
+ bool appendComponent(StringRef component);
+
+ /// A period and the \p suffix are appended to the end of the pathname.
+ /// When the \p suffix is empty, no action is performed.
+ /// @brief Adds a period and the \p suffix to the end of the pathname.
+ void appendSuffix(StringRef suffix);
+
+ /// The suffix of the filename is erased. The suffix begins with and
+ /// includes the last . character in the filename after the last directory
+ /// separator and extends until the end of the name. If no . character is
+ /// after the last directory separator, then the file name is left
+ /// unchanged (i.e. it was already without a suffix) but the function
+ /// returns false.
+ /// @returns false if there was no suffix to remove, true otherwise.
+ /// @brief Remove the suffix from a path name.
+ bool eraseSuffix();
+
+ /// The current Path name is made unique in the file system. Upon return,
+ /// the Path will have been changed to make a unique file in the file
+ /// system or it will not have been changed if the current path name is
+ /// already unique.
+ /// @throws std::string if an unrecoverable error occurs.
+ /// @brief Make the current path name unique in the file system.
+ bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
+
+ /// The current Path name is made absolute by prepending the
+ /// current working directory if necessary.
+ LLVM_ATTRIBUTE_DEPRECATED(
+ void makeAbsolute(),
+ LLVM_PATH_DEPRECATED_MSG(fs::make_absolute));
+
+ /// @}
+ /// @name Disk Mutators
+ /// @{
+ public:
+ /// This method attempts to make the file referenced by the Path object
+ /// available for reading so that the canRead() method will return true.
+ /// @brief Make the file readable;
+ bool makeReadableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method attempts to make the file referenced by the Path object
+ /// available for writing so that the canWrite() method will return true.
+ /// @brief Make the file writable;
+ bool makeWriteableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method attempts to make the file referenced by the Path object
+ /// available for execution so that the canExecute() method will return
+ /// true.
+ /// @brief Make the file readable;
+ bool makeExecutableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method allows the last modified time stamp and permission bits
+ /// to be set on the disk object referenced by the Path.
+ /// @throws std::string if an error occurs.
+ /// @returns true on error.
+ /// @brief Set the status information.
+ bool setStatusInfoOnDisk(const FileStatus &SI,
+ std::string *ErrStr = 0) const;
+
+ /// This method attempts to create a directory in the file system with the
+ /// same name as the Path object. The \p create_parents parameter controls
+ /// whether intermediate directories are created or not. if \p
+ /// create_parents is true, then an attempt will be made to create all
+ /// intermediate directories, as needed. If \p create_parents is false,
+ /// then only the final directory component of the Path name will be
+ /// created. The created directory will have no entries.
+ /// @returns true if the directory could not be created, false otherwise
+ /// @brief Create the directory this Path refers to.
+ bool createDirectoryOnDisk(
+ bool create_parents = false, ///< Determines whether non-existent
+ ///< directory components other than the last one (the "parents")
+ ///< are created or not.
+ std::string* ErrMsg = 0 ///< Optional place to put error messages.
+ );
+
+ /// This method attempts to create a file in the file system with the same
+ /// name as the Path object. The intermediate directories must all exist
+ /// at the time this method is called. Use createDirectoriesOnDisk to
+ /// accomplish that. The created file will be empty upon return from this
+ /// function.
+ /// @returns true if the file could not be created, false otherwise.
+ /// @brief Create the file this Path refers to.
+ bool createFileOnDisk(
+ std::string* ErrMsg = 0 ///< Optional place to put error messages.
+ );
+
+ /// This is like createFile except that it creates a temporary file. A
+ /// unique temporary file name is generated based on the contents of
+ /// \p this before the call. The new name is assigned to \p this and the
+ /// file is created. Note that this will both change the Path object
+ /// *and* create the corresponding file. This function will ensure that
+ /// the newly generated temporary file name is unique in the file system.
+ /// @returns true if the file couldn't be created, false otherwise.
+ /// @brief Create a unique temporary file
+ bool createTemporaryFileOnDisk(
+ bool reuse_current = false, ///< When set to true, this parameter
+ ///< indicates that if the current file name does not exist then
+ ///< it will be used without modification.
+ std::string* ErrMsg = 0 ///< Optional place to put error messages
+ );
+
+ /// This method renames the file referenced by \p this as \p newName. The
+ /// file referenced by \p this must exist. The file referenced by
+ /// \p newName does not need to exist.
+ /// @returns true on error, false otherwise
+ /// @brief Rename one file as another.
+ bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
+
+ /// This method attempts to destroy the file or directory named by the
+ /// last component of the Path. If the Path refers to a directory and the
+ /// \p destroy_contents is false, an attempt will be made to remove just
+ /// the directory (the final Path component). If \p destroy_contents is
+ /// true, an attempt will be made to remove the entire contents of the
+ /// directory, recursively. If the Path refers to a file, the
+ /// \p destroy_contents parameter is ignored.
+ /// @param destroy_contents Indicates whether the contents of a destroyed
+ /// @param Err An optional string to receive an error message.
+ /// directory should also be destroyed (recursively).
+ /// @returns false if the file/directory was destroyed, true on error.
+ /// @brief Removes the file or directory from the filesystem.
+ bool eraseFromDisk(bool destroy_contents = false,
+ std::string *Err = 0) const;
+
+
+ /// MapInFilePages - This is a low level system API to map in the file
+ /// that is currently opened as FD into the current processes' address
+ /// space for read only access. This function may return null on failure
+ /// or if the system cannot provide the following constraints:
+ /// 1) The pages must be valid after the FD is closed, until
+ /// UnMapFilePages is called.
+ /// 2) Any padding after the end of the file must be zero filled, if
+ /// present.
+ /// 3) The pages must be contiguous.
+ ///
+ /// This API is not intended for general use, clients should use
+ /// MemoryBuffer::getFile instead.
+ static const char *MapInFilePages(int FD, size_t FileSize,
+ off_t Offset);
+
+ /// UnMapFilePages - Free pages mapped into the current process by
+ /// MapInFilePages.
+ ///
+ /// This API is not intended for general use, clients should use
+ /// MemoryBuffer::getFile instead.
+ static void UnMapFilePages(const char *Base, size_t FileSize);
+
+ /// @}
+ /// @name Data
+ /// @{
+ protected:
+ // Our win32 implementation relies on this string being mutable.
+ mutable std::string path; ///< Storage for the path name.
+
+
+ /// @}
+ };
+
+ /// This class is identical to Path class except it allows you to obtain the
+ /// file status of the Path as well. The reason for the distinction is one of
+ /// efficiency. First, the file status requires additional space and the space
+ /// is incorporated directly into PathWithStatus without an additional malloc.
+ /// Second, obtaining status information is an expensive operation on most
+ /// operating systems so we want to be careful and explicit about where we
+ /// allow this operation in LLVM.
+ /// @brief Path with file status class.
+ class PathWithStatus : public Path {
+ /// @name Constructors
+ /// @{
+ public:
+ /// @brief Default constructor
+ PathWithStatus() : Path(), status(), fsIsValid(false) {}
+
+ /// @brief Copy constructor
+ PathWithStatus(const PathWithStatus &that)
+ : Path(static_cast<const Path&>(that)), status(that.status),
+ fsIsValid(that.fsIsValid) {}
+
+ /// This constructor allows construction from a Path object
+ /// @brief Path constructor
+ PathWithStatus(const Path &other)
+ : Path(other), status(), fsIsValid(false) {}
+
+ /// This constructor will accept a char* or std::string as a path. No
+ /// checking is done on this path to determine if it is valid. To
+ /// determine validity of the path, use the isValid method.
+ /// @brief Construct a Path from a string.
+ explicit PathWithStatus(
+ StringRef p ///< The path to assign.
+ ) : Path(p), status(), fsIsValid(false) {}
+
+ /// This constructor will accept a character range as a path. No checking
+ /// is done on this path to determine if it is valid. To determine
+ /// validity of the path, use the isValid method.
+ /// @brief Construct a Path from a string.
+ explicit PathWithStatus(
+ const char *StrStart, ///< Pointer to the first character of the path
+ unsigned StrLen ///< Length of the path.
+ ) : Path(StrStart, StrLen), status(), fsIsValid(false) {}
+
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ PathWithStatus &operator=(const PathWithStatus &that) {
+ static_cast<Path&>(*this) = static_cast<const Path&>(that);
+ status = that.status;
+ fsIsValid = that.fsIsValid;
+ return *this;
+ }
+
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ PathWithStatus &operator=(const Path &that) {
+ static_cast<Path&>(*this) = static_cast<const Path&>(that);
+ fsIsValid = false;
+ return *this;
+ }
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+ /// This function returns status information about the file. The type of
+ /// path (file or directory) is updated to reflect the actual contents
+ /// of the file system.
+ /// @returns 0 on failure, with Error explaining why (if non-zero)
+ /// @returns a pointer to a FileStatus structure on success.
+ /// @brief Get file status.
+ const FileStatus *getFileStatus(
+ bool forceUpdate = false, ///< Force an update from the file system
+ std::string *Error = 0 ///< Optional place to return an error msg.
+ ) const;
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ mutable FileStatus status; ///< Status information.
+ mutable bool fsIsValid; ///< Whether we've obtained it or not
+
+ /// @}
+ };
+
+ /// This enumeration delineates the kinds of files that LLVM knows about.
+ enum LLVMFileType {
+ Unknown_FileType = 0, ///< Unrecognized file
+ Bitcode_FileType, ///< Bitcode file
+ Archive_FileType, ///< ar style archive file
+ ELF_Relocatable_FileType, ///< ELF Relocatable object file
+ ELF_Executable_FileType, ///< ELF Executable image
+ ELF_SharedObject_FileType, ///< ELF dynamically linked shared lib
+ ELF_Core_FileType, ///< ELF core image
+ Mach_O_Object_FileType, ///< Mach-O Object file
+ Mach_O_Executable_FileType, ///< Mach-O Executable
+ Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM
+ Mach_O_Core_FileType, ///< Mach-O Core File
+ Mach_O_PreloadExecutable_FileType, ///< Mach-O Preloaded Executable
+ Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib
+ Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker
+ Mach_O_Bundle_FileType, ///< Mach-O Bundle file
+ Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub
+ Mach_O_DSYMCompanion_FileType, ///< Mach-O dSYM companion file
+ COFF_FileType ///< COFF object file or lib
+ };
+
+ /// This utility function allows any memory block to be examined in order
+ /// to determine its file type.
+ LLVMFileType IdentifyFileType(const char*magic, unsigned length);
+
+ /// This function can be used to copy the file specified by Src to the
+ /// file specified by Dest. If an error occurs, Dest is removed.
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Copy one file to another.
+ bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg);
+
+ /// This is the OS-specific path separator: a colon on Unix or a semicolon
+ /// on Windows.
+ extern const char PathSeparator;
+}
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/PathV2.h b/contrib/llvm/include/llvm/Support/PathV2.h
new file mode 100644
index 000000000000..6d38c9571558
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PathV2.h
@@ -0,0 +1,358 @@
+//===- llvm/Support/PathV2.h - Path Operating System Concept ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::path namespace. It is designed after
+// TR2/boost filesystem (v3), but modified to remove exception handling and the
+// path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATHV2_H
+#define LLVM_SUPPORT_PATHV2_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/DataTypes.h"
+#include <iterator>
+
+namespace llvm {
+namespace sys {
+namespace path {
+
+/// @name Lexical Component Iterator
+/// @{
+
+/// @brief Path iterator.
+///
+/// This is a bidirectional iterator that iterates over the individual
+/// components in \a path. The forward traversal order is as follows:
+/// * The root-name element, if present.
+/// * The root-directory element, if present.
+/// * Each successive filename element, if present.
+/// * Dot, if one or more trailing non-root slash characters are present.
+/// 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
+///
+class const_iterator {
+ StringRef Path; //< The entire path.
+ StringRef Component; //< The current component. Not necessarily in Path.
+ size_t Position; //< The iterators current position within Path.
+
+ // An end iterator has Position = Path.size() + 1.
+ friend const_iterator begin(StringRef path);
+ friend const_iterator end(StringRef path);
+
+public:
+ typedef const StringRef value_type;
+ typedef ptrdiff_t difference_type;
+ typedef value_type &reference;
+ typedef value_type *pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ reference operator*() const { return Component; }
+ pointer operator->() const { return &Component; }
+ const_iterator &operator++(); // preincrement
+ const_iterator &operator++(int); // postincrement
+ const_iterator &operator--(); // predecrement
+ const_iterator &operator--(int); // postdecrement
+ bool operator==(const const_iterator &RHS) const;
+ bool operator!=(const const_iterator &RHS) const;
+
+ /// @brief Difference in bytes between this and RHS.
+ ptrdiff_t operator-(const const_iterator &RHS) const;
+};
+
+typedef std::reverse_iterator<const_iterator> reverse_iterator;
+
+/// @brief Get begin iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized with the first component of \a path.
+const_iterator begin(StringRef path);
+
+/// @brief Get end iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized to the end of \a path.
+const_iterator end(StringRef path);
+
+/// @brief Get reverse begin iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized with the first reverse component of \a path.
+inline reverse_iterator rbegin(StringRef path) {
+ return reverse_iterator(end(path));
+}
+
+/// @brief Get reverse end iterator over \a path.
+/// @param path Input path.
+/// @returns Iterator initialized to the reverse end of \a path.
+inline reverse_iterator rend(StringRef path) {
+ return reverse_iterator(begin(path));
+}
+
+/// @}
+/// @name Lexical Modifiers
+/// @{
+
+/// @brief Remove the last component from \a path unless it is the root dir.
+///
+/// directory/filename.cpp => directory/
+/// directory/ => directory
+/// / => /
+///
+/// @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
+///
+/// @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
+/// optionally start with a '.', if it does not, one will be
+/// prepended.
+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
+///
+/// @param path Set to \a path + \a component.
+/// @param component The component to be appended to \a path.
+void append(SmallVectorImpl<char> &path, const Twine &a,
+ const Twine &b = "",
+ const Twine &c = "",
+ const Twine &d = "");
+
+/// @brief Append to path.
+///
+/// /foo + [bar,f] => /foo/bar/f
+/// /foo/ + [bar,f] => /foo/bar/f
+/// foo + [bar,f] => foo/bar/f
+///
+/// @param path Set to \a path + [\a begin, \a end).
+/// @param begin Start of components to append.
+/// @param end One past the end of components to append.
+void append(SmallVectorImpl<char> &path,
+ const_iterator begin, const_iterator end);
+
+/// @}
+/// @name Transforms (or some other better name)
+/// @{
+
+/// Convert path to the native form. This is used to give paths to users and
+/// operating system calls in the platform's normal way. For example, on Windows
+/// all '/' are converted to '\'.
+///
+/// @param path A path that is transformed to native format.
+/// @param result Holds the result of the transformation.
+void native(const Twine &path, SmallVectorImpl<char> &result);
+
+/// @}
+/// @name Lexical Observers
+/// @{
+
+/// @brief Get root name.
+///
+/// //net/hello => //net
+/// c:/hello => c: (on Windows, on other platforms nothing)
+/// /hello => <empty>
+///
+/// @param path Input path.
+/// @result The root name of \a path if it has one, otherwise "".
+const StringRef root_name(StringRef path);
+
+/// @brief Get root directory.
+///
+/// /goo/hello => /
+/// c:/hello => /
+/// d/file.txt => <empty>
+///
+/// @param path Input path.
+/// @result The root directory of \a path if it has one, otherwise
+/// "".
+const StringRef root_directory(StringRef path);
+
+/// @brief Get root path.
+///
+/// Equivalent to root_name + root_directory.
+///
+/// @param path Input path.
+/// @result The root path of \a path if it has one, otherwise "".
+const StringRef root_path(StringRef path);
+
+/// @brief Get relative path.
+///
+/// C:\hello\world => hello\world
+/// foo/bar => foo/bar
+/// /foo/bar => foo/bar
+///
+/// @param path Input path.
+/// @result The path starting after root_path if one exists, otherwise "".
+const StringRef relative_path(StringRef path);
+
+/// @brief Get parent path.
+///
+/// / => <empty>
+/// /foo => /
+/// foo/../bar => foo/..
+///
+/// @param path Input path.
+/// @result The parent path of \a path if one exists, otherwise "".
+const StringRef parent_path(StringRef path);
+
+/// @brief Get filename.
+///
+/// /foo.txt => foo.txt
+/// . => .
+/// .. => ..
+/// / => /
+///
+/// @param path Input path.
+/// @result The filename part of \a path. This is defined as the last component
+/// of \a path.
+const StringRef filename(StringRef path);
+
+/// @brief Get stem.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// 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/.. => ..
+///
+/// @param path Input path.
+/// @result The stem of \a path.
+const StringRef stem(StringRef path);
+
+/// @brief Get extension.
+///
+/// If filename contains a dot but not solely one or two dots, result is the
+/// 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
+///
+/// @param path Input path.
+/// @result The extension of \a path.
+const StringRef extension(StringRef path);
+
+/// @brief Check whether the given char is a path separator on the host OS.
+///
+/// @param value a character
+/// @result true if \a value is a path separator character on the host OS
+bool is_separator(char value);
+
+/// @brief Get the typical temporary directory for the system, e.g.,
+/// "/var/tmp" or "C:/TEMP"
+///
+/// @param erasedOnReboot Whether to favor a path that is erased on reboot
+/// rather than one that potentially persists longer. This parameter will be
+/// ignored if the user or system has set the typical environment variable
+/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory.
+///
+/// @param Result Holds the resulting path name.
+void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
+
+/// @brief Has root name?
+///
+/// root_name != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root name, false otherwise.
+bool has_root_name(const Twine &path);
+
+/// @brief Has root directory?
+///
+/// root_directory != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root directory, false otherwise.
+bool has_root_directory(const Twine &path);
+
+/// @brief Has root path?
+///
+/// root_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a root path, false otherwise.
+bool has_root_path(const Twine &path);
+
+/// @brief Has relative path?
+///
+/// relative_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a relative path, false otherwise.
+bool has_relative_path(const Twine &path);
+
+/// @brief Has parent path?
+///
+/// parent_path != ""
+///
+/// @param path Input path.
+/// @result True if the path has a parent path, false otherwise.
+bool has_parent_path(const Twine &path);
+
+/// @brief Has filename?
+///
+/// filename != ""
+///
+/// @param path Input path.
+/// @result True if the path has a filename, false otherwise.
+bool has_filename(const Twine &path);
+
+/// @brief Has stem?
+///
+/// stem != ""
+///
+/// @param path Input path.
+/// @result True if the path has a stem, false otherwise.
+bool has_stem(const Twine &path);
+
+/// @brief Has extension?
+///
+/// extension != ""
+///
+/// @param path Input path.
+/// @result True if the path has a extension, false otherwise.
+bool has_extension(const Twine &path);
+
+/// @brief Is path absolute?
+///
+/// @param path Input path.
+/// @result True if the path is absolute, false if it is not.
+bool is_absolute(const Twine &path);
+
+/// @brief Is path relative?
+///
+/// @param path Input path.
+/// @result True if the path is relative, false if it is not.
+bool is_relative(const Twine &path);
+
+} // end namespace path
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/PatternMatch.h b/contrib/llvm/include/llvm/Support/PatternMatch.h
new file mode 100644
index 000000000000..221fa8b3ebf9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PatternMatch.h
@@ -0,0 +1,824 @@
+//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- 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 simple and efficient mechanism for performing general
+// tree-based pattern matches on the LLVM IR. The power of these routines is
+// that it allows you to write concise patterns that are expressive and easy to
+// understand. The other major advantage of this is that it allows you to
+// trivially capture/bind elements in the pattern to variables. For example,
+// you can do something like this:
+//
+// Value *Exp = ...
+// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
+// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
+// m_And(m_Value(Y), m_ConstantInt(C2))))) {
+// ... Pattern is matched and variables are bound ...
+// }
+//
+// This is primarily useful to things like the instruction combiner, but can
+// also be useful for static analysis tools or code generators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATTERNMATCH_H
+#define LLVM_SUPPORT_PATTERNMATCH_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Operator.h"
+
+namespace llvm {
+namespace PatternMatch {
+
+template<typename Val, typename Pattern>
+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);
+ }
+};
+
+template<typename T>
+inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; }
+
+
+template<typename Class>
+struct class_match {
+ template<typename ITy>
+ bool match(ITy *V) { return isa<Class>(V); }
+};
+
+/// m_Value() - Match an arbitrary value and ignore it.
+inline class_match<Value> m_Value() { return class_match<Value>(); }
+/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it.
+inline class_match<ConstantInt> m_ConstantInt() {
+ return class_match<ConstantInt>();
+}
+/// m_Undef() - Match an arbitrary undef constant.
+inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
+
+inline class_match<Constant> m_Constant() { return class_match<Constant>(); }
+
+struct match_zero {
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const Constant *C = dyn_cast<Constant>(V))
+ return C->isNullValue();
+ 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 apint_match {
+ const APInt *&Res;
+ apint_match(const APInt *&R) : Res(R) {}
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ 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;
+ }
+ 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>
+ bool match(ITy *V) {
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ const APInt &CIV = CI->getValue();
+ if (Val >= 0)
+ return CIV == static_cast<uint64_t>(Val);
+ // If Val is negative, and CI is shorter than it, truncate to the right
+ // number of bits. If it is larger, then we have to sign extend. Just
+ // compare their negated values.
+ return -CIV == -Val;
+ }
+ return false;
+ }
+};
+
+/// m_ConstantInt<int64_t> - Match a ConstantInt with a specific value.
+template<int64_t Val>
+inline constantint_match<Val> m_ConstantInt() {
+ return constantint_match<Val>();
+}
+
+/// cst_pred_ty - This helper class is used to match scalar and vector constants
+/// that satisfy a specified predicate.
+template<typename Predicate>
+struct cst_pred_ty : public Predicate {
+ template<typename ITy>
+ 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());
+ 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>
+struct api_pred_ty : public Predicate {
+ const APInt *&Res;
+ api_pred_ty(const APInt *&R) : Res(R) {}
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (const ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ if (this->isValue(CI->getValue())) {
+ 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;
+ }
+
+ return false;
+ }
+};
+
+
+struct is_one {
+ bool isValue(const APInt &C) { return C == 1; }
+};
+
+/// 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; }
+
+struct is_sign_bit {
+ bool isValue(const APInt &C) { return C.isSignBit(); }
+};
+
+/// m_SignBit() - Match an integer or vector with only the sign bit(s) set.
+inline cst_pred_ty<is_sign_bit> m_SignBit() {return cst_pred_ty<is_sign_bit>();}
+inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; }
+
+struct is_power2 {
+ bool isValue(const APInt &C) { return C.isPowerOf2(); }
+};
+
+/// m_Power2() - Match an integer or vector power of 2.
+inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
+inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
+
+template<typename Class>
+struct bind_ty {
+ Class *&VR;
+ bind_ty(Class *&V) : VR(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (Class *CV = dyn_cast<Class>(V)) {
+ VR = CV;
+ return true;
+ }
+ return false;
+ }
+};
+
+/// m_Value - Match a value, capturing it if we match.
+inline bind_ty<Value> m_Value(Value *&V) { return V; }
+
+/// m_ConstantInt - Match a ConstantInt, capturing the value if we match.
+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; }
+
+/// specificval_ty - Match a specified Value*.
+struct specificval_ty {
+ const Value *Val;
+ specificval_ty(const Value *V) : Val(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ return V == Val;
+ }
+};
+
+/// m_Specific - Match if we have a specific specified value.
+inline specificval_ty m_Specific(const Value *V) { return V; }
+
+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))
+ if (CV->getBitWidth() <= 64) {
+ VR = CV->getZExtValue();
+ return true;
+ }
+ return false;
+ }
+};
+
+/// 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.
+//
+
+template<typename LHS_t, typename RHS_t, unsigned Opcode>
+struct BinaryOp_match {
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Opcode) {
+ BinaryOperator *I = cast<BinaryOperator>(V);
+ return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Add>
+m_Add(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FAdd>
+m_FAdd(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Sub>
+m_Sub(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FSub>
+m_FSub(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Mul>
+m_Mul(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FMul>
+m_FMul(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv>
+m_UDiv(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv>
+m_SDiv(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv>
+m_FDiv(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::URem>
+m_URem(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SRem>
+m_SRem(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FRem>
+m_FRem(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::And>
+m_And(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Or>
+m_Or(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Xor>
+m_Xor(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Shl>
+m_Shl(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::LShr>
+m_LShr(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::AShr>
+m_AShr(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Class that matches two different binary ops.
+//
+template<typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2>
+struct BinOp2_match {
+ LHS_t L;
+ RHS_t R;
+
+ BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Opc1 ||
+ V->getValueID() == Value::InstructionVal + Opc2) {
+ BinaryOperator *I = cast<BinaryOperator>(V);
+ return L.match(I->getOperand(0)) && R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) &&
+ L.match(CE->getOperand(0)) && R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+/// m_Shr - Matches LShr or AShr.
+template<typename LHS, typename RHS>
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>
+m_Shr(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R);
+}
+
+/// m_LogicalShift - Matches LShr or Shl.
+template<typename LHS, typename RHS>
+inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>
+m_LogicalShift(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R);
+}
+
+/// m_IDiv - Matches UDiv and SDiv.
+template<typename LHS, typename RHS>
+inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>
+m_IDiv(const LHS &L, const RHS &R) {
+ return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Class that matches exact binary ops.
+//
+template<typename SubPattern_t>
+struct Exact_match {
+ SubPattern_t SubPattern;
+
+ Exact_match(const SubPattern_t &SP) : SubPattern(SP) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (PossiblyExactOperator *PEO = dyn_cast<PossiblyExactOperator>(V))
+ return PEO->isExact() && SubPattern.match(V);
+ return false;
+ }
+};
+
+template<typename T>
+inline Exact_match<T> m_Exact(const T &SubPattern) { return SubPattern; }
+
+//===----------------------------------------------------------------------===//
+// Matchers for CmpInst classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+struct CmpClass_match {
+ PredicateTy &Predicate;
+ LHS_t L;
+ RHS_t R;
+
+ CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS)
+ : Predicate(Pred), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ Predicate = I->getPredicate();
+ return true;
+ }
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ ICmpInst, ICmpInst::Predicate>(Pred, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ FCmpInst, FCmpInst::Predicate>(Pred, L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for SelectInst classes
+//
+
+template<typename Cond_t, typename LHS_t, typename RHS_t>
+struct SelectClass_match {
+ Cond_t C;
+ LHS_t L;
+ RHS_t R;
+
+ SelectClass_match(const Cond_t &Cond, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : C(Cond), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (SelectInst *I = dyn_cast<SelectInst>(V))
+ return C.match(I->getOperand(0)) &&
+ L.match(I->getOperand(1)) &&
+ R.match(I->getOperand(2));
+ return false;
+ }
+};
+
+template<typename Cond, typename LHS, typename RHS>
+inline SelectClass_match<Cond, LHS, RHS>
+m_Select(const Cond &C, const LHS &L, const RHS &R) {
+ return SelectClass_match<Cond, LHS, RHS>(C, L, R);
+}
+
+/// m_SelectCst - This matches a select of two constants, e.g.:
+/// m_SelectCst<-1, 0>(m_Value(V))
+template<int64_t L, int64_t R, typename Cond>
+inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R> >
+m_SelectCst(const Cond &C) {
+ return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>());
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for CastInst classes
+//
+
+template<typename Op_t, unsigned Opcode>
+struct CastClass_match {
+ Op_t Op;
+
+ CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Operator *O = dyn_cast<Operator>(V))
+ return O->getOpcode() == Opcode && Op.match(O->getOperand(0));
+ return false;
+ }
+};
+
+/// m_BitCast
+template<typename OpTy>
+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>
+m_PtrToInt(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::PtrToInt>(Op);
+}
+
+/// m_Trunc
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::Trunc>
+m_Trunc(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::Trunc>(Op);
+}
+
+/// m_SExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::SExt>
+m_SExt(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::SExt>(Op);
+}
+
+/// m_ZExt
+template<typename OpTy>
+inline CastClass_match<OpTy, Instruction::ZExt>
+m_ZExt(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::ZExt>(Op);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for unary operators
+//
+
+template<typename LHS_t>
+struct not_match {
+ LHS_t L;
+
+ not_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Operator *O = dyn_cast<Operator>(V))
+ if (O->getOpcode() == Instruction::Xor)
+ return matchIfNot(O->getOperand(0), O->getOperand(1));
+ return false;
+ }
+private:
+ bool matchIfNot(Value *LHS, Value *RHS) {
+ return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) ||
+ // FIXME: Remove CV.
+ isa<ConstantVector>(RHS)) &&
+ cast<Constant>(RHS)->isAllOnesValue() &&
+ L.match(LHS);
+ }
+};
+
+template<typename LHS>
+inline not_match<LHS> m_Not(const LHS &L) { return L; }
+
+
+template<typename LHS_t>
+struct neg_match {
+ LHS_t L;
+
+ neg_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Operator *O = dyn_cast<Operator>(V))
+ if (O->getOpcode() == Instruction::Sub)
+ return matchIfNeg(O->getOperand(0), O->getOperand(1));
+ return false;
+ }
+private:
+ bool matchIfNeg(Value *LHS, Value *RHS) {
+ return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) ||
+ isa<ConstantAggregateZero>(LHS)) &&
+ L.match(RHS);
+ }
+};
+
+/// m_Neg - Match an integer negate.
+template<typename LHS>
+inline neg_match<LHS> m_Neg(const LHS &L) { return L; }
+
+
+template<typename LHS_t>
+struct fneg_match {
+ LHS_t L;
+
+ fneg_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Operator *O = dyn_cast<Operator>(V))
+ if (O->getOpcode() == Instruction::FSub)
+ return matchIfFNeg(O->getOperand(0), O->getOperand(1));
+ return false;
+ }
+private:
+ bool matchIfFNeg(Value *LHS, Value *RHS) {
+ if (ConstantFP *C = dyn_cast<ConstantFP>(LHS))
+ return C->isNegativeZeroValue() && L.match(RHS);
+ return false;
+ }
+};
+
+/// m_FNeg - Match a floating point negate.
+template<typename LHS>
+inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; }
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for control flow.
+//
+
+template<typename Cond_t>
+struct brc_match {
+ Cond_t Cond;
+ BasicBlock *&T, *&F;
+ brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
+ : Cond(C), T(t), F(f) {
+ }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(V))
+ if (BI->isConditional() && Cond.match(BI->getCondition())) {
+ T = BI->getSuccessor(0);
+ F = BI->getSuccessor(1);
+ return true;
+ }
+ return false;
+ }
+};
+
+template<typename Cond_t>
+inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) {
+ return brc_match<Cond_t>(C, T, F);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y).
+//
+
+template<typename LHS_t, typename RHS_t, typename Pred_t>
+struct MaxMin_match {
+ LHS_t L;
+ RHS_t R;
+
+ MaxMin_match(const LHS_t &LHS, const RHS_t &RHS)
+ : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x".
+ SelectInst *SI = dyn_cast<SelectInst>(V);
+ if (!SI)
+ return false;
+ ICmpInst *Cmp = dyn_cast<ICmpInst>(SI->getCondition());
+ if (!Cmp)
+ return false;
+ // At this point we have a select conditioned on a comparison. Check that
+ // it is the values returned by the select that are being compared.
+ Value *TrueVal = SI->getTrueValue();
+ Value *FalseVal = SI->getFalseValue();
+ Value *LHS = Cmp->getOperand(0);
+ Value *RHS = Cmp->getOperand(1);
+ if ((TrueVal != LHS || FalseVal != RHS) &&
+ (TrueVal != RHS || FalseVal != LHS))
+ return false;
+ ICmpInst::Predicate Pred = LHS == TrueVal ?
+ Cmp->getPredicate() : Cmp->getSwappedPredicate();
+ // Does "(x pred y) ? x : y" represent the desired max/min operation?
+ if (!Pred_t::match(Pred))
+ return false;
+ // It does! Bind the operands.
+ return L.match(LHS) && R.match(RHS);
+ }
+};
+
+/// smax_pred_ty - Helper class for identifying signed max predicates.
+struct smax_pred_ty {
+ static bool match(ICmpInst::Predicate Pred) {
+ return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE;
+ }
+};
+
+/// smin_pred_ty - Helper class for identifying signed min predicates.
+struct smin_pred_ty {
+ static bool match(ICmpInst::Predicate Pred) {
+ return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE;
+ }
+};
+
+/// umax_pred_ty - Helper class for identifying unsigned max predicates.
+struct umax_pred_ty {
+ static bool match(ICmpInst::Predicate Pred) {
+ return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE;
+ }
+};
+
+/// umin_pred_ty - Helper class for identifying unsigned min predicates.
+struct umin_pred_ty {
+ static bool match(ICmpInst::Predicate Pred) {
+ return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<LHS, RHS, smax_pred_ty>
+m_SMax(const LHS &L, const RHS &R) {
+ return MaxMin_match<LHS, RHS, smax_pred_ty>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<LHS, RHS, smin_pred_ty>
+m_SMin(const LHS &L, const RHS &R) {
+ return MaxMin_match<LHS, RHS, smin_pred_ty>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<LHS, RHS, umax_pred_ty>
+m_UMax(const LHS &L, const RHS &R) {
+ return MaxMin_match<LHS, RHS, umax_pred_ty>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline MaxMin_match<LHS, RHS, umin_pred_ty>
+m_UMin(const LHS &L, const RHS &R) {
+ return MaxMin_match<LHS, RHS, umin_pred_ty>(L, R);
+}
+
+} // end namespace PatternMatch
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/PluginLoader.h b/contrib/llvm/include/llvm/Support/PluginLoader.h
new file mode 100644
index 000000000000..bdbb134b28eb
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PluginLoader.h
@@ -0,0 +1,37 @@
+//===-- llvm/Support/PluginLoader.h - Plugin Loader for Tools ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A tool can #include this file to get a -load option that allows the user to
+// load arbitrary shared objects into the tool's address space. Note that this
+// header can only be included by a program ONCE, so it should never to used by
+// library authors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PLUGINLOADER_H
+#define LLVM_SUPPORT_PLUGINLOADER_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+ struct PluginLoader {
+ void operator=(const std::string &Filename);
+ static unsigned getNumPlugins();
+ static std::string& getPlugin(unsigned num);
+ };
+
+#ifndef DONT_GET_PLUGIN_LOADER_OPTION
+ // This causes operator= above to be invoked for every -load option.
+ static cl::opt<PluginLoader, false, cl::parser<std::string> >
+ LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"),
+ cl::desc("Load the specified plugin"));
+#endif
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h
new file mode 100644
index 000000000000..837082139214
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PointerLikeTypeTraits.h
@@ -0,0 +1,81 @@
+//===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- 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 PointerLikeTypeTraits class. This allows data
+// structures to reason about pointers and other things that are pointer sized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
+#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// PointerLikeTypeTraits - This is a traits object that is used to handle
+/// pointer types and things that are just wrappers for pointers as a uniform
+/// entity.
+template <typename T>
+class PointerLikeTypeTraits {
+ // getAsVoidPointer
+ // getFromVoidPointer
+ // getNumLowBitsAvailable
+};
+
+// Provide PointerLikeTypeTraits for non-cvr pointers.
+template<typename T>
+class PointerLikeTypeTraits<T*> {
+public:
+ static inline void *getAsVoidPointer(T* P) { return P; }
+ static inline T *getFromVoidPointer(void *P) {
+ return static_cast<T*>(P);
+ }
+
+ /// Note, we assume here that malloc returns objects at least 4-byte aligned.
+ /// However, this may be wrong, or pointers may be from something other than
+ /// malloc. In this case, you should specialize this template to reduce this.
+ ///
+ /// All clients should use assertions to do a run-time check to ensure that
+ /// this is actually true.
+ enum { NumLowBitsAvailable = 2 };
+};
+
+// Provide PointerLikeTypeTraits for const pointers.
+template<typename T>
+class PointerLikeTypeTraits<const T*> {
+ typedef PointerLikeTypeTraits<T*> NonConst;
+
+public:
+ static inline const void *getAsVoidPointer(const T* P) {
+ return NonConst::getAsVoidPointer(const_cast<T*>(P));
+ }
+ static inline const T *getFromVoidPointer(const void *P) {
+ return NonConst::getFromVoidPointer(const_cast<void*>(P));
+ }
+ enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+};
+
+// Provide PointerLikeTypeTraits for uintptr_t.
+template<>
+class PointerLikeTypeTraits<uintptr_t> {
+public:
+ static inline void *getAsVoidPointer(uintptr_t P) {
+ return reinterpret_cast<void*>(P);
+ }
+ static inline uintptr_t getFromVoidPointer(void *P) {
+ return reinterpret_cast<uintptr_t>(P);
+ }
+ // No bits are available!
+ enum { NumLowBitsAvailable = 0 };
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/PredIteratorCache.h b/contrib/llvm/include/llvm/Support/PredIteratorCache.h
new file mode 100644
index 000000000000..bb66a8ed58b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PredIteratorCache.h
@@ -0,0 +1,70 @@
+//===- llvm/Support/PredIteratorCache.h - pred_iterator Cache ---*- 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 PredIteratorCache class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H
+#define LLVM_SUPPORT_PREDITERATORCACHE_H
+
+namespace llvm {
+
+ /// PredIteratorCache - This class is an extremely trivial cache for
+ /// predecessor iterator queries. This is useful for code that repeatedly
+ /// wants the predecessor list for the same blocks.
+ class PredIteratorCache {
+ /// BlockToPredsMap - Pointer to null-terminated list.
+ DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap;
+ DenseMap<BasicBlock*, unsigned> BlockToPredCountMap;
+
+ /// Memory - This is the space that holds cached preds.
+ BumpPtrAllocator Memory;
+ public:
+
+ /// GetPreds - Get a cached list for the null-terminated predecessor list of
+ /// the specified block. This can be used in a loop like this:
+ /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI)
+ /// use(*PI);
+ /// instead of:
+ /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
+ BasicBlock **GetPreds(BasicBlock *BB) {
+ BasicBlock **&Entry = BlockToPredsMap[BB];
+ if (Entry) return Entry;
+
+ SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB));
+ PredCache.push_back(0); // null terminator.
+
+ BlockToPredCountMap[BB] = PredCache.size()-1;
+
+ Entry = Memory.Allocate<BasicBlock*>(PredCache.size());
+ std::copy(PredCache.begin(), PredCache.end(), Entry);
+ return Entry;
+ }
+
+ unsigned GetNumPreds(BasicBlock *BB) {
+ GetPreds(BB);
+ return BlockToPredCountMap[BB];
+ }
+
+ /// clear - Remove all information.
+ void clear() {
+ BlockToPredsMap.clear();
+ BlockToPredCountMap.clear();
+ Memory.Reset();
+ }
+ };
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/PrettyStackTrace.h b/contrib/llvm/include/llvm/Support/PrettyStackTrace.h
new file mode 100644
index 000000000000..9b3ecda50c1e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/PrettyStackTrace.h
@@ -0,0 +1,71 @@
+//===- llvm/Support/PrettyStackTrace.h - Pretty Crash Handling --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PrettyStackTraceEntry class, which is used to make
+// crashes give more contextual information about what the program was doing
+// when it crashed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PRETTYSTACKTRACE_H
+#define LLVM_SUPPORT_PRETTYSTACKTRACE_H
+
+namespace llvm {
+ class raw_ostream;
+
+ /// DisablePrettyStackTrace - Set this to true to disable this module. This
+ /// might be necessary if the host application installs its own signal
+ /// handlers which conflict with the ones installed by this module.
+ /// Defaults to false.
+ extern bool DisablePrettyStackTrace;
+
+ /// PrettyStackTraceEntry - This class is used to represent a frame of the
+ /// "pretty" stack trace that is dumped when a program crashes. You can define
+ /// subclasses of this and declare them on the program stack: when they are
+ /// constructed and destructed, they will add their symbolic frames to a
+ /// 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
+ public:
+ PrettyStackTraceEntry();
+ virtual ~PrettyStackTraceEntry();
+
+ /// print - Emit information about this stack frame to OS.
+ virtual void print(raw_ostream &OS) const = 0;
+
+ /// getNextEntry - Return the next entry in the list of frames.
+ const PrettyStackTraceEntry *getNextEntry() const { return NextEntry; }
+ };
+
+ /// PrettyStackTraceString - This object prints a specified string (which
+ /// should not contain newlines) to the stream as the stack trace when a crash
+ /// occurs.
+ class PrettyStackTraceString : public PrettyStackTraceEntry {
+ const char *Str;
+ public:
+ PrettyStackTraceString(const char *str) : Str(str) {}
+ virtual void print(raw_ostream &OS) const;
+ };
+
+ /// PrettyStackTraceProgram - This object prints a specified program arguments
+ /// to the stream as the stack trace when a crash occurs.
+ class PrettyStackTraceProgram : public PrettyStackTraceEntry {
+ int ArgC;
+ const char *const *ArgV;
+ public:
+ PrettyStackTraceProgram(int argc, const char * const*argv)
+ : ArgC(argc), ArgV(argv) {}
+ virtual void print(raw_ostream &OS) const;
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Process.h b/contrib/llvm/include/llvm/Support/Process.h
new file mode 100644
index 000000000000..d796b7906d37
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Process.h
@@ -0,0 +1,150 @@
+//===- llvm/Support/Process.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 declares the llvm::sys::Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROCESS_H
+#define LLVM_SYSTEM_PROCESS_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 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();
+ /// @}
+ };
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Program.h b/contrib/llvm/include/llvm/Support/Program.h
new file mode 100644
index 000000000000..a85f23550ec8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Program.h
@@ -0,0 +1,159 @@
+//===- llvm/Support/Program.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 declares the llvm::sys::Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROGRAM_H
+#define LLVM_SYSTEM_PROGRAM_H
+
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+class error_code;
+namespace sys {
+
+ // TODO: Add operations to communicate with the process, redirect its I/O,
+ // etc.
+
+ /// This class provides an abstraction for programs that are executable by the
+ /// operating system. It provides a platform generic way to find executable
+ /// programs from the path and to execute them in various ways. The sys::Path
+ /// class is used to specify the location of the Program.
+ /// @since 1.4
+ /// @brief An abstraction for finding and executing programs.
+ class Program {
+ /// Opaque handle for target specific data.
+ void *Data_;
+
+ // Noncopyable.
+ Program(const Program& other);
+ Program& operator=(const Program& other);
+
+ /// @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
+ /// invoking program. If Path::executable() does not return true when this
+ /// function is called then a std::string is thrown.
+ /// @returns false in case of error, true otherwise.
+ /// @see FindProgramByName
+ /// @brief Executes the program with the given set of \p args.
+ bool Execute
+ ( const Path& path, ///< sys::Path object providing the path of the
+ ///< program to be executed. It is presumed this is the result of
+ ///< the FindProgramByName method.
+ const char** args, ///< A vector of strings that are passed to the
+ ///< program. The first element should be the name of the program.
+ ///< The list *must* be terminated by a null char* entry.
+ const char ** env = 0, ///< An optional vector of strings to use for
+ ///< the program's environment. If not provided, the current program's
+ ///< environment will be used.
+ const sys::Path** redirects = 0, ///< An optional array of pointers to
+ ///< Paths. If the array is null, no redirection is done. The array
+ ///< should have a size of at least three. If the pointer in the array
+ ///< are not null, then the inferior process's stdin(0), stdout(1),
+ ///< and stderr(2) will be redirected to the corresponding Paths.
+ ///< When an empty Path is passed in, the corresponding file
+ ///< descriptor will be disconnected (ie, /dev/null'd) in a portable
+ ///< way.
+ unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
+ ///< of memory can be allocated by process. If memory usage will be
+ ///< higher limit, the child is killed and this call returns. If zero
+ ///< - no memory limit.
+ 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 invoking the
+ ///< program.
+ );
+
+ /// This function waits for the program to exit. This function will block
+ /// the current program until the invoked program exits.
+ /// @returns an integer result code indicating the status of the program.
+ /// A zero or positive value indicates the result code of the program.
+ /// -1 indicates failure to execute
+ /// -2 indicates a crash during execution or timeout
+ /// @see Execute
+ /// @brief Waits for the program to exit.
+ int Wait
+ ( const Path& path, ///< The path to the child process executable.
+ unsigned secondsToWait, ///< If non-zero, this specifies the amount
+ ///< of time to wait for the child process to exit. If the time
+ ///< expires, the child is killed and this call returns. If zero,
+ ///< this function will wait until the child finishes or forever if
+ ///< it doesn't.
+ std::string* ErrMsg ///< 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 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.
+ );
+
+ /// 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
+ /// returned unmodified.
+ /// @returns A Path object initialized to the path of the program or a
+ /// Path object that is empty (invalid) if the program could not be found.
+ /// @brief Construct a Program by finding it by name.
+ static Path FindProgramByName(const std::string& name);
+
+ // These methods change the specified standard stream (stdin, stdout, or
+ // stderr) to binary mode. They return errc::success if the specified stream
+ // was changed. Otherwise a platform dependent error is returned.
+ static error_code ChangeStdinToBinary();
+ static error_code ChangeStdoutToBinary();
+ static error_code ChangeStderrToBinary();
+
+ /// A convenience function equivalent to Program prg; prg.Execute(..);
+ /// prg.Wait(..);
+ /// @see Execute, Wait
+ static int ExecuteAndWait(const Path& path,
+ const char** args,
+ const char ** env = 0,
+ const sys::Path** redirects = 0,
+ unsigned secondsToWait = 0,
+ unsigned memoryLimit = 0,
+ std::string* ErrMsg = 0);
+
+ /// A convenience function equivalent to Program prg; prg.Execute(..);
+ /// @see Execute
+ static void ExecuteNoWait(const Path& path,
+ const char** args,
+ const char ** env = 0,
+ const sys::Path** redirects = 0,
+ unsigned memoryLimit = 0,
+ std::string* ErrMsg = 0);
+
+ /// @}
+
+ };
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/RWMutex.h b/contrib/llvm/include/llvm/Support/RWMutex.h
new file mode 100644
index 000000000000..0d4cb81de397
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/RWMutex.h
@@ -0,0 +1,173 @@
+//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::RWMutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_RWMUTEX_H
+#define LLVM_SYSTEM_RWMUTEX_H
+
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic RWMutex class.
+ class RWMutexImpl
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it.
+ /// @brief Default Constructor.
+ explicit RWMutexImpl();
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~RWMutexImpl();
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock in reader mode. If the
+ /// lock is held by a writer, this method will wait until it can acquire
+ /// the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock in reader mode.
+ bool reader_acquire();
+
+ /// Attempts to release the lock in reader mode.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock in reader mode.
+ bool reader_release();
+
+ /// Attempts to unconditionally acquire the lock in reader mode. If the
+ /// lock is held by any readers, this method will wait until it can
+ /// acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock in writer mode.
+ bool writer_acquire();
+
+ /// Attempts to release the lock in writer mode.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock in write mode.
+ bool writer_release();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+ void* data_; ///< We don't know what the data will be
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ RWMutexImpl(const RWMutexImpl & original);
+ void operator=(const RWMutexImpl &);
+ /// @}
+ };
+
+ /// SmartMutex - An R/W mutex with a compile time constant parameter that
+ /// indicates whether this mutex should become a no-op when we're not
+ /// running in multithreaded mode.
+ template<bool mt_only>
+ class SmartRWMutex : public RWMutexImpl {
+ unsigned readers, writers;
+ public:
+ explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
+
+ bool reader_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ ++readers;
+ return true;
+ }
+
+ bool reader_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(readers > 0 && "Reader lock not acquired before release!");
+ --readers;
+ return true;
+ }
+
+ bool writer_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 0 && "Writer lock already acquired!");
+ ++writers;
+ return true;
+ }
+
+ bool writer_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 1 && "Writer lock not acquired before release!");
+ --writers;
+ return true;
+ }
+
+ private:
+ SmartRWMutex(const SmartRWMutex<mt_only> & original);
+ void operator=(const SmartRWMutex<mt_only> &);
+ };
+ typedef SmartRWMutex<false> RWMutex;
+
+ /// ScopedReader - RAII acquisition of a reader lock
+ template<bool mt_only>
+ struct SmartScopedReader {
+ SmartRWMutex<mt_only>& mutex;
+
+ explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.reader_acquire();
+ }
+
+ ~SmartScopedReader() {
+ mutex.reader_release();
+ }
+ };
+ typedef SmartScopedReader<false> ScopedReader;
+
+ /// ScopedWriter - RAII acquisition of a writer lock
+ template<bool mt_only>
+ struct SmartScopedWriter {
+ SmartRWMutex<mt_only>& mutex;
+
+ explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.writer_acquire();
+ }
+
+ ~SmartScopedWriter() {
+ mutex.writer_release();
+ }
+ };
+ typedef SmartScopedWriter<false> ScopedWriter;
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Recycler.h b/contrib/llvm/include/llvm/Support/Recycler.h
new file mode 100644
index 000000000000..fa6e189e97bd
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Recycler.h
@@ -0,0 +1,118 @@
+//==- llvm/Support/Recycler.h - Recycling Allocator --------------*- 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 Recycler class template. See the doxygen comment for
+// Recycler for more details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RECYCLER_H
+#define LLVM_SUPPORT_RECYCLER_H
+
+#include "llvm/ADT/ilist.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+
+namespace llvm {
+
+/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
+/// printing statistics.
+///
+void PrintRecyclerStats(size_t Size, size_t Align, size_t FreeListSize);
+
+/// RecyclerStruct - Implementation detail for Recycler. This is a
+/// class that the recycler imposes on free'd memory to carve out
+/// next/prev pointers.
+struct RecyclerStruct {
+ RecyclerStruct *Prev, *Next;
+};
+
+template<>
+struct ilist_traits<RecyclerStruct> :
+ public ilist_default_traits<RecyclerStruct> {
+ static RecyclerStruct *getPrev(const RecyclerStruct *t) { return t->Prev; }
+ static RecyclerStruct *getNext(const RecyclerStruct *t) { return t->Next; }
+ static void setPrev(RecyclerStruct *t, RecyclerStruct *p) { t->Prev = p; }
+ static void setNext(RecyclerStruct *t, RecyclerStruct *n) { t->Next = n; }
+
+ mutable RecyclerStruct Sentinel;
+ RecyclerStruct *createSentinel() const {
+ return &Sentinel;
+ }
+ static void destroySentinel(RecyclerStruct *) {}
+
+ RecyclerStruct *provideInitialHead() const { return createSentinel(); }
+ RecyclerStruct *ensureHead(RecyclerStruct*) const { return createSentinel(); }
+ static void noteHead(RecyclerStruct*, RecyclerStruct*) {}
+
+ static void deleteNode(RecyclerStruct *) {
+ llvm_unreachable("Recycler's ilist_traits shouldn't see a deleteNode call!");
+ }
+};
+
+/// Recycler - This class manages a linked-list of deallocated nodes
+/// and facilitates reusing deallocated memory in place of allocating
+/// new memory.
+///
+template<class T, size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
+class Recycler {
+ /// FreeList - Doubly-linked list of nodes that have deleted contents and
+ /// are not in active use.
+ ///
+ iplist<RecyclerStruct> FreeList;
+
+public:
+ ~Recycler() {
+ // If this fails, either the callee has lost track of some allocation,
+ // or the callee isn't tracking allocations and should just call
+ // clear() before deleting the Recycler.
+ assert(FreeList.empty() && "Non-empty recycler deleted!");
+ }
+
+ /// clear - Release all the tracked allocations to the allocator. The
+ /// recycler must be free of any tracked allocations before being
+ /// deleted; calling clear is one way to ensure this.
+ template<class AllocatorType>
+ void clear(AllocatorType &Allocator) {
+ while (!FreeList.empty()) {
+ T *t = reinterpret_cast<T *>(FreeList.remove(FreeList.begin()));
+ Allocator.Deallocate(t);
+ }
+ }
+
+ template<class SubClass, class AllocatorType>
+ SubClass *Allocate(AllocatorType &Allocator) {
+ assert(sizeof(SubClass) <= Size &&
+ "Recycler allocation size is less than object size!");
+ assert(AlignOf<SubClass>::Alignment <= Align &&
+ "Recycler allocation alignment is less than object alignment!");
+ return !FreeList.empty() ?
+ reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
+ static_cast<SubClass *>(Allocator.Allocate(Size, Align));
+ }
+
+ template<class AllocatorType>
+ T *Allocate(AllocatorType &Allocator) {
+ return Allocate<T>(Allocator);
+ }
+
+ template<class SubClass, class AllocatorType>
+ void Deallocate(AllocatorType & /*Allocator*/, SubClass* Element) {
+ FreeList.push_front(reinterpret_cast<RecyclerStruct *>(Element));
+ }
+
+ void PrintStats() {
+ PrintRecyclerStats(Size, Align, FreeList.size());
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/RecyclingAllocator.h b/contrib/llvm/include/llvm/Support/RecyclingAllocator.h
new file mode 100644
index 000000000000..34ab874778c9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/RecyclingAllocator.h
@@ -0,0 +1,73 @@
+//==- llvm/Support/RecyclingAllocator.h - Recycling Allocator ----*- 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 RecyclingAllocator class. See the doxygen comment for
+// RecyclingAllocator for more details on the implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RECYCLINGALLOCATOR_H
+#define LLVM_SUPPORT_RECYCLINGALLOCATOR_H
+
+#include "llvm/Support/Recycler.h"
+
+namespace llvm {
+
+/// RecyclingAllocator - This class wraps an Allocator, adding the
+/// functionality of recycling deleted objects.
+///
+template<class AllocatorType, class T,
+ size_t Size = sizeof(T), size_t Align = AlignOf<T>::Alignment>
+class RecyclingAllocator {
+private:
+ /// Base - Implementation details.
+ ///
+ Recycler<T, Size, Align> Base;
+
+ /// Allocator - The wrapped allocator.
+ ///
+ AllocatorType Allocator;
+
+public:
+ ~RecyclingAllocator() { Base.clear(Allocator); }
+
+ /// Allocate - Return a pointer to storage for an object of type
+ /// SubClass. The storage may be either newly allocated or recycled.
+ ///
+ template<class SubClass>
+ SubClass *Allocate() { return Base.template Allocate<SubClass>(Allocator); }
+
+ T *Allocate() { return Base.Allocate(Allocator); }
+
+ /// Deallocate - Release storage for the pointed-to object. The
+ /// storage will be kept track of and may be recycled.
+ ///
+ template<class SubClass>
+ void Deallocate(SubClass* E) { return Base.Deallocate(Allocator, E); }
+
+ void PrintStats() { Base.PrintStats(); }
+};
+
+}
+
+template<class AllocatorType, class T, size_t Size, size_t Align>
+inline void *operator new(size_t,
+ llvm::RecyclingAllocator<AllocatorType,
+ T, Size, Align> &Allocator) {
+ return Allocator.Allocate();
+}
+
+template<class AllocatorType, class T, size_t Size, size_t Align>
+inline void operator delete(void *E,
+ llvm::RecyclingAllocator<AllocatorType,
+ T, Size, Align> &A) {
+ A.Deallocate(E);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Regex.h b/contrib/llvm/include/llvm/Support/Regex.h
new file mode 100644
index 000000000000..7648e77bfbb5
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Regex.h
@@ -0,0 +1,81 @@
+//===-- Regex.h - Regular Expression matcher implementation -*- 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 POSIX regular expression matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGEX_H
+#define LLVM_SUPPORT_REGEX_H
+
+#include <string>
+
+struct llvm_regex;
+
+namespace llvm {
+ class StringRef;
+ template<typename T> class SmallVectorImpl;
+
+ class Regex {
+ public:
+ enum {
+ NoFlags=0,
+ /// Compile for matching that ignores upper/lower case distinctions.
+ IgnoreCase=1,
+ /// Compile for newline-sensitive matching. With this flag '[^' bracket
+ /// expressions and '.' never match newline. A ^ anchor matches the
+ /// 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
+ };
+
+ /// Compiles the given POSIX Extended Regular Expression \arg Regex.
+ /// This implementation supports regexes and matching strings with embedded
+ /// NUL characters.
+ Regex(StringRef Regex, unsigned Flags = NoFlags);
+ ~Regex();
+
+ /// isValid - returns the error encountered during regex compilation, or
+ /// matching, if any.
+ bool isValid(std::string &Error);
+
+ /// getNumMatches - In a valid regex, return the number of parenthesized
+ /// matches it contains. The number filled in by match will include this
+ /// many entries plus one for the whole regex (as element 0).
+ unsigned getNumMatches() const;
+
+ /// matches - Match the regex against a given \arg String.
+ ///
+ /// \param Matches - If given, on a successful match this will be filled in
+ /// with references to the matched group expressions (inside \arg 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
+ /// replacement string are replaced with the appropriate match substring.
+ ///
+ /// Note that the replacement string has backslash escaping performed on
+ /// it. Invalid backreferences are ignored (replaced by empty strings).
+ ///
+ /// \param Error If non-null, any errors in the substitution (invalid
+ /// backreferences, trailing backslashes) will be recorded as a non-empty
+ /// string.
+ std::string sub(StringRef Repl, StringRef String, std::string *Error = 0);
+
+ private:
+ struct llvm_regex *preg;
+ int error;
+ };
+}
+
+#endif // LLVM_SUPPORT_REGEX_H
diff --git a/contrib/llvm/include/llvm/Support/Registry.h b/contrib/llvm/include/llvm/Support/Registry.h
new file mode 100644
index 000000000000..d0375bedd9f2
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Registry.h
@@ -0,0 +1,223 @@
+//=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a registry template for discovering pluggable modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_H
+#define LLVM_SUPPORT_REGISTRY_H
+
+namespace llvm {
+ /// A simple registry entry which provides only a name, description, and
+ /// no-argument constructor.
+ template <typename T>
+ class SimpleRegistryEntry {
+ const char *Name, *Desc;
+ T *(*Ctor)();
+
+ public:
+ SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
+ : Name(N), Desc(D), Ctor(C)
+ {}
+
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+ T *instantiate() const { return Ctor(); }
+ };
+
+
+ /// Traits for registry entries. If using other than SimpleRegistryEntry, it
+ /// is necessary to define an alternate traits class.
+ template <typename T>
+ class RegistryTraits {
+ RegistryTraits(); // Do not implement.
+
+ public:
+ typedef SimpleRegistryEntry<T> entry;
+
+ /// nameof/descof - Accessors for name and description of entries. These are
+ // used to generate help for command-line options.
+ static const char *nameof(const entry &Entry) { return Entry.getName(); }
+ static const char *descof(const entry &Entry) { return Entry.getDesc(); }
+ };
+
+
+ /// A global registry used in conjunction with static constructors to make
+ /// pluggable components (like targets or garbage collectors) "just work" when
+ /// linked with an executable.
+ template <typename T, typename U = RegistryTraits<T> >
+ class Registry {
+ public:
+ typedef U traits;
+ typedef typename U::entry entry;
+
+ class node;
+ class listener;
+ class iterator;
+
+ private:
+ Registry(); // Do not implement.
+
+ static void Announce(const entry &E) {
+ for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
+ Cur->registered(E);
+ }
+
+ friend class node;
+ static node *Head, *Tail;
+
+ friend class listener;
+ static listener *ListenerHead, *ListenerTail;
+
+ public:
+ /// Node in linked list of entries.
+ ///
+ class node {
+ friend class iterator;
+
+ node *Next;
+ const entry& Val;
+
+ public:
+ node(const entry& V) : Next(0), Val(V) {
+ if (Tail)
+ Tail->Next = this;
+ else
+ Head = this;
+ Tail = this;
+
+ Announce(V);
+ }
+ };
+
+
+ /// Iterators for registry entries.
+ ///
+ class iterator {
+ const node *Cur;
+
+ public:
+ explicit iterator(const node *N) : Cur(N) {}
+
+ bool operator==(const iterator &That) const { return Cur == That.Cur; }
+ bool operator!=(const iterator &That) const { return Cur != That.Cur; }
+ iterator &operator++() { Cur = Cur->Next; return *this; }
+ const entry &operator*() const { return Cur->Val; }
+ const entry *operator->() const { return &Cur->Val; }
+ };
+
+ static iterator begin() { return iterator(Head); }
+ static iterator end() { return iterator(0); }
+
+
+ /// Abstract base class for registry listeners, which are informed when new
+ /// entries are added to the registry. Simply subclass and instantiate:
+ ///
+ /// class CollectorPrinter : public Registry<Collector>::listener {
+ /// protected:
+ /// void registered(const Registry<Collector>::entry &e) {
+ /// cerr << "collector now available: " << e->getName() << "\n";
+ /// }
+ ///
+ /// public:
+ /// CollectorPrinter() { init(); } // Print those already registered.
+ /// };
+ ///
+ /// CollectorPrinter Printer;
+ ///
+ class listener {
+ listener *Prev, *Next;
+
+ friend void Registry::Announce(const entry &E);
+
+ protected:
+ /// Called when an entry is added to the registry.
+ ///
+ virtual void registered(const entry &) = 0;
+
+ /// Calls 'registered' for each pre-existing entry.
+ ///
+ void init() {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ registered(*I);
+ }
+
+ public:
+ listener() : Prev(ListenerTail), Next(0) {
+ if (Prev)
+ Prev->Next = this;
+ else
+ ListenerHead = this;
+ ListenerTail = this;
+ }
+
+ virtual ~listener() {
+ if (Next)
+ Next->Prev = Prev;
+ else
+ ListenerTail = Prev;
+ if (Prev)
+ Prev->Next = Next;
+ else
+ ListenerHead = Next;
+ }
+ };
+
+
+ /// A static registration template. Use like such:
+ ///
+ /// Registry<Collector>::Add<FancyGC>
+ /// X("fancy-gc", "Newfangled garbage collector.");
+ ///
+ /// Use of this template requires that:
+ ///
+ /// 1. The registered subclass has a default constructor.
+ //
+ /// 2. The registry entry type has a constructor compatible with this
+ /// signature:
+ ///
+ /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
+ ///
+ /// If you have more elaborate requirements, then copy and modify.
+ ///
+ template <typename V>
+ class Add {
+ entry Entry;
+ node Node;
+
+ static T *CtorFn() { return new V(); }
+
+ public:
+ Add(const char *Name, const char *Desc)
+ : Entry(Name, Desc, CtorFn), Node(Entry) {}
+ };
+
+ /// Registry::Parser now lives in llvm/Support/RegistryParser.h.
+
+ };
+
+ // Since these are defined in a header file, plugins must be sure to export
+ // these symbols.
+
+ template <typename T, typename U>
+ typename Registry<T,U>::node *Registry<T,U>::Head;
+
+ template <typename T, typename U>
+ typename Registry<T,U>::node *Registry<T,U>::Tail;
+
+ template <typename T, typename U>
+ typename Registry<T,U>::listener *Registry<T,U>::ListenerHead;
+
+ template <typename T, typename U>
+ typename Registry<T,U>::listener *Registry<T,U>::ListenerTail;
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/RegistryParser.h b/contrib/llvm/include/llvm/Support/RegistryParser.h
new file mode 100644
index 000000000000..2cc578370fef
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/RegistryParser.h
@@ -0,0 +1,55 @@
+//=== RegistryParser.h - Linker-supported plugin registries -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a command-line parser for a registry.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_REGISTRY_PARSER_H
+#define LLVM_SUPPORT_REGISTRY_PARSER_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Registry.h"
+
+namespace llvm {
+
+ /// A command-line parser for a registry. Use like such:
+ ///
+ /// static cl::opt<Registry<Collector>::entry, false,
+ /// RegistryParser<Collector> >
+ /// GCOpt("gc", cl::desc("Garbage collector to use."),
+ /// cl::value_desc());
+ ///
+ /// To make use of the value:
+ ///
+ /// Collector *TheCollector = GCOpt->instantiate();
+ ///
+ template <typename T, typename U = RegistryTraits<T> >
+ class RegistryParser :
+ public cl::parser<const typename U::entry*>,
+ public Registry<T, U>::listener {
+ typedef U traits;
+ typedef typename U::entry entry;
+ typedef typename Registry<T, U>::listener listener;
+
+ protected:
+ void registered(const entry &E) {
+ addLiteralOption(traits::nameof(E), &E, traits::descof(E));
+ }
+
+ public:
+ void initialize(cl::Option &O) {
+ listener::init();
+ cl::parser<const typename U::entry*>::initialize(O);
+ }
+ };
+
+}
+
+#endif // LLVM_SUPPORT_REGISTRY_PARSER_H
diff --git a/contrib/llvm/include/llvm/Support/SMLoc.h b/contrib/llvm/include/llvm/Support/SMLoc.h
new file mode 100644
index 000000000000..d48bfcc30c5b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/SMLoc.h
@@ -0,0 +1,62 @@
+//===- SMLoc.h - Source location for use with diagnostics -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SMLoc class. This class encapsulates a location in
+// source code for use in diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_SMLOC_H
+#define SUPPORT_SMLOC_H
+
+#include <cassert>
+
+namespace llvm {
+
+/// SMLoc - Represents a location in source code.
+class SMLoc {
+ const char *Ptr;
+public:
+ SMLoc() : Ptr(0) {}
+ SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
+
+ bool isValid() const { return Ptr != 0; }
+
+ bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
+ bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
+
+ const char *getPointer() const { return Ptr; }
+
+ static SMLoc getFromPointer(const char *Ptr) {
+ SMLoc L;
+ L.Ptr = Ptr;
+ return L;
+ }
+};
+
+/// 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.
+class SMRange {
+public:
+ SMLoc Start, End;
+
+ SMRange() {}
+ SMRange(SMLoc Start, SMLoc End) : Start(Start), End(End) {
+ assert(Start.isValid() == End.isValid() &&
+ "Start and end should either both be valid or both be invalid!");
+ }
+
+ bool isValid() const { return Start.isValid(); }
+};
+
+} // end namespace llvm
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Support/SaveAndRestore.h b/contrib/llvm/include/llvm/Support/SaveAndRestore.h
new file mode 100644
index 000000000000..ffa99b968d3c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/SaveAndRestore.h
@@ -0,0 +1,47 @@
+//===-- SaveAndRestore.h - Utility -------------------------------*- 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 utility classes that uses RAII to save and restore
+// values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SAVERESTORE
+#define LLVM_ADT_SAVERESTORE
+
+namespace llvm {
+
+// SaveAndRestore - A utility class that uses RAII to save and restore
+// the value of a variable.
+template<typename T>
+struct SaveAndRestore {
+ SaveAndRestore(T& x) : X(x), old_value(x) {}
+ SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
+ X = new_value;
+ }
+ ~SaveAndRestore() { X = old_value; }
+ T get() { return old_value; }
+private:
+ T& X;
+ T old_value;
+};
+
+// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
+// value of a variable is saved, and during the dstor the old value is
+// or'ed with the new value.
+struct SaveOr {
+ SaveOr(bool& x) : X(x), old_value(x) { x = false; }
+ ~SaveOr() { X |= old_value; }
+private:
+ bool& X;
+ const bool old_value;
+};
+
+}
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Signals.h b/contrib/llvm/include/llvm/Support/Signals.h
new file mode 100644
index 000000000000..634f4cf76dc0
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Signals.h
@@ -0,0 +1,59 @@
+//===- llvm/Support/Signals.h - Signal Handling support ----------*- 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 some helpful functions for dealing with the possibility of
+// unix signals occurring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SIGNALS_H
+#define LLVM_SYSTEM_SIGNALS_H
+
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This function runs all the registered interrupt handlers, including the
+ /// removal of files registered by RemoveFileOnSignal.
+ void RunInterruptHandlers();
+
+ /// This function registers signal handlers to ensure that if a signal gets
+ /// delivered that the named file is removed.
+ /// @brief Remove a file if a fatal signal occurs.
+ bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
+
+ /// This function removes a file from the list of files to be removed on
+ /// signal delivery.
+ void DontRemoveFileOnSignal(const Path &Filename);
+
+ /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
+ /// process, print a stack trace and then exit.
+ /// @brief Print a stack trace if a fatal signal occurs.
+ void PrintStackTraceOnErrorSignal();
+
+ /// AddSignalHandler - Add a function to be called when an abort/kill signal
+ /// is delivered to the process. The handler can have a cookie passed to it
+ /// to identify what instance of the handler it is.
+ void AddSignalHandler(void (*FnPtr)(void *), void *Cookie);
+
+ /// This function registers a function to be called when the user "interrupts"
+ /// the program (typically by pressing ctrl-c). When the user interrupts the
+ /// program, the specified interrupt function is called instead of the program
+ /// being killed, and the interrupt function automatically disabled. Note
+ /// that interrupt functions are not allowed to call any non-reentrant
+ /// functions. An null interrupt function pointer disables the current
+ /// installed function. Note also that the handler may be executed on a
+ /// different thread on some platforms.
+ /// @brief Register a function to be called when ctrl-c is pressed.
+ void SetInterruptFunction(void (*IF)());
+} // End sys namespace
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Solaris.h b/contrib/llvm/include/llvm/Support/Solaris.h
new file mode 100644
index 000000000000..57eee2cb4973
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Solaris.h
@@ -0,0 +1,40 @@
+/*===- llvm/Support/Solaris.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 portability fixes for Solaris hosts.
+ *
+ *===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_SYSTEM_SOLARIS_H
+#define LLVM_SYSTEM_SOLARIS_H
+
+#include <sys/types.h>
+#include <sys/regset.h>
+
+#undef CS
+#undef DS
+#undef ES
+#undef FS
+#undef GS
+#undef SS
+#undef EAX
+#undef ECX
+#undef EDX
+#undef EBX
+#undef ESP
+#undef EBP
+#undef ESI
+#undef EDI
+#undef EIP
+#undef UESP
+#undef EFL
+#undef ERR
+#undef TRAPNO
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/SourceMgr.h b/contrib/llvm/include/llvm/Support/SourceMgr.h
new file mode 100644
index 000000000000..76967dbf78aa
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/SourceMgr.h
@@ -0,0 +1,199 @@
+//===- SourceMgr.h - Manager for Source Buffers & Diagnostics ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SMDiagnostic and SourceMgr classes. This
+// provides a simple substrate for diagnostics, #include handling, and other low
+// level things for simple parsers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_SOURCEMGR_H
+#define SUPPORT_SOURCEMGR_H
+
+#include "llvm/Support/SMLoc.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <string>
+
+namespace llvm {
+ class MemoryBuffer;
+ class SourceMgr;
+ class SMDiagnostic;
+ class Twine;
+ class raw_ostream;
+
+/// SourceMgr - This owns the files read by a parser, handles include stacks,
+/// and handles diagnostic wrangling.
+class SourceMgr {
+public:
+ enum DiagKind {
+ DK_Error,
+ DK_Warning,
+ DK_Note
+ };
+
+ /// DiagHandlerTy - Clients that want to handle their own diagnostics in a
+ /// custom way can register a function pointer+context as a diagnostic
+ /// handler. It gets called each time PrintMessage is invoked.
+ typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
+private:
+ struct SrcBuffer {
+ /// Buffer - The memory buffer for the file.
+ MemoryBuffer *Buffer;
+
+ /// IncludeLoc - This is the location of the parent include, or null if at
+ /// the top level.
+ SMLoc IncludeLoc;
+ };
+
+ /// Buffers - This is all of the buffers that we are reading from.
+ std::vector<SrcBuffer> Buffers;
+
+ // IncludeDirectories - This is the list of directories we should search for
+ // include files in.
+ std::vector<std::string> IncludeDirectories;
+
+ /// LineNoCache - This is a cache for line number queries, its implementation
+ /// is really private to SourceMgr.cpp.
+ mutable void *LineNoCache;
+
+ DiagHandlerTy DiagHandler;
+ void *DiagContext;
+
+ SourceMgr(const SourceMgr&); // DO NOT IMPLEMENT
+ void operator=(const SourceMgr&); // DO NOT IMPLEMENT
+public:
+ SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {}
+ ~SourceMgr();
+
+ void setIncludeDirs(const std::vector<std::string> &Dirs) {
+ IncludeDirectories = Dirs;
+ }
+
+ /// setDiagHandler - Specify a diagnostic handler to be invoked every time
+ /// PrintMessage is called. Ctx is passed into the handler when it is invoked.
+ void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0) {
+ DiagHandler = DH;
+ DiagContext = Ctx;
+ }
+
+ DiagHandlerTy getDiagHandler() const { return DiagHandler; }
+ void *getDiagContext() const { return DiagContext; }
+
+ const SrcBuffer &getBufferInfo(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i];
+ }
+
+ const MemoryBuffer *getMemoryBuffer(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i].Buffer;
+ }
+
+ SMLoc getParentIncludeLoc(unsigned i) const {
+ assert(i < Buffers.size() && "Invalid Buffer ID!");
+ return Buffers[i].IncludeLoc;
+ }
+
+ /// AddNewSourceBuffer - Add a new source buffer to this source manager. This
+ /// takes ownership of the memory buffer.
+ unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) {
+ SrcBuffer NB;
+ NB.Buffer = F;
+ NB.IncludeLoc = IncludeLoc;
+ Buffers.push_back(NB);
+ return Buffers.size()-1;
+ }
+
+ /// AddIncludeFile - Search for a file with the specified name in the current
+ /// directory or in one of the IncludeDirs. If no file is found, this returns
+ /// ~0, otherwise it returns the buffer ID of the stacked file.
+ /// The full path to the included file can be found in IncludedFile.
+ unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc,
+ std::string &IncludedFile);
+
+ /// FindBufferContainingLoc - Return the ID of the buffer containing the
+ /// specified location, returning -1 if not found.
+ int FindBufferContainingLoc(SMLoc Loc) const;
+
+ /// FindLineNumber - Find the line number for the specified location in the
+ /// specified file. This is not a fast method.
+ unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
+
+ /// PrintMessage - Emit a message about the specified location with the
+ /// specified string.
+ ///
+ /// @param ShowColors - Display colored messages if output is a terminal and
+ /// the default error handler is used.
+ void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
+ bool ShowColors = true) const;
+
+
+ /// GetMessage - Return an SMDiagnostic at the specified location with the
+ /// specified string.
+ ///
+ /// @param Type - If non-null, the kind of message (e.g., "error") which is
+ /// prefixed to the message.
+ SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const;
+
+ /// PrintIncludeStack - Prints the names of included files and the line of the
+ /// file they were included from. A diagnostic handler can use this before
+ /// printing its custom formatted message.
+ ///
+ /// @param IncludeLoc - The line of the include.
+ /// @param OS the raw_ostream to print on.
+ void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
+};
+
+
+/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
+/// allowing printing to a raw_ostream as a caret diagnostic.
+class SMDiagnostic {
+ const SourceMgr *SM;
+ SMLoc Loc;
+ std::string Filename;
+ int LineNo, ColumnNo;
+ SourceMgr::DiagKind Kind;
+ std::string Message, LineContents;
+ std::vector<std::pair<unsigned, unsigned> > Ranges;
+
+public:
+ // Null diagnostic.
+ SMDiagnostic()
+ : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
+ // Diagnostic with no location (e.g. file not found, command line arg error).
+ SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Kind,
+ const std::string &Msg)
+ : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Kind),
+ Message(Msg) {}
+
+ // Diagnostic with a location.
+ SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
+ int Line, int Col, SourceMgr::DiagKind Kind,
+ const std::string &Msg, const std::string &LineStr,
+ ArrayRef<std::pair<unsigned,unsigned> > Ranges);
+
+ const SourceMgr *getSourceMgr() const { return SM; }
+ SMLoc getLoc() const { return Loc; }
+ const std::string &getFilename() const { return Filename; }
+ int getLineNo() const { return LineNo; }
+ int getColumnNo() const { return ColumnNo; }
+ SourceMgr::DiagKind getKind() const { return Kind; }
+ const std::string &getMessage() const { return Message; }
+ const std::string &getLineContents() const { return LineContents; }
+ const std::vector<std::pair<unsigned, unsigned> > &getRanges() const {
+ return Ranges;
+ }
+ void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const;
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h b/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h
new file mode 100644
index 000000000000..531dbb216d7a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/StreamableMemoryObject.h
@@ -0,0 +1,181 @@
+//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef STREAMABLEMEMORYOBJECT_H_
+#define STREAMABLEMEMORYOBJECT_H_
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/DataStream.h"
+#include <vector>
+
+namespace llvm {
+
+/// StreamableMemoryObject - Interface to data which might be streamed.
+/// Streamability has 2 important implications/restrictions. First, the data
+/// might not yet exist in memory when the request is made. This just means
+/// that readByte/readBytes might have to block or do some work to get it.
+/// More significantly, the exact size of the object might not be known until
+/// it has all been fetched. This means that to return the right result,
+/// getExtent must also wait for all the data to arrive; therefore it should
+/// not be called on objects which are actually streamed (this would defeat
+/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be
+/// used to test addresses without knowing the exact size of the stream.
+/// Finally, getPointer can be used instead of readBytes to avoid extra copying.
+class StreamableMemoryObject : public MemoryObject {
+ public:
+ /// Destructor - Override as necessary.
+ virtual ~StreamableMemoryObject();
+
+ /// getBase - Returns the lowest valid address in the region.
+ ///
+ /// @result - The lowest valid address.
+ virtual uint64_t getBase() const = 0;
+
+ /// getExtent - Returns the size of the region in bytes. (The region is
+ /// contiguous, so the highest valid address of the region
+ /// is getBase() + getExtent() - 1).
+ /// May block until all bytes in the stream have been read
+ ///
+ /// @result - The size of the region.
+ virtual uint64_t getExtent() const = 0;
+
+ /// readByte - Tries to read a single byte from the region.
+ /// May block until (address - base) bytes have been read
+ /// @param address - The address of the byte, in the same space as getBase().
+ /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
+
+ /// readBytes - Tries to read a contiguous range of bytes from the
+ /// region, up to the end of the region.
+ /// May block until (address - base + size) bytes have
+ /// been read. Additionally, StreamableMemoryObjects will
+ /// not do partial reads - if size bytes cannot be read,
+ /// readBytes will fail.
+ ///
+ /// @param address - The address of the first byte, in the same space as
+ /// getBase().
+ /// @param size - The maximum number of bytes to copy.
+ /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
+ /// and large enough to hold size bytes.
+ /// @param copied - A pointer to a nunber that is filled in with the number
+ /// of bytes actually read. May be NULL.
+ /// @result - 0 if successful; -1 if not. Failure may be due to a
+ /// bounds violation or an implementation-specific error.
+ virtual int readBytes(uint64_t address,
+ uint64_t size,
+ uint8_t* buf,
+ uint64_t* copied) const = 0;
+
+ /// getPointer - Ensures that the requested data is in memory, and returns
+ /// A pointer to it. More efficient than using readBytes if the
+ /// data is already in memory.
+ /// May block until (address - base + size) bytes have been read
+ /// @param address - address of the byte, in the same space as getBase()
+ /// @param size - amount of data that must be available on return
+ /// @result - valid pointer to the requested data
+ virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0;
+
+ /// isValidAddress - Returns true if the address is within the object
+ /// (i.e. between base and base + extent - 1 inclusive)
+ /// May block until (address - base) bytes have been read
+ /// @param address - address of the byte, in the same space as getBase()
+ /// @result - true if the address may be read with readByte()
+ virtual bool isValidAddress(uint64_t address) const = 0;
+
+ /// isObjectEnd - Returns true if the address is one past the end of the
+ /// object (i.e. if it is equal to base + extent)
+ /// May block until (address - base) bytes have been read
+ /// @param address - address of the byte, in the same space as getBase()
+ /// @result - true if the address is equal to base + extent
+ virtual bool isObjectEnd(uint64_t address) const = 0;
+};
+
+/// StreamingMemoryObject - interface to data which is actually streamed from
+/// a DataStreamer. In addition to inherited members, it has the
+/// dropLeadingBytes and setKnownObjectSize methods which are not applicable
+/// to non-streamed objects.
+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 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 {
+ // 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
+ // not currently necessary. Users that need the pointer don't stream.
+ 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;
+
+ /// 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,
+ /// since we don't know a priori if it's present, and we can't put bytes
+ /// back into the stream once we've read them.
+ bool dropLeadingBytes(size_t s);
+
+ /// If the data object size is known in advance, many of the operations can
+ /// be made more efficient, so this method should be called before reading
+ /// starts (although it can be called anytime).
+ void setKnownObjectSize(size_t size);
+
+private:
+ const static uint32_t kChunkSize = 4096 * 4;
+ mutable std::vector<unsigned char> Bytes;
+ OwningPtr<DataStreamer> Streamer;
+ mutable size_t BytesRead; // Bytes read from stream
+ size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
+ mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached
+ mutable bool EOFReached;
+
+ // Fetch enough bytes such that Pos can be read or EOF is reached
+ // (i.e. BytesRead > Pos). Return true if Pos can be read.
+ // Unlike most of the functions in BitcodeReader, returns true on success.
+ // Most of the requests will be small, but we fetch at kChunkSize bytes
+ // at a time to avoid making too many potentially expensive GetBytes calls
+ bool fetchToPos(size_t Pos) const {
+ if (EOFReached) return Pos < ObjectSize;
+ while (Pos >= BytesRead) {
+ Bytes.resize(BytesRead + BytesSkipped + kChunkSize);
+ size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
+ kChunkSize);
+ BytesRead += bytes;
+ if (bytes < kChunkSize) {
+ if (ObjectSize && BytesRead < Pos)
+ assert(0 && "Unexpected short read fetching bitcode");
+ if (BytesRead <= Pos) { // reached EOF/ran out of bytes
+ ObjectSize = BytesRead;
+ EOFReached = true;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT
+ void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT
+};
+
+StreamableMemoryObject *getNonStreamedMemoryObject(
+ const unsigned char *Start, const unsigned char *End);
+
+}
+#endif // STREAMABLEMEMORYOBJECT_H_
diff --git a/contrib/llvm/include/llvm/Support/StringPool.h b/contrib/llvm/include/llvm/Support/StringPool.h
new file mode 100644
index 000000000000..de05e0b547a1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/StringPool.h
@@ -0,0 +1,139 @@
+//===-- StringPool.h - Interned string pool ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares an interned string pool, which helps reduce the cost of
+// strings by using the same storage for identical strings.
+//
+// To intern a string:
+//
+// StringPool Pool;
+// PooledStringPtr Str = Pool.intern("wakka wakka");
+//
+// To use the value of an interned string, use operator bool and operator*:
+//
+// if (Str)
+// cerr << "the string is" << *Str << "\n";
+//
+// Pooled strings are immutable, but you can change a PooledStringPtr to point
+// to another instance. So that interned strings can eventually be freed,
+// strings in the string pool are reference-counted (automatically).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STRINGPOOL_H
+#define LLVM_SUPPORT_STRINGPOOL_H
+
+#include "llvm/ADT/StringMap.h"
+#include <new>
+#include <cassert>
+
+namespace llvm {
+
+ class PooledStringPtr;
+
+ /// StringPool - An interned string pool. Use the intern method to add a
+ /// string. Strings are removed automatically as PooledStringPtrs are
+ /// destroyed.
+ class StringPool {
+ /// PooledString - This is the value of an entry in the pool's interning
+ /// table.
+ struct PooledString {
+ StringPool *Pool; ///< So the string can remove itself.
+ unsigned Refcount; ///< Number of referencing PooledStringPtrs.
+
+ public:
+ PooledString() : Pool(0), Refcount(0) { }
+ };
+
+ friend class PooledStringPtr;
+
+ typedef StringMap<PooledString> table_t;
+ typedef StringMapEntry<PooledString> entry_t;
+ table_t InternTable;
+
+ public:
+ StringPool();
+ ~StringPool();
+
+ /// intern - Adds a string to the pool and returns a reference-counted
+ /// pointer to it. No additional memory is allocated if the string already
+ /// exists in the pool.
+ PooledStringPtr intern(StringRef Str);
+
+ /// empty - Checks whether the pool is empty. Returns true if so.
+ ///
+ inline bool empty() const { return InternTable.empty(); }
+ };
+
+ /// PooledStringPtr - A pointer to an interned string. Use operator bool to
+ /// test whether the pointer is valid, and operator * to get the string if so.
+ /// This is a lightweight value class with storage requirements equivalent to
+ /// a single pointer, but it does have reference-counting overhead when
+ /// copied.
+ class PooledStringPtr {
+ typedef StringPool::entry_t entry_t;
+ entry_t *S;
+
+ public:
+ PooledStringPtr() : S(0) {}
+
+ explicit PooledStringPtr(entry_t *E) : S(E) {
+ if (S) ++S->getValue().Refcount;
+ }
+
+ PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
+ if (S) ++S->getValue().Refcount;
+ }
+
+ PooledStringPtr &operator=(const PooledStringPtr &That) {
+ if (S != That.S) {
+ clear();
+ S = That.S;
+ if (S) ++S->getValue().Refcount;
+ }
+ return *this;
+ }
+
+ void clear() {
+ if (!S)
+ return;
+ if (--S->getValue().Refcount == 0) {
+ S->getValue().Pool->InternTable.remove(S);
+ S->Destroy();
+ }
+ S = 0;
+ }
+
+ ~PooledStringPtr() { clear(); }
+
+ inline const char *begin() const {
+ assert(*this && "Attempt to dereference empty PooledStringPtr!");
+ return S->getKeyData();
+ }
+
+ inline const char *end() const {
+ assert(*this && "Attempt to dereference empty PooledStringPtr!");
+ return S->getKeyData() + S->getKeyLength();
+ }
+
+ inline unsigned size() const {
+ assert(*this && "Attempt to dereference empty PooledStringPtr!");
+ return S->getKeyLength();
+ }
+
+ inline const char *operator*() const { return begin(); }
+ inline operator bool() const { return S != 0; }
+
+ inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
+ inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/SwapByteOrder.h b/contrib/llvm/include/llvm/Support/SwapByteOrder.h
new file mode 100644
index 000000000000..6c0592c05ad7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/SwapByteOrder.h
@@ -0,0 +1,101 @@
+//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares generic and optimized functions to swap the byte order of
+// an integral type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstddef>
+#include <limits>
+
+namespace llvm {
+namespace sys {
+
+/// SwapByteOrder_16 - This function returns a byte-swapped representation of
+/// the 16-bit argument.
+inline uint16_t SwapByteOrder_16(uint16_t value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+ // The DLL version of the runtime lacks these functions (bug!?), but in a
+ // release build they're replaced with BSWAP instructions anyway.
+ return _byteswap_ushort(value);
+#else
+ uint16_t Hi = value << 8;
+ uint16_t Lo = value >> 8;
+ return Hi | Lo;
+#endif
+}
+
+/// SwapByteOrder_32 - This function returns a byte-swapped representation of
+/// the 32-bit argument.
+inline uint32_t SwapByteOrder_32(uint32_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+ return __builtin_bswap32(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_ulong(value);
+#else
+ uint32_t Byte0 = value & 0x000000FF;
+ uint32_t Byte1 = value & 0x0000FF00;
+ uint32_t Byte2 = value & 0x00FF0000;
+ uint32_t Byte3 = value & 0xFF000000;
+ return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// SwapByteOrder_64 - This function returns a byte-swapped representation of
+/// the 64-bit argument.
+inline uint64_t SwapByteOrder_64(uint64_t value) {
+#if defined(__llvm__) || \
+(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC)
+ return __builtin_bswap64(value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_uint64(value);
+#else
+ uint64_t Hi = SwapByteOrder_32(uint32_t(value));
+ uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
+ return (Hi << 32) | Lo;
+#endif
+}
+
+inline unsigned char SwapByteOrder(unsigned char C) { return C; }
+inline signed char SwapByteOrder(signed char C) { return C; }
+inline char SwapByteOrder(char C) { return C; }
+
+inline unsigned short SwapByteOrder(unsigned short C) { return SwapByteOrder_16(C); }
+inline signed short SwapByteOrder( signed short C) { return SwapByteOrder_16(C); }
+
+inline unsigned int SwapByteOrder(unsigned int C) { return SwapByteOrder_32(C); }
+inline signed int SwapByteOrder( signed int C) { return SwapByteOrder_32(C); }
+
+#if __LONG_MAX__ == __INT_MAX__
+inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_32(C); }
+inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_32(C); }
+#elif __LONG_MAX__ == __LONG_LONG_MAX__
+inline unsigned long SwapByteOrder(unsigned long C) { return SwapByteOrder_64(C); }
+inline signed long SwapByteOrder( signed long C) { return SwapByteOrder_64(C); }
+#else
+#error "Unknown long size!"
+#endif
+
+inline unsigned long long SwapByteOrder(unsigned long long C) {
+ return SwapByteOrder_64(C);
+}
+inline signed long long SwapByteOrder(signed long long C) {
+ return SwapByteOrder_64(C);
+}
+
+} // end namespace sys
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/SystemUtils.h b/contrib/llvm/include/llvm/Support/SystemUtils.h
new file mode 100644
index 000000000000..399aee51eb7b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/SystemUtils.h
@@ -0,0 +1,44 @@
+//===- SystemUtils.h - Utilities to do low-level system stuff ---*- 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 functions used to do a variety of low-level, often
+// system-specific, tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
+#define LLVM_SUPPORT_SYSTEMUTILS_H
+
+#include <string>
+
+namespace llvm {
+ class raw_ostream;
+ namespace sys { class Path; }
+
+/// Determine if the raw_ostream provided is connected to a terminal. If so,
+/// generate a warning message to errs() advising against display of bitcode
+/// and return true. Otherwise just return false.
+/// @brief Check for output written to a console
+bool CheckBitcodeOutputToConsole(
+ raw_ostream &stream_to_check, ///< The stream to be checked
+ bool print_warning = true ///< Control whether warnings are printed
+);
+
+/// PrependMainExecutablePath - Prepend the path to the program being executed
+/// to \p ExeName, given the value of argv[0] and the address of main()
+/// itself. This allows us to find another LLVM tool if it is built in the same
+/// directory. An empty string is returned on error; note that this function
+/// just mainpulates the path and doesn't check for executability.
+/// @brief Find a named executable.
+sys::Path PrependMainExecutablePath(const std::string &ExeName,
+ const char *Argv0, void *MainAddr);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/TargetFolder.h b/contrib/llvm/include/llvm/Support/TargetFolder.h
new file mode 100644
index 000000000000..c65faa66219e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/TargetFolder.h
@@ -0,0 +1,255 @@
+//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- 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 TargetFolder class, a helper for IRBuilder.
+// It provides IRBuilder with a set of methods for creating constants with
+// target dependent folding, in addition to the same target-independent
+// folding that the ConstantFolder class provides. For general constant
+// creation and folding, use ConstantExpr and the routines in
+// llvm/Analysis/ConstantFolding.h.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+namespace llvm {
+
+class TargetData;
+
+/// TargetFolder - Create constants with target dependent folding.
+class TargetFolder {
+ const TargetData *TD;
+
+ /// Fold - Fold the constant using target specific information.
+ Constant *Fold(Constant *C) const {
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ if (Constant *CF = ConstantFoldConstantExpression(CE, TD))
+ return CF;
+ return C;
+ }
+
+public:
+ explicit TargetFolder(const TargetData *TheTD) : TD(TheTD) {}
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
+ }
+ Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFAdd(LHS, RHS));
+ }
+ Constant *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
+ }
+ Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFSub(LHS, RHS));
+ }
+ Constant *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
+ }
+ Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFMul(LHS, RHS));
+ }
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
+ }
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
+ }
+ Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFDiv(LHS, RHS));
+ }
+ Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getURem(LHS, RHS));
+ }
+ Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getSRem(LHS, RHS));
+ }
+ Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getFRem(LHS, RHS));
+ }
+ Constant *CreateShl(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
+ }
+ Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
+ }
+ Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
+ }
+ Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getAnd(LHS, RHS));
+ }
+ Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getOr(LHS, RHS));
+ }
+ Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::getXor(LHS, RHS));
+ }
+
+ Constant *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const {
+ return Fold(ConstantExpr::get(Opc, LHS, RHS));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const {
+ return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
+ }
+ Constant *CreateFNeg(Constant *C) const {
+ return Fold(ConstantExpr::getFNeg(C));
+ }
+ Constant *CreateNot(Constant *C) const {
+ return Fold(ConstantExpr::getNot(C));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) const {
+ return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
+ }
+ Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const {
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ return Fold(ConstantExpr::getGetElementPtr(C, Idx));
+ }
+ Constant *CreateGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) const {
+ return Fold(ConstantExpr::getGetElementPtr(C, IdxList));
+ }
+
+ Constant *CreateInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Constant *> IdxList) const {
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const {
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx));
+ }
+ Constant *CreateInBoundsGetElementPtr(Constant *C,
+ ArrayRef<Value *> IdxList) const {
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateCast(Instruction::CastOps Op, Constant *C,
+ Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getCast(Op, C, DestTy));
+ }
+ Constant *CreateIntCast(Constant *C, Type *DestTy,
+ bool isSigned) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
+ }
+ Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
+ return ConstantExpr::getPointerCast(C, DestTy);
+ }
+ Constant *CreateBitCast(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::BitCast, C, DestTy);
+ }
+ Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::IntToPtr, C, DestTy);
+ }
+ Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
+ return CreateCast(Instruction::PtrToInt, C, DestTy);
+ }
+ Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
+ }
+ Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
+ }
+ Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+ if (C->getType() == DestTy)
+ return C; // avoid calling Fold
+ return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+ }
+ Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const {
+ return Fold(ConstantExpr::getCompare(P, LHS, RHS));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ return Fold(ConstantExpr::getSelect(C, True, False));
+ }
+
+ Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ return Fold(ConstantExpr::getExtractElement(Vec, Idx));
+ }
+
+ Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const {
+ return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
+ }
+
+ Constant *CreateShuffleVector(Constant *V1, Constant *V2,
+ Constant *Mask) const {
+ return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
+ }
+
+ Constant *CreateExtractValue(Constant *Agg,
+ ArrayRef<unsigned> IdxList) const {
+ return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
+ }
+
+ Constant *CreateInsertValue(Constant *Agg, Constant *Val,
+ ArrayRef<unsigned> IdxList) const {
+ return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
+ }
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/TargetRegistry.h b/contrib/llvm/include/llvm/Support/TargetRegistry.h
new file mode 100644
index 000000000000..88081307ac6b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/TargetRegistry.h
@@ -0,0 +1,1140 @@
+//===-- Support/TargetRegistry.h - Target Registration ----------*- 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 the TargetRegistry interface, which tools can use to access
+// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
+// which have been registered.
+//
+// Target specific class implementations should register themselves using the
+// appropriate TargetRegistry interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
+#define LLVM_SUPPORT_TARGETREGISTRY_H
+
+#include "llvm/Support/CodeGen.h"
+#include "llvm/ADT/Triple.h"
+#include <string>
+#include <cassert>
+
+namespace llvm {
+ class AsmPrinter;
+ class Module;
+ class MCAssembler;
+ class MCAsmBackend;
+ class MCAsmInfo;
+ class MCAsmParser;
+ class MCCodeEmitter;
+ class MCCodeGenInfo;
+ class MCContext;
+ class MCDisassembler;
+ class MCInstrAnalysis;
+ class MCInstPrinter;
+ class MCInstrInfo;
+ class MCRegisterInfo;
+ class MCStreamer;
+ class MCSubtargetInfo;
+ class MCTargetAsmLexer;
+ class MCTargetAsmParser;
+ class TargetMachine;
+ class TargetOptions;
+ class raw_ostream;
+ class formatted_raw_ostream;
+
+ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm,
+ bool useLoc, bool useCFI,
+ bool useDwarfDirectory,
+ MCInstPrinter *InstPrint,
+ MCCodeEmitter *CE,
+ MCAsmBackend *TAB,
+ bool ShowInst);
+
+ /// Target - Wrapper for Target specific information.
+ ///
+ /// For registration purposes, this is a POD type so that targets can be
+ /// registered without the use of static constructors.
+ ///
+ /// Targets should implement a single global instance of this class (which
+ /// will be zero initialized), and pass that instance to the TargetRegistry as
+ /// part of their initialization.
+ class Target {
+ public:
+ friend struct TargetRegistry;
+
+ typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
+
+ typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T,
+ StringRef TT);
+ typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
+ Reloc::Model RM,
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL);
+ typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
+ typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
+ typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
+ typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
+ StringRef CPU,
+ StringRef Features);
+ typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
+ StringRef TT,
+ StringRef CPU,
+ StringRef Features,
+ const TargetOptions &Options,
+ Reloc::Model RM,
+ CodeModel::Model CM,
+ 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 MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
+ MCAsmParser &P);
+ typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
+ const MCSubtargetInfo &STI);
+ typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI);
+ typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx);
+ typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
+ StringRef TT,
+ MCContext &Ctx,
+ MCAsmBackend &TAB,
+ raw_ostream &_OS,
+ MCCodeEmitter *_Emitter,
+ bool RelaxAll,
+ bool NoExecStack);
+ typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
+ formatted_raw_ostream &OS,
+ bool isVerboseAsm,
+ bool useLoc,
+ bool useCFI,
+ bool useDwarfDirectory,
+ MCInstPrinter *InstPrint,
+ MCCodeEmitter *CE,
+ MCAsmBackend *TAB,
+ bool ShowInst);
+
+ private:
+ /// Next - The next registered target in the linked list, maintained by the
+ /// TargetRegistry.
+ Target *Next;
+
+ /// TripleMatchQualityFn - The target function for rating the match quality
+ /// of a triple.
+ TripleMatchQualityFnTy TripleMatchQualityFn;
+
+ /// Name - The target name.
+ const char *Name;
+
+ /// ShortDesc - A short description of the target.
+ const char *ShortDesc;
+
+ /// HasJIT - Whether this target supports the JIT.
+ bool HasJIT;
+
+ /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
+ /// registered.
+ MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
+
+ /// MCCodeGenInfoCtorFn - Constructor function for this target's
+ /// MCCodeGenInfo, if registered.
+ MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
+
+ /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
+ /// if registered.
+ MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
+
+ /// MCInstrAnalysisCtorFn - Constructor function for this target's
+ /// MCInstrAnalysis, if registered.
+ MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
+
+ /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
+ /// if registered.
+ MCRegInfoCtorFnTy MCRegInfoCtorFn;
+
+ /// MCSubtargetInfoCtorFn - Constructor function for this target's
+ /// MCSubtargetInfo, if registered.
+ MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
+
+ /// TargetMachineCtorFn - Construction function for this target's
+ /// TargetMachine, if registered.
+ TargetMachineCtorTy TargetMachineCtorFn;
+
+ /// MCAsmBackendCtorFn - Construction function for this target's
+ /// 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;
+
+ /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
+ /// if registered.
+ AsmPrinterCtorTy AsmPrinterCtorFn;
+
+ /// MCDisassemblerCtorFn - Construction function for this target's
+ /// MCDisassembler, if registered.
+ MCDisassemblerCtorTy MCDisassemblerCtorFn;
+
+ /// MCInstPrinterCtorFn - Construction function for this target's
+ /// MCInstPrinter, if registered.
+ MCInstPrinterCtorTy MCInstPrinterCtorFn;
+
+ /// MCCodeEmitterCtorFn - Construction function for this target's
+ /// CodeEmitter, if registered.
+ MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
+
+ /// MCObjectStreamerCtorFn - Construction function for this target's
+ /// MCObjectStreamer, if registered.
+ MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
+
+ /// AsmStreamerCtorFn - Construction function for this target's
+ /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
+ AsmStreamerCtorTy AsmStreamerCtorFn;
+
+ public:
+ Target() : AsmStreamerCtorFn(llvm::createAsmStreamer) {}
+
+ /// @name Target Information
+ /// @{
+
+ // getNext - Return the next registered target.
+ const Target *getNext() const { return Next; }
+
+ /// getName - Get the target name.
+ const char *getName() const { return Name; }
+
+ /// getShortDescription - Get a short description of the target.
+ const char *getShortDescription() const { return ShortDesc; }
+
+ /// @}
+ /// @name Feature Predicates
+ /// @{
+
+ /// hasJIT - Check if this targets supports the just-in-time compilation.
+ bool hasJIT() const { return HasJIT; }
+
+ /// hasTargetMachine - Check if this target supports code generation.
+ bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
+
+ /// 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; }
+
+ /// hasAsmPrinter - Check if this target supports .s printing.
+ bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; }
+
+ /// hasMCDisassembler - Check if this target has a disassembler.
+ bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
+
+ /// hasMCInstPrinter - Check if this target has an instruction printer.
+ bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; }
+
+ /// hasMCCodeEmitter - Check if this target supports instruction encoding.
+ bool hasMCCodeEmitter() const { return MCCodeEmitterCtorFn != 0; }
+
+ /// hasMCObjectStreamer - Check if this target supports streaming to files.
+ bool hasMCObjectStreamer() const { return MCObjectStreamerCtorFn != 0; }
+
+ /// hasAsmStreamer - Check if this target supports streaming to files.
+ bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; }
+
+ /// @}
+ /// @name Feature Constructors
+ /// @{
+
+ /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
+ /// target triple.
+ ///
+ /// \arg 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.
+ MCAsmInfo *createMCAsmInfo(StringRef Triple) const {
+ if (!MCAsmInfoCtorFn)
+ return 0;
+ return MCAsmInfoCtorFn(*this, Triple);
+ }
+
+ /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
+ ///
+ MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) const {
+ if (!MCCodeGenInfoCtorFn)
+ return 0;
+ return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
+ }
+
+ /// createMCInstrInfo - Create a MCInstrInfo implementation.
+ ///
+ MCInstrInfo *createMCInstrInfo() const {
+ if (!MCInstrInfoCtorFn)
+ return 0;
+ return MCInstrInfoCtorFn();
+ }
+
+ /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
+ ///
+ MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
+ if (!MCInstrAnalysisCtorFn)
+ return 0;
+ return MCInstrAnalysisCtorFn(Info);
+ }
+
+ /// createMCRegInfo - Create a MCRegisterInfo implementation.
+ ///
+ MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
+ if (!MCRegInfoCtorFn)
+ return 0;
+ return MCRegInfoCtorFn(Triple);
+ }
+
+ /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
+ ///
+ /// \arg 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
+ /// additional target features.
+ MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
+ StringRef Features) const {
+ if (!MCSubtargetInfoCtorFn)
+ return 0;
+ return MCSubtargetInfoCtorFn(Triple, CPU, Features);
+ }
+
+ /// createTargetMachine - Create a target specific machine implementation
+ /// for the specified \arg Triple.
+ ///
+ /// \arg 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.
+ TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
+ StringRef Features, const TargetOptions &Options,
+ Reloc::Model RM = Reloc::Default,
+ CodeModel::Model CM = CodeModel::Default,
+ CodeGenOpt::Level OL = CodeGenOpt::Default) const {
+ if (!TargetMachineCtorFn)
+ return 0;
+ return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
+ RM, CM, OL);
+ }
+
+ /// 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 {
+ 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);
+ }
+
+ /// createMCAsmParser - Create a target specific assembly parser.
+ ///
+ /// \arg Parser - The target independent parser implementation to use for
+ /// parsing and lexing.
+ MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
+ MCAsmParser &Parser) const {
+ if (!MCAsmParserCtorFn)
+ return 0;
+ return MCAsmParserCtorFn(STI, Parser);
+ }
+
+ /// createAsmPrinter - Create a target specific assembly printer pass. This
+ /// takes ownership of the MCStreamer object.
+ AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
+ if (!AsmPrinterCtorFn)
+ return 0;
+ return AsmPrinterCtorFn(TM, Streamer);
+ }
+
+ MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI) const {
+ if (!MCDisassemblerCtorFn)
+ return 0;
+ return MCDisassemblerCtorFn(*this, STI);
+ }
+
+ MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI) const {
+ if (!MCInstPrinterCtorFn)
+ return 0;
+ return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
+ }
+
+
+ /// createMCCodeEmitter - Create a target specific code emitter.
+ MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx) const {
+ if (!MCCodeEmitterCtorFn)
+ return 0;
+ return MCCodeEmitterCtorFn(II, STI, Ctx);
+ }
+
+ /// 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.
+ MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
+ MCAsmBackend &TAB,
+ raw_ostream &_OS,
+ MCCodeEmitter *_Emitter,
+ bool RelaxAll,
+ bool NoExecStack) const {
+ if (!MCObjectStreamerCtorFn)
+ return 0;
+ return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter,
+ RelaxAll, NoExecStack);
+ }
+
+ /// createAsmStreamer - Create a target specific MCStreamer.
+ MCStreamer *createAsmStreamer(MCContext &Ctx,
+ formatted_raw_ostream &OS,
+ bool isVerboseAsm,
+ bool useLoc,
+ bool useCFI,
+ bool useDwarfDirectory,
+ MCInstPrinter *InstPrint,
+ MCCodeEmitter *CE,
+ MCAsmBackend *TAB,
+ bool ShowInst) const {
+ // AsmStreamerCtorFn is default to llvm::createAsmStreamer
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
+ useDwarfDirectory, InstPrint, CE, TAB, ShowInst);
+ }
+
+ /// @}
+ };
+
+ /// TargetRegistry - Generic interface to target specific features.
+ struct TargetRegistry {
+ class iterator {
+ const Target *Current;
+ explicit iterator(Target *T) : Current(T) {}
+ friend struct TargetRegistry;
+ public:
+ iterator(const iterator &I) : Current(I.Current) {}
+ iterator() : Current(0) {}
+
+ bool operator==(const iterator &x) const {
+ return Current == x.Current;
+ }
+ bool operator!=(const iterator &x) const {
+ return !operator==(x);
+ }
+
+ // Iterator traversal: forward iteration only
+ iterator &operator++() { // Preincrement
+ assert(Current && "Cannot increment end iterator!");
+ Current = Current->getNext();
+ return *this;
+ }
+ iterator operator++(int) { // Postincrement
+ iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ const Target &operator*() const {
+ assert(Current && "Cannot dereference end iterator!");
+ return *Current;
+ }
+
+ const Target *operator->() const {
+ return &operator*();
+ }
+ };
+
+ /// printRegisteredTargetsForVersion - Print the registered targets
+ /// appropriately for inclusion in a tool's version output.
+ static void printRegisteredTargetsForVersion();
+
+ /// @name Registry Access
+ /// @{
+
+ static iterator begin();
+
+ static iterator end() { return iterator(); }
+
+ /// lookupTarget - Lookup a target based on a target triple.
+ ///
+ /// \param Triple - The triple to use for finding a target.
+ /// \param Error - On failure, an error string describing why no target was
+ /// found.
+ static const Target *lookupTarget(const std::string &Triple,
+ std::string &Error);
+
+ /// getClosestTargetForJIT - Pick the best target that is compatible with
+ /// the current host. If no close target can be found, this returns null
+ /// and sets the Error string to a reason.
+ ///
+ /// Maintained for compatibility through 2.6.
+ static const Target *getClosestTargetForJIT(std::string &Error);
+
+ /// @}
+ /// @name Target Registration
+ /// @{
+
+ /// RegisterTarget - Register the given target. Attempts to register a
+ /// target which has already been registered will be ignored.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Name - The target name. This should be a static string.
+ /// @param ShortDesc - A short target description. This should be a static
+ /// string.
+ /// @param TQualityFn - The triple match quality computation function for
+ /// this target.
+ /// @param HasJIT - Whether the target supports JIT code
+ /// generation.
+ static void RegisterTarget(Target &T,
+ const char *Name,
+ const char *ShortDesc,
+ Target::TripleMatchQualityFnTy TQualityFn,
+ bool HasJIT = false);
+
+ /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCAsmInfo for the target.
+ static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCAsmInfoCtorFn)
+ T.MCAsmInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCCodeGenInfo for the target.
+ static void RegisterMCCodeGenInfo(Target &T,
+ Target::MCCodeGenInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCCodeGenInfoCtorFn)
+ T.MCCodeGenInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCInstrInfo for the target.
+ static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCInstrInfoCtorFn)
+ T.MCInstrInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
+ /// the given target.
+ static void RegisterMCInstrAnalysis(Target &T,
+ Target::MCInstrAnalysisCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCInstrAnalysisCtorFn)
+ T.MCInstrAnalysisCtorFn = Fn;
+ }
+
+ /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCRegisterInfo for the target.
+ static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCRegInfoCtorFn)
+ T.MCRegInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
+ /// the given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCSubtargetInfo for the target.
+ static void RegisterMCSubtargetInfo(Target &T,
+ Target::MCSubtargetInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCSubtargetInfoCtorFn)
+ T.MCSubtargetInfoCtorFn = Fn;
+ }
+
+ /// RegisterTargetMachine - Register a TargetMachine implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a TargetMachine for the target.
+ static void RegisterTargetMachine(Target &T,
+ Target::TargetMachineCtorTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.TargetMachineCtorFn)
+ T.TargetMachineCtorFn = Fn;
+ }
+
+ /// RegisterMCAsmBackend - Register a MCAsmBackend 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 AsmBackend for the target.
+ static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
+ if (!T.MCAsmBackendCtorFn)
+ 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.
+ ///
+ /// 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 MCTargetAsmParser for the target.
+ static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
+ if (!T.MCAsmParserCtorFn)
+ T.MCAsmParserCtorFn = Fn;
+ }
+
+ /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
+ /// target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an AsmPrinter for the target.
+ static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.AsmPrinterCtorFn)
+ T.AsmPrinterCtorFn = Fn;
+ }
+
+ /// RegisterMCDisassembler - Register a MCDisassembler implementation for
+ /// the given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCDisassembler for the target.
+ static void RegisterMCDisassembler(Target &T,
+ Target::MCDisassemblerCtorTy Fn) {
+ if (!T.MCDisassemblerCtorFn)
+ T.MCDisassemblerCtorFn = Fn;
+ }
+
+ /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct an MCInstPrinter for the target.
+ static void RegisterMCInstPrinter(Target &T,
+ Target::MCInstPrinterCtorTy Fn) {
+ if (!T.MCInstPrinterCtorFn)
+ T.MCInstPrinterCtorFn = Fn;
+ }
+
+ /// RegisterMCCodeEmitter - Register a MCCodeEmitter 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 MCCodeEmitter for the target.
+ static void RegisterMCCodeEmitter(Target &T,
+ Target::MCCodeEmitterCtorTy Fn) {
+ if (!T.MCCodeEmitterCtorFn)
+ T.MCCodeEmitterCtorFn = Fn;
+ }
+
+ /// RegisterMCObjectStreamer - Register a object code MCStreamer
+ /// 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 MCStreamer for the target.
+ static void RegisterMCObjectStreamer(Target &T,
+ Target::MCObjectStreamerCtorTy Fn) {
+ if (!T.MCObjectStreamerCtorFn)
+ T.MCObjectStreamerCtorFn = Fn;
+ }
+
+ /// RegisterAsmStreamer - Register an assembly MCStreamer 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 MCStreamer for the target.
+ static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
+ if (T.AsmStreamerCtorFn == createAsmStreamer)
+ T.AsmStreamerCtorFn = Fn;
+ }
+
+ /// @}
+ };
+
+
+ //===--------------------------------------------------------------------===//
+
+ /// RegisterTarget - Helper template for registering a target, for use in the
+ /// target's initialization function. Usage:
+ ///
+ ///
+ /// Target TheFooTarget; // The global target instance.
+ ///
+ /// extern "C" void LLVMInitializeFooTargetInfo() {
+ /// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
+ /// }
+ template<Triple::ArchType TargetArchType = Triple::UnknownArch,
+ bool HasJIT = false>
+ struct RegisterTarget {
+ RegisterTarget(Target &T, const char *Name, const char *Desc) {
+ TargetRegistry::RegisterTarget(T, Name, Desc,
+ &getTripleMatchQuality,
+ HasJIT);
+ }
+
+ static unsigned getTripleMatchQuality(const std::string &TT) {
+ if (Triple(TT).getArch() == TargetArchType)
+ return 20;
+ return 0;
+ }
+ };
+
+ /// RegisterMCAsmInfo - Helper template for registering a target assembly info
+ /// implementation. This invokes the static "Create" method on the class to
+ /// actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
+ /// }
+ template<class MCAsmInfoImpl>
+ struct RegisterMCAsmInfo {
+ RegisterMCAsmInfo(Target &T) {
+ TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
+ }
+ private:
+ static MCAsmInfo *Allocator(const Target &T, StringRef TT) {
+ return new MCAsmInfoImpl(T, TT);
+ }
+
+ };
+
+ /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
+ /// implementation. This invokes the specified function to do the
+ /// construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCAsmInfoFn {
+ RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCAsmInfo(T, Fn);
+ }
+ };
+
+ /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
+ /// implementation. This invokes the static "Create" method on the class
+ /// to actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
+ /// }
+ template<class MCCodeGenInfoImpl>
+ struct RegisterMCCodeGenInfo {
+ RegisterMCCodeGenInfo(Target &T) {
+ TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
+ }
+ private:
+ static MCCodeGenInfo *Allocator(StringRef TT, Reloc::Model RM,
+ CodeModel::Model CM, CodeGenOpt::Level OL) {
+ return new MCCodeGenInfoImpl();
+ }
+ };
+
+ /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
+ /// info implementation. This invokes the specified function to do the
+ /// construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCCodeGenInfoFn {
+ RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
+ }
+ };
+
+ /// RegisterMCInstrInfo - Helper template for registering a target instruction
+ /// info implementation. This invokes the static "Create" method on the class
+ /// to actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
+ /// }
+ template<class MCInstrInfoImpl>
+ struct RegisterMCInstrInfo {
+ RegisterMCInstrInfo(Target &T) {
+ TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
+ }
+ private:
+ static MCInstrInfo *Allocator() {
+ return new MCInstrInfoImpl();
+ }
+ };
+
+ /// RegisterMCInstrInfoFn - Helper template for registering a target
+ /// instruction info implementation. This invokes the specified function to
+ /// do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCInstrInfoFn {
+ RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCInstrInfo(T, Fn);
+ }
+ };
+
+ /// RegisterMCInstrAnalysis - Helper template for registering a target
+ /// instruction analyzer implementation. This invokes the static "Create"
+ /// method on the class to actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
+ /// }
+ template<class MCInstrAnalysisImpl>
+ struct RegisterMCInstrAnalysis {
+ RegisterMCInstrAnalysis(Target &T) {
+ TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
+ }
+ private:
+ static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
+ return new MCInstrAnalysisImpl(Info);
+ }
+ };
+
+ /// RegisterMCInstrAnalysisFn - Helper template for registering a target
+ /// instruction analyzer implementation. This invokes the specified function
+ /// to do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCInstrAnalysisFn {
+ RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
+ TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
+ }
+ };
+
+ /// RegisterMCRegInfo - Helper template for registering a target register info
+ /// implementation. This invokes the static "Create" method on the class to
+ /// actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
+ /// }
+ template<class MCRegisterInfoImpl>
+ struct RegisterMCRegInfo {
+ RegisterMCRegInfo(Target &T) {
+ TargetRegistry::RegisterMCRegInfo(T, &Allocator);
+ }
+ private:
+ static MCRegisterInfo *Allocator(StringRef TT) {
+ return new MCRegisterInfoImpl();
+ }
+ };
+
+ /// RegisterMCRegInfoFn - Helper template for registering a target register
+ /// info implementation. This invokes the specified function to do the
+ /// construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCRegInfoFn {
+ RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCRegInfo(T, Fn);
+ }
+ };
+
+ /// RegisterMCSubtargetInfo - Helper template for registering a target
+ /// subtarget info implementation. This invokes the static "Create" method
+ /// on the class to actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
+ /// }
+ template<class MCSubtargetInfoImpl>
+ struct RegisterMCSubtargetInfo {
+ RegisterMCSubtargetInfo(Target &T) {
+ TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
+ }
+ private:
+ static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU,
+ StringRef FS) {
+ return new MCSubtargetInfoImpl();
+ }
+ };
+
+ /// RegisterMCSubtargetInfoFn - Helper template for registering a target
+ /// subtarget info implementation. This invokes the specified function to
+ /// do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCSubtargetInfoFn {
+ RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
+ }
+ };
+
+ /// RegisterTargetMachine - Helper template for registering a target machine
+ /// implementation, for use in the target machine initialization
+ /// function. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
+ /// }
+ template<class TargetMachineImpl>
+ struct RegisterTargetMachine {
+ RegisterTargetMachine(Target &T) {
+ TargetRegistry::RegisterTargetMachine(T, &Allocator);
+ }
+
+ private:
+ static TargetMachine *Allocator(const Target &T, StringRef TT,
+ StringRef CPU, StringRef FS,
+ const TargetOptions &Options,
+ Reloc::Model RM,
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) {
+ return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
+ }
+ };
+
+ /// RegisterMCAsmBackend - Helper template for registering a target specific
+ /// assembler backend. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooMCAsmBackend() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
+ /// }
+ template<class MCAsmBackendImpl>
+ struct RegisterMCAsmBackend {
+ RegisterMCAsmBackend(Target &T) {
+ TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
+ }
+
+ 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);
+ }
+ };
+
+ /// RegisterMCAsmParser - Helper template for registering a target specific
+ /// assembly parser, for use in the target machine initialization
+ /// function. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooMCAsmParser() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
+ /// }
+ template<class MCAsmParserImpl>
+ struct RegisterMCAsmParser {
+ RegisterMCAsmParser(Target &T) {
+ TargetRegistry::RegisterMCAsmParser(T, &Allocator);
+ }
+
+ private:
+ static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) {
+ return new MCAsmParserImpl(STI, P);
+ }
+ };
+
+ /// RegisterAsmPrinter - Helper template for registering a target specific
+ /// assembly printer, for use in the target machine initialization
+ /// function. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooAsmPrinter() {
+ /// extern Target TheFooTarget;
+ /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
+ /// }
+ template<class AsmPrinterImpl>
+ struct RegisterAsmPrinter {
+ RegisterAsmPrinter(Target &T) {
+ TargetRegistry::RegisterAsmPrinter(T, &Allocator);
+ }
+
+ private:
+ static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) {
+ return new AsmPrinterImpl(TM, Streamer);
+ }
+ };
+
+ /// RegisterMCCodeEmitter - Helper template for registering a target specific
+ /// machine code emitter, for use in the target initialization
+ /// function. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooMCCodeEmitter() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
+ /// }
+ template<class MCCodeEmitterImpl>
+ struct RegisterMCCodeEmitter {
+ RegisterMCCodeEmitter(Target &T) {
+ TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
+ }
+
+ private:
+ static MCCodeEmitter *Allocator(const MCInstrInfo &II,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx) {
+ return new MCCodeEmitterImpl();
+ }
+ };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/TargetSelect.h b/contrib/llvm/include/llvm/Support/TargetSelect.h
new file mode 100644
index 000000000000..a86e953f00ea
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/TargetSelect.h
@@ -0,0 +1,166 @@
+//===- TargetSelect.h - Target Selection & Registration ---------*- 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 utilities to make sure that certain classes of targets are
+// linked into the main application executable, and initialize them as
+// appropriate.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TARGETSELECT_H
+#define LLVM_SUPPORT_TARGETSELECT_H
+
+#include "llvm/Config/llvm-config.h"
+
+extern "C" {
+ // Declare all of the target-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo();
+#include "llvm/Config/Targets.def"
+
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+
+ // Declare all of the target-MC-initialization functions that are available.
+#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/Targets.def"
+
+ // Declare all of the available assembly printer initialization functions.
+#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+
+ // Declare all of the available assembly parser initialization functions.
+#define LLVM_ASM_PARSER(TargetName) void LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+
+ // Declare all of the available disassembler initialization functions.
+#define LLVM_DISASSEMBLER(TargetName) \
+ void LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+}
+
+namespace llvm {
+ /// InitializeAllTargetInfos - The main program should call this function if
+ /// it wants access to all available targets that LLVM is configured to
+ /// support, to make them available via the TargetRegistry.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline void InitializeAllTargetInfos() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo();
+#include "llvm/Config/Targets.def"
+ }
+
+ /// InitializeAllTargets - The main program should call this function if it
+ /// wants access to all available target machines that LLVM is configured to
+ /// support, to make them available via the TargetRegistry.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline void InitializeAllTargets() {
+ // FIXME: Remove this, clients should do it.
+ InitializeAllTargetInfos();
+
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
+#include "llvm/Config/Targets.def"
+ }
+
+ /// InitializeAllTargetMCs - The main program should call this function if it
+ /// wants access to all available target MC that LLVM is configured to
+ /// support, to make them available via the TargetRegistry.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline void InitializeAllTargetMCs() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC();
+#include "llvm/Config/Targets.def"
+ }
+
+ /// InitializeAllAsmPrinters - The main program should call this function if
+ /// it wants all asm printers that LLVM is configured to support, to make them
+ /// available via the TargetRegistry.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline void InitializeAllAsmPrinters() {
+#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter();
+#include "llvm/Config/AsmPrinters.def"
+ }
+
+ /// InitializeAllAsmParsers - The main program should call this function if it
+ /// wants all asm parsers that LLVM is configured to support, to make them
+ /// available via the TargetRegistry.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline void InitializeAllAsmParsers() {
+#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser();
+#include "llvm/Config/AsmParsers.def"
+ }
+
+ /// InitializeAllDisassemblers - The main program should call this function if
+ /// it wants all disassemblers that LLVM is configured to support, to make
+ /// them available via the TargetRegistry.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline void InitializeAllDisassemblers() {
+#define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler();
+#include "llvm/Config/Disassemblers.def"
+ }
+
+ /// InitializeNativeTarget - The main program should call this function to
+ /// initialize the native target corresponding to the host. This is useful
+ /// for JIT applications to ensure that the target gets linked in correctly.
+ ///
+ /// It is legal for a client to make multiple calls to this function.
+ inline bool InitializeNativeTarget() {
+ // If we have a native target, initialize it to ensure it is linked in.
+#ifdef LLVM_NATIVE_TARGET
+ LLVM_NATIVE_TARGETINFO();
+ LLVM_NATIVE_TARGET();
+ LLVM_NATIVE_TARGETMC();
+ return false;
+#else
+ return true;
+#endif
+ }
+
+ /// InitializeNativeTargetAsmPrinter - The main program should call
+ /// this function to initialize the native target asm printer.
+ inline bool InitializeNativeTargetAsmPrinter() {
+ // If we have a native target, initialize the corresponding asm printer.
+#ifdef LLVM_NATIVE_ASMPRINTER
+ LLVM_NATIVE_ASMPRINTER();
+ return false;
+#else
+ return true;
+#endif
+ }
+
+ /// InitializeNativeTargetAsmParser - The main program should call
+ /// this function to initialize the native target asm parser.
+ inline bool InitializeNativeTargetAsmParser() {
+ // If we have a native target, initialize the corresponding asm parser.
+#ifdef LLVM_NATIVE_ASMPARSER
+ LLVM_NATIVE_ASMPARSER();
+ return false;
+#else
+ return true;
+#endif
+ }
+
+ /// InitializeNativeTargetDisassembler - The main program should call
+ /// this function to initialize the native target disassembler.
+ inline bool InitializeNativeTargetDisassembler() {
+ // If we have a native target, initialize the corresponding disassembler.
+#ifdef LLVM_NATIVE_DISASSEMBLER
+ LLVM_NATIVE_DISASSEMBLER();
+ return false;
+#else
+ return true;
+#endif
+ }
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/ThreadLocal.h b/contrib/llvm/include/llvm/Support/ThreadLocal.h
new file mode 100644
index 000000000000..15350a7afff7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ThreadLocal.h
@@ -0,0 +1,54 @@
+//===- llvm/Support/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::ThreadLocal class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
+#define LLVM_SYSTEM_THREAD_LOCAL_H
+
+#include "llvm/Support/Threading.h"
+#include <cassert>
+
+namespace llvm {
+ namespace sys {
+ // ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
+ // YOU SHOULD NEVER USE THIS DIRECTLY.
+ class ThreadLocalImpl {
+ void* data;
+ public:
+ ThreadLocalImpl();
+ virtual ~ThreadLocalImpl();
+ void setInstance(const void* d);
+ const void* getInstance();
+ void removeInstance();
+ };
+
+ /// ThreadLocal - A class used to abstract thread-local storage. It holds,
+ /// for each thread, a pointer a single object of type T.
+ template<class T>
+ class ThreadLocal : public ThreadLocalImpl {
+ public:
+ ThreadLocal() : ThreadLocalImpl() { }
+
+ /// get - Fetches a pointer to the object associated with the current
+ /// thread. If no object has yet been associated, it returns NULL;
+ T* get() { return static_cast<T*>(getInstance()); }
+
+ // set - Associates a pointer to an object with the current thread.
+ void set(T* d) { setInstance(d); }
+
+ // erase - Removes the pointer associated with the current thread.
+ void erase() { removeInstance(); }
+ };
+ }
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Threading.h b/contrib/llvm/include/llvm/Support/Threading.h
new file mode 100644
index 000000000000..c0e842c2fe73
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Threading.h
@@ -0,0 +1,59 @@
+//===-- llvm/Support/Threading.h - Control multithreading mode --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// TThis file defines llvm_start_multithreaded() and friends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_THREADING_H
+#define LLVM_SYSTEM_THREADING_H
+
+namespace llvm {
+ /// llvm_start_multithreaded - Allocate and initialize structures needed to
+ /// make LLVM safe for multithreading. The return value indicates whether
+ /// multithreaded initialization succeeded. LLVM will still be operational
+ /// on "failed" return, and will still be safe for hosting threading
+ /// applications in the JIT, but will not be safe for concurrent calls to the
+ /// LLVM APIs.
+ /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
+ bool llvm_start_multithreaded();
+
+ /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
+ /// safe for multithreading.
+ /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
+ void llvm_stop_multithreaded();
+
+ /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
+ /// mode or not.
+ bool llvm_is_multithreaded();
+
+ /// acquire_global_lock - Acquire the global lock. This is a no-op if called
+ /// before llvm_start_multithreaded().
+ void llvm_acquire_global_lock();
+
+ /// release_global_lock - Release the global lock. This is a no-op if called
+ /// 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.
+ ///
+ /// 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
+ /// so where system support is available.
+ ///
+ /// \param UserFn - The callback to execute.
+ /// \param UserData - An argument to pass to the callback function.
+ /// \param RequestedStackSize - If non-zero, a requested size (in bytes) for
+ /// the thread stack.
+ void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
+ unsigned RequestedStackSize = 0);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/TimeValue.h b/contrib/llvm/include/llvm/Support/TimeValue.h
new file mode 100644
index 000000000000..94f132a05ca7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/TimeValue.h
@@ -0,0 +1,382 @@
+//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+#ifndef LLVM_SYSTEM_TIMEVALUE_H
+#define LLVM_SYSTEM_TIMEVALUE_H
+
+namespace llvm {
+namespace sys {
+ /// This class is used where a precise fixed point in time is required. The
+ /// range of TimeValue spans many hundreds of billions of years both past and
+ /// present. The precision of TimeValue is to the nanosecond. However, the
+ /// actual precision of its values will be determined by the resolution of
+ /// the system clock. The TimeValue class is used in conjunction with several
+ /// other lib/System interfaces to specify the time at which a call should
+ /// timeout, etc.
+ /// @since 1.4
+ /// @brief Provides an abstraction for a fixed point in time.
+ class TimeValue {
+
+ /// @name Constants
+ /// @{
+ public:
+
+ /// A constant TimeValue representing the smallest time
+ /// value permissible by the class. MinTime is some point
+ /// in the distant past, about 300 billion years BCE.
+ /// @brief The smallest possible time value.
+ static const TimeValue MinTime;
+
+ /// A constant TimeValue representing the largest time
+ /// value permissible by the class. MaxTime is some point
+ /// in the distant future, about 300 billion years AD.
+ /// @brief The largest possible time value.
+ static const TimeValue MaxTime;
+
+ /// A constant TimeValue representing the base time,
+ /// or zero time of 00:00:00 (midnight) January 1st, 2000.
+ /// @brief 00:00:00 Jan 1, 2000 UTC.
+ static const TimeValue ZeroTime;
+
+ /// A constant TimeValue for the Posix base time which is
+ /// 00:00:00 (midnight) January 1st, 1970.
+ /// @brief 00:00:00 Jan 1, 1970 UTC.
+ static const TimeValue PosixZeroTime;
+
+ /// A constant TimeValue for the Win32 base time which is
+ /// 00:00:00 (midnight) January 1st, 1601.
+ /// @brief 00:00:00 Jan 1, 1601 UTC.
+ static const TimeValue Win32ZeroTime;
+
+ /// @}
+ /// @name Types
+ /// @{
+ public:
+ typedef int64_t SecondsType; ///< Type used for representing seconds.
+ typedef int32_t NanoSecondsType;///< Type used for representing nanoseconds.
+
+ enum TimeConversions {
+ NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion
+ MICROSECONDS_PER_SECOND = 1000000, ///< One Million
+ MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
+ NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
+ NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
+ };
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Caller provides the exact value in seconds and nanoseconds. The
+ /// \p nanos argument defaults to zero for convenience.
+ /// @brief Explicit constructor
+ explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
+ : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
+
+ /// Caller provides the exact value as a double in seconds with the
+ /// fractional part representing nanoseconds.
+ /// @brief Double Constructor.
+ explicit TimeValue( double new_time )
+ : seconds_( 0 ) , nanos_ ( 0 ) {
+ SecondsType integer_part = static_cast<SecondsType>( new_time );
+ seconds_ = integer_part;
+ nanos_ = static_cast<NanoSecondsType>( (new_time -
+ static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
+ this->normalize();
+ }
+
+ /// This is a static constructor that returns a TimeValue that represents
+ /// the current time.
+ /// @brief Creates a TimeValue with the current time (UTC).
+ static TimeValue now();
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Add \p that to \p this.
+ /// @returns this
+ /// @brief Incrementing assignment operator.
+ TimeValue& operator += (const TimeValue& that ) {
+ this->seconds_ += that.seconds_ ;
+ this->nanos_ += that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Subtract \p that from \p this.
+ /// @returns this
+ /// @brief Decrementing assignment operator.
+ TimeValue& operator -= (const TimeValue &that ) {
+ this->seconds_ -= that.seconds_ ;
+ this->nanos_ -= that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Determine if \p this is less than \p that.
+ /// @returns True iff *this < that.
+ /// @brief True if this < that.
+ int operator < (const TimeValue &that) const { return that > *this; }
+
+ /// Determine if \p this is greather than \p that.
+ /// @returns True iff *this > that.
+ /// @brief True if this > that.
+ int operator > (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ > that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determine if \p this is less than or equal to \p that.
+ /// @returns True iff *this <= that.
+ /// @brief True if this <= that.
+ int operator <= (const TimeValue &that) const { return that >= *this; }
+
+ /// Determine if \p this is greater than or equal to \p that.
+ /// @returns True iff *this >= that.
+ /// @brief True if this >= that.
+ int operator >= (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ >= that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determines if two TimeValue objects represent the same moment in time.
+ /// @brief True iff *this == that.
+ /// @brief True if this == that.
+ int operator == (const TimeValue &that) const {
+ return (this->seconds_ == that.seconds_) &&
+ (this->nanos_ == that.nanos_);
+ }
+
+ /// Determines if two TimeValue objects represent times that are not the
+ /// same.
+ /// @return True iff *this != that.
+ /// @brief True if this != that.
+ int operator != (const TimeValue &that) const { return !(*this == that); }
+
+ /// Adds two TimeValue objects together.
+ /// @returns The sum of the two operands as a new TimeValue
+ /// @brief Addition operator.
+ friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// Subtracts two TimeValue objects.
+ /// @returns The difference of the two operands as a new TimeValue
+ /// @brief Subtraction operator.
+ friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+
+ /// Returns only the seconds component of the TimeValue. The nanoseconds
+ /// portion is ignored. No rounding is performed.
+ /// @brief Retrieve the seconds component
+ SecondsType seconds() const { return seconds_; }
+
+ /// Returns only the nanoseconds component of the TimeValue. The seconds
+ /// portion is ignored.
+ /// @brief Retrieve the nanoseconds component.
+ NanoSecondsType nanoseconds() const { return nanos_; }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest microsecond (divide by one thousand).
+ /// @brief Retrieve the fractional part as microseconds;
+ uint32_t microseconds() const {
+ return nanos_ / NANOSECONDS_PER_MICROSECOND;
+ }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest millisecond (divide by one million).
+ /// @brief Retrieve the fractional part as milliseconds;
+ uint32_t milliseconds() const {
+ return nanos_ / NANOSECONDS_PER_MILLISECOND;
+ }
+
+ /// Returns the TimeValue as a number of microseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of microseconds (can overflow)
+ uint64_t usec() const {
+ return seconds_ * MICROSECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MICROSECOND );
+ }
+
+ /// Returns the TimeValue as a number of milliseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of milliseconds (can overflow)
+ uint64_t msec() const {
+ return seconds_ * MILLISECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MILLISECOND );
+ }
+
+ /// Converts the TimeValue into the corresponding number of "ticks" for
+ /// Posix, correcting for the difference in Posix zero time.
+ /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
+ uint64_t toPosixTime() const {
+ uint64_t result = seconds_ - PosixZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
+ return result;
+ }
+
+ /// Converts the TimeValue into the corresponding number of seconds
+ /// since the epoch (00:00:00 Jan 1,1970).
+ uint64_t toEpochTime() const {
+ return seconds_ - PosixZeroTime.seconds_;
+ }
+
+ /// Converts the TimeValue into the corresponding number of "ticks" for
+ /// Win32 platforms, correcting for the difference in Win32 zero time.
+ /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
+ uint64_t toWin32Time() const {
+ uint64_t result = seconds_ - Win32ZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
+ return result;
+ }
+
+ /// Provides the seconds and nanoseconds as results in its arguments after
+ /// correction for the Posix zero time.
+ /// @brief Convert to timespec time (ala POSIX.1b)
+ void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
+ seconds = seconds_ - PosixZeroTime.seconds_;
+ nanos = nanos_;
+ }
+
+ /// Provides conversion of the TimeValue into a readable time & date.
+ /// @returns std::string containing the readable time value
+ /// @brief Convert time to a string.
+ std::string str() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// The seconds component of the TimeValue is set to \p sec without
+ /// modifying the nanoseconds part. This is useful for whole second
+ /// arithmetic.
+ /// @brief Set the seconds component.
+ void seconds (SecondsType sec ) {
+ this->seconds_ = sec;
+ this->normalize();
+ }
+
+ /// The nanoseconds component of the TimeValue is set to \p nanos without
+ /// modifying the seconds part. This is useful for basic computations
+ /// involving just the nanoseconds portion. Note that the TimeValue will be
+ /// normalized after this call so that the fractional (nanoseconds) portion
+ /// will have the smallest equivalent value.
+ /// @brief Set the nanoseconds component using a number of nanoseconds.
+ void nanoseconds ( NanoSecondsType nanos ) {
+ this->nanos_ = nanos;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of microseconds.
+ void microseconds ( int32_t micros ) {
+ this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of milliseconds.
+ void milliseconds ( int32_t millis ) {
+ this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from microsecond format to TimeValue format
+ void usec( int64_t microseconds ) {
+ this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from millisecond format to TimeValue format
+ void msec( int64_t milliseconds ) {
+ this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// Converts the \p seconds argument from PosixTime to the corresponding
+ /// TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form PosixTime to TimeValue
+ void fromEpochTime( SecondsType seconds ) {
+ seconds_ = seconds + PosixZeroTime.seconds_;
+ nanos_ = 0;
+ this->normalize();
+ }
+
+ /// Converts the \p win32Time argument from Windows FILETIME to the
+ /// corresponding TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form Windows FILETIME to TimeValue
+ void fromWin32Time( uint64_t win32Time ) {
+ this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
+ this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
+ }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// This causes the values to be represented so that the fractional
+ /// part is minimized, possibly incrementing the seconds part.
+ /// @brief Normalize to canonical form.
+ void normalize();
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ /// Store the values as a <timeval>.
+ SecondsType seconds_;///< Stores the seconds part of the TimeVal
+ NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
+ /// @}
+
+ };
+
+inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
+ sum.normalize ();
+ return sum;
+}
+
+inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
+ difference.normalize ();
+ return difference;
+}
+
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Timer.h b/contrib/llvm/include/llvm/Support/Timer.h
new file mode 100644
index 000000000000..404cb6d6c8b6
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Timer.h
@@ -0,0 +1,194 @@
+//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- 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 three classes: Timer, TimeRegion, and TimerGroup,
+// documented below.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMER_H
+#define LLVM_SUPPORT_TIMER_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+#include <vector>
+#include <utility>
+
+namespace llvm {
+
+class Timer;
+class TimerGroup;
+class raw_ostream;
+
+class TimeRecord {
+ double WallTime; // Wall clock time elapsed in seconds
+ double UserTime; // User time elapsed
+ double SystemTime; // System time elapsed
+ ssize_t MemUsed; // Memory allocated (in bytes)
+public:
+ TimeRecord() : WallTime(0), UserTime(0), SystemTime(0), MemUsed(0) {}
+
+ /// getCurrentTime - Get the current time and memory usage. If Start is true
+ /// we get the memory usage before the time, otherwise we get time before
+ /// memory usage. This matters if the time to get the memory usage is
+ /// significant and shouldn't be counted as part of a duration.
+ static TimeRecord getCurrentTime(bool Start = true);
+
+ double getProcessTime() const { return UserTime+SystemTime; }
+ double getUserTime() const { return UserTime; }
+ double getSystemTime() const { return SystemTime; }
+ double getWallTime() const { return WallTime; }
+ ssize_t getMemUsed() const { return MemUsed; }
+
+
+ // operator< - Allow sorting.
+ bool operator<(const TimeRecord &T) const {
+ // Sort by Wall Time elapsed, as it is the only thing really accurate
+ return WallTime < T.WallTime;
+ }
+
+ void operator+=(const TimeRecord &RHS) {
+ WallTime += RHS.WallTime;
+ UserTime += RHS.UserTime;
+ SystemTime += RHS.SystemTime;
+ MemUsed += RHS.MemUsed;
+ }
+ void operator-=(const TimeRecord &RHS) {
+ WallTime -= RHS.WallTime;
+ UserTime -= RHS.UserTime;
+ SystemTime -= RHS.SystemTime;
+ MemUsed -= RHS.MemUsed;
+ }
+
+ /// print - Print the current timer to standard error, and reset the "Started"
+ /// flag.
+ void print(const TimeRecord &Total, raw_ostream &OS) const;
+};
+
+/// Timer - This class is used to track the amount of time spent between
+/// invocations of its startTimer()/stopTimer() methods. Given appropriate OS
+/// support it can also keep track of the RSS of the program at various points.
+/// By default, the Timer will print the amount of time it has captured to
+/// standard error when the laster timer is destroyed, otherwise it is printed
+/// when its TimerGroup is destroyed. Timers do not print their information
+/// if they are never started.
+///
+class Timer {
+ TimeRecord Time;
+ std::string Name; // The name of this time variable.
+ bool Started; // Has this time variable ever been started?
+ TimerGroup *TG; // The TimerGroup this Timer is in.
+
+ Timer **Prev, *Next; // Doubly linked list of timers in the group.
+public:
+ explicit Timer(StringRef N) : TG(0) { init(N); }
+ Timer(StringRef N, TimerGroup &tg) : TG(0) { init(N, tg); }
+ Timer(const Timer &RHS) : TG(0) {
+ assert(RHS.TG == 0 && "Can only copy uninitialized timers");
+ }
+ const Timer &operator=(const Timer &T) {
+ assert(TG == 0 && T.TG == 0 && "Can only assign uninit timers");
+ return *this;
+ }
+ ~Timer();
+
+ // Create an uninitialized timer, client must use 'init'.
+ explicit Timer() : TG(0) {}
+ void init(StringRef N);
+ void init(StringRef N, TimerGroup &tg);
+
+ const std::string &getName() const { return Name; }
+ bool isInitialized() const { return TG != 0; }
+
+ /// startTimer - Start the timer running. Time between calls to
+ /// startTimer/stopTimer is counted by the Timer class. Note that these calls
+ /// must be correctly paired.
+ ///
+ void startTimer();
+
+ /// stopTimer - Stop the timer.
+ ///
+ void stopTimer();
+
+private:
+ friend class TimerGroup;
+};
+
+
+/// The TimeRegion class is used as a helper class to call the startTimer() and
+/// stopTimer() methods of the Timer class. When the object is constructed, it
+/// starts the timer specified as it's argument. When it is destroyed, it stops
+/// the relevant timer. This makes it easy to time a region of code.
+///
+class TimeRegion {
+ Timer *T;
+ TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT
+public:
+ explicit TimeRegion(Timer &t) : T(&t) {
+ T->startTimer();
+ }
+ explicit TimeRegion(Timer *t) : T(t) {
+ if (T) T->startTimer();
+ }
+ ~TimeRegion() {
+ if (T) T->stopTimer();
+ }
+};
+
+
+/// NamedRegionTimer - This class is basically a combination of TimeRegion and
+/// Timer. It allows you to declare a new timer, AND specify the region to
+/// time, all in one statement. All timers with the same name are merged. This
+/// is primarily used for debugging and for hunting performance problems.
+///
+struct NamedRegionTimer : public TimeRegion {
+ explicit NamedRegionTimer(StringRef Name,
+ bool Enabled = true);
+ explicit NamedRegionTimer(StringRef Name, StringRef GroupName,
+ bool Enabled = true);
+};
+
+
+/// The TimerGroup class is used to group together related timers into a single
+/// report that is printed when the TimerGroup is destroyed. It is illegal to
+/// destroy a TimerGroup object before all of the Timers in it are gone. A
+/// TimerGroup can be specified for a newly created timer in its constructor.
+///
+class TimerGroup {
+ std::string Name;
+ Timer *FirstTimer; // First timer in the group.
+ 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
+public:
+ explicit TimerGroup(StringRef name);
+ ~TimerGroup();
+
+ void setName(StringRef name) { Name.assign(name.begin(), name.end()); }
+
+ /// print - Print any started timers in this group and zero them.
+ void print(raw_ostream &OS);
+
+ /// printAll - This static method prints all timers and clears them all out.
+ static void printAll(raw_ostream &OS);
+
+private:
+ friend class Timer;
+ void addTimer(Timer &T);
+ void removeTimer(Timer &T);
+ void PrintQueuedTimers(raw_ostream &OS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/ToolOutputFile.h b/contrib/llvm/include/llvm/Support/ToolOutputFile.h
new file mode 100644
index 000000000000..65b182a24535
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ToolOutputFile.h
@@ -0,0 +1,62 @@
+//===- ToolOutputFile.h - Output files for compiler-like tools -----------===//
+//
+// 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 tool_output_file class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TOOL_OUTPUT_FILE_H
+#define LLVM_SUPPORT_TOOL_OUTPUT_FILE_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+/// tool_output_file - This class contains a raw_fd_ostream and adds a
+/// few extra features commonly needed for compiler-like tool output files:
+/// - The file is automatically deleted if the process is killed.
+/// - The file is automatically deleted when the tool_output_file
+/// object is destroyed unless the client calls keep().
+class tool_output_file {
+ /// Installer - This class is declared before the raw_fd_ostream so that
+ /// it is constructed before the raw_fd_ostream is constructed and
+ /// destructed after the raw_fd_ostream is destructed. It installs
+ /// cleanups in its constructor and uninstalls them in its destructor.
+ class CleanupInstaller {
+ /// Filename - The name of the file.
+ std::string Filename;
+ public:
+ /// Keep - The flag which indicates whether we should not delete the file.
+ bool Keep;
+
+ explicit CleanupInstaller(const char *filename);
+ ~CleanupInstaller();
+ } Installer;
+
+ /// OS - The contained stream. This is intentionally declared after
+ /// Installer.
+ raw_fd_ostream OS;
+
+public:
+ /// tool_output_file - This constructor's arguments are passed to
+ /// to raw_fd_ostream's constructor.
+ tool_output_file(const char *filename, std::string &ErrorInfo,
+ unsigned Flags = 0);
+
+ /// os - Return the contained raw_fd_ostream.
+ raw_fd_ostream &os() { return OS; }
+
+ /// keep - Indicate that the tool's job wrt this output file has been
+ /// successful and the file should not be deleted.
+ void keep() { Installer.Keep = true; }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/TypeBuilder.h b/contrib/llvm/include/llvm/Support/TypeBuilder.h
new file mode 100644
index 000000000000..c75606917c1c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/TypeBuilder.h
@@ -0,0 +1,399 @@
+//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TypeBuilder class, which is used as a convenient way to
+// create LLVM types with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPEBUILDER_H
+#define LLVM_SUPPORT_TYPEBUILDER_H
+
+#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
+#include <limits.h>
+
+namespace llvm {
+
+/// TypeBuilder - This provides a uniform API for looking up types
+/// known at compile time. To support cross-compilation, we define a
+/// series of tag types in the llvm::types namespace, like i<N>,
+/// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be
+/// any of these, a native C type (whose size may depend on the host
+/// compiler), or a pointer, function, or struct type built out of
+/// these. TypeBuilder<T, true> removes native C types from this set
+/// to guarantee that its result is suitable for cross-compilation.
+/// We define the primitive types, pointer types, and functions up to
+/// 5 arguments here, but to use this class with your own types,
+/// you'll need to specialize it. For example, say you want to call a
+/// function defined externally as:
+///
+/// struct MyType {
+/// int32 a;
+/// int32 *b;
+/// void *array[1]; // Intended as a flexible array.
+/// };
+/// int8 AFunction(struct MyType *value);
+///
+/// You'll want to use
+/// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
+/// to declare the function, but when you first try this, your compiler will
+/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
+/// write:
+///
+/// namespace llvm {
+/// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
+/// public:
+/// static StructType *get(LLVMContext &Context) {
+/// // If you cache this result, be sure to cache it separately
+/// // for each LLVMContext.
+/// return StructType::get(
+/// TypeBuilder<types::i<32>, xcompile>::get(Context),
+/// TypeBuilder<types::i<32>*, xcompile>::get(Context),
+/// TypeBuilder<types::i<8>*[], xcompile>::get(Context),
+/// NULL);
+/// }
+///
+/// // You may find this a convenient place to put some constants
+/// // to help with getelementptr. They don't have any effect on
+/// // the operation of TypeBuilder.
+/// enum Fields {
+/// FIELD_A,
+/// FIELD_B,
+/// FIELD_ARRAY
+/// };
+/// }
+/// } // namespace llvm
+///
+/// TypeBuilder cannot handle recursive types or types you only know at runtime.
+/// If you try to give it a recursive type, it will deadlock, infinitely
+/// recurse, or do something similarly undesirable.
+template<typename T, bool cross_compilable> class TypeBuilder {};
+
+// Types for use with cross-compilable TypeBuilders. These correspond
+// exactly with an LLVM-native type.
+namespace types {
+/// i<N> corresponds to the LLVM IntegerType with N bits.
+template<uint32_t num_bits> class i {};
+
+// The following classes represent the LLVM floating types.
+class ieee_float {};
+class ieee_double {};
+class x86_fp80 {};
+class fp128 {};
+class ppc_fp128 {};
+// X86 MMX.
+class x86_mmx {};
+} // namespace types
+
+// LLVM doesn't have const or volatile types.
+template<typename T, bool cross> class TypeBuilder<const T, cross>
+ : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<volatile T, cross>
+ : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
+ : public TypeBuilder<T, cross> {};
+
+// Pointers
+template<typename T, bool cross> class TypeBuilder<T*, cross> {
+public:
+ static PointerType *get(LLVMContext &Context) {
+ return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
+ }
+};
+
+/// There is no support for references
+template<typename T, bool cross> class TypeBuilder<T&, cross> {};
+
+// Arrays
+template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
+public:
+ static ArrayType *get(LLVMContext &Context) {
+ return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
+ }
+};
+/// LLVM uses an array of length 0 to represent an unknown-length array.
+template<typename T, bool cross> class TypeBuilder<T[], cross> {
+public:
+ static ArrayType *get(LLVMContext &Context) {
+ return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
+ }
+};
+
+// Define the C integral types only for TypeBuilder<T, false>.
+//
+// C integral types do not have a defined size. It would be nice to use the
+// stdint.h-defined typedefs that do have defined sizes, but we'd run into the
+// following problem:
+//
+// On an ILP32 machine, stdint.h might define:
+//
+// typedef int int32_t;
+// typedef long long int64_t;
+// typedef long size_t;
+//
+// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
+// TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in
+// addition to the defined-size types because we'd get duplicate definitions on
+// platforms where stdint.h instead defines:
+//
+// typedef int int32_t;
+// typedef long long int64_t;
+// typedef int size_t;
+//
+// So we define all the primitive C types and nothing else.
+#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
+template<> class TypeBuilder<T, false> { \
+public: \
+ static IntegerType *get(LLVMContext &Context) { \
+ return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
+ } \
+}; \
+template<> class TypeBuilder<T, true> { \
+ /* We provide a definition here so users don't accidentally */ \
+ /* define these types to work. */ \
+}
+DEFINE_INTEGRAL_TYPEBUILDER(char);
+DEFINE_INTEGRAL_TYPEBUILDER(signed char);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
+DEFINE_INTEGRAL_TYPEBUILDER(short);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
+DEFINE_INTEGRAL_TYPEBUILDER(int);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
+DEFINE_INTEGRAL_TYPEBUILDER(long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
+#ifdef _MSC_VER
+DEFINE_INTEGRAL_TYPEBUILDER(__int64);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
+#else /* _MSC_VER */
+DEFINE_INTEGRAL_TYPEBUILDER(long long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
+#endif /* _MSC_VER */
+#undef DEFINE_INTEGRAL_TYPEBUILDER
+
+template<uint32_t num_bits, bool cross>
+class TypeBuilder<types::i<num_bits>, cross> {
+public:
+ static IntegerType *get(LLVMContext &C) {
+ return IntegerType::get(C, num_bits);
+ }
+};
+
+template<> class TypeBuilder<float, false> {
+public:
+ static Type *get(LLVMContext& C) {
+ return Type::getFloatTy(C);
+ }
+};
+template<> class TypeBuilder<float, true> {};
+
+template<> class TypeBuilder<double, false> {
+public:
+ static Type *get(LLVMContext& C) {
+ return Type::getDoubleTy(C);
+ }
+};
+template<> class TypeBuilder<double, true> {};
+
+template<bool cross> class TypeBuilder<types::ieee_float, cross> {
+public:
+ static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
+};
+template<bool cross> class TypeBuilder<types::ieee_double, cross> {
+public:
+ static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
+};
+template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
+public:
+ static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::fp128, cross> {
+public:
+ static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
+public:
+ static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
+public:
+ static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
+};
+
+template<bool cross> class TypeBuilder<void, cross> {
+public:
+ static Type *get(LLVMContext &C) {
+ return Type::getVoidTy(C);
+ }
+};
+
+/// void* is disallowed in LLVM types, but it occurs often enough in C code that
+/// we special case it.
+template<> class TypeBuilder<void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<volatile void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const volatile void*, false>
+ : public TypeBuilder<types::i<8>*, false> {};
+
+template<typename R, bool cross> class TypeBuilder<R(), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
+ }
+};
+template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
+ }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
+ }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ TypeBuilder<A3, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ bool cross>
+class TypeBuilder<R(A1, A2, A3, A4), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ TypeBuilder<A3, cross>::get(Context),
+ TypeBuilder<A4, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ TypeBuilder<A3, cross>::get(Context),
+ TypeBuilder<A4, cross>::get(Context),
+ TypeBuilder<A5, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, false);
+ }
+};
+
+template<typename R, bool cross> class TypeBuilder<R(...), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
+ }
+};
+template<typename R, typename A1, bool cross>
+class TypeBuilder<R(A1, ...), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
+ }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2, ...), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
+ }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3, ...), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ TypeBuilder<A3, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ TypeBuilder<A3, cross>::get(Context),
+ TypeBuilder<A4, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
+ }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+ typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
+public:
+ static FunctionType *get(LLVMContext &Context) {
+ Type *params[] = {
+ TypeBuilder<A1, cross>::get(Context),
+ TypeBuilder<A2, cross>::get(Context),
+ TypeBuilder<A3, cross>::get(Context),
+ TypeBuilder<A4, cross>::get(Context),
+ TypeBuilder<A5, cross>::get(Context),
+ };
+ return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+ params, true);
+ }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Valgrind.h b/contrib/llvm/include/llvm/Support/Valgrind.h
new file mode 100644
index 000000000000..e14764703932
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Valgrind.h
@@ -0,0 +1,75 @@
+//===- llvm/Support/Valgrind.h - Communication with Valgrind -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods for communicating with a valgrind instance this program is running
+// under. These are all no-ops unless LLVM was configured on a system with the
+// valgrind headers installed and valgrind is controlling this process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_VALGRIND_H
+#define LLVM_SYSTEM_VALGRIND_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Config/llvm-config.h"
+#include <stddef.h>
+
+#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
+// tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact
+// functions by name.
+extern "C" {
+LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line,
+ const volatile void *cv);
+LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line,
+ const volatile void *cv);
+LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line);
+LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
+}
+#endif
+
+namespace llvm {
+namespace sys {
+ // True if Valgrind is controlling this process.
+ bool RunningOnValgrind();
+
+ // Discard valgrind's translation of code in the range [Addr .. Addr + Len).
+ // Otherwise valgrind may continue to execute the old version of the code.
+ void ValgrindDiscardTranslations(const void *Addr, size_t Len);
+
+#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
+ // Thread Sanitizer is a valgrind tool that finds races in code.
+ // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
+
+ // This marker is used to define a happens-before arc. The race detector will
+ // infer an arc from the begin to the end when they share the same pointer
+ // argument.
+ #define TsanHappensBefore(cv) \
+ AnnotateHappensBefore(__FILE__, __LINE__, cv)
+
+ // This marker defines the destination of a happens-before arc.
+ #define TsanHappensAfter(cv) \
+ AnnotateHappensAfter(__FILE__, __LINE__, cv)
+
+ // Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
+ #define TsanIgnoreWritesBegin() \
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
+
+ // Resume checking for racy writes.
+ #define TsanIgnoreWritesEnd() \
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
+#else
+ #define TsanHappensBefore(cv)
+ #define TsanHappensAfter(cv)
+ #define TsanIgnoreWritesBegin()
+ #define TsanIgnoreWritesEnd()
+#endif
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/ValueHandle.h b/contrib/llvm/include/llvm/Support/ValueHandle.h
new file mode 100644
index 000000000000..b7210b2063ea
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/ValueHandle.h
@@ -0,0 +1,417 @@
+//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ValueHandle class and its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_VALUEHANDLE_H
+#define LLVM_SUPPORT_VALUEHANDLE_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Value.h"
+
+namespace llvm {
+class ValueHandleBase;
+
+// ValueHandleBase** is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<ValueHandleBase**> {
+public:
+ static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; }
+ static inline ValueHandleBase **getFromVoidPointer(void *P) {
+ return static_cast<ValueHandleBase**>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+
+/// ValueHandleBase - This is the common base class of value handles.
+/// ValueHandle's are smart pointers to Value's that have special behavior when
+/// the value is deleted or ReplaceAllUsesWith'd. See the specific handles
+/// below for details.
+///
+class ValueHandleBase {
+ friend class Value;
+protected:
+ /// HandleBaseKind - This indicates what sub class the handle actually is.
+ /// This is to avoid having a vtable for the light-weight handle pointers. The
+ /// fully general Callback version does have a vtable.
+ enum HandleBaseKind {
+ Assert,
+ Callback,
+ Tracking,
+ Weak
+ };
+
+private:
+ PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
+ ValueHandleBase *Next;
+
+ // A subclass may want to store some information along with the value
+ // pointer. Allow them to do this by making the value pointer a pointer-int
+ // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this
+ // access.
+ PointerIntPair<Value*, 2> VP;
+
+ explicit ValueHandleBase(const ValueHandleBase&); // DO NOT IMPLEMENT.
+public:
+ explicit ValueHandleBase(HandleBaseKind Kind)
+ : PrevPair(0, Kind), Next(0), VP(0, 0) {}
+ ValueHandleBase(HandleBaseKind Kind, Value *V)
+ : PrevPair(0, Kind), Next(0), VP(V, 0) {
+ if (isValid(VP.getPointer()))
+ AddToUseList();
+ }
+ ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
+ : PrevPair(0, Kind), Next(0), VP(RHS.VP) {
+ if (isValid(VP.getPointer()))
+ AddToExistingUseList(RHS.getPrevPtr());
+ }
+ ~ValueHandleBase() {
+ if (isValid(VP.getPointer()))
+ RemoveFromUseList();
+ }
+
+ Value *operator=(Value *RHS) {
+ if (VP.getPointer() == RHS) return RHS;
+ if (isValid(VP.getPointer())) RemoveFromUseList();
+ VP.setPointer(RHS);
+ if (isValid(VP.getPointer())) AddToUseList();
+ return RHS;
+ }
+
+ Value *operator=(const ValueHandleBase &RHS) {
+ if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer();
+ if (isValid(VP.getPointer())) RemoveFromUseList();
+ VP.setPointer(RHS.VP.getPointer());
+ if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr());
+ return VP.getPointer();
+ }
+
+ Value *operator->() const { return getValPtr(); }
+ Value &operator*() const { return *getValPtr(); }
+
+protected:
+ Value *getValPtr() const { return VP.getPointer(); }
+
+ void setValPtrInt(unsigned K) { VP.setInt(K); }
+ unsigned getValPtrInt() const { return VP.getInt(); }
+
+ static bool isValid(Value *V) {
+ return V &&
+ V != DenseMapInfo<Value *>::getEmptyKey() &&
+ V != DenseMapInfo<Value *>::getTombstoneKey();
+ }
+
+private:
+ // Callbacks made from Value.
+ static void ValueIsDeleted(Value *V);
+ static void ValueIsRAUWd(Value *Old, Value *New);
+
+ // Internal implementation details.
+ ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
+ HandleBaseKind getKind() const { return PrevPair.getInt(); }
+ void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
+
+ /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
+ /// List is the address of either the head of the list or a Next node within
+ /// the existing use list.
+ void AddToExistingUseList(ValueHandleBase **List);
+
+ /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
+ /// Node.
+ void AddToExistingUseListAfter(ValueHandleBase *Node);
+
+ /// AddToUseList - Add this ValueHandle to the use list for VP.
+ void AddToUseList();
+ /// RemoveFromUseList - Remove this ValueHandle from its current use list.
+ void RemoveFromUseList();
+};
+
+/// WeakVH - This is a value handle that tries hard to point to a Value, even
+/// across RAUW operations, but will null itself out if the value is destroyed.
+/// this is useful for advisory sorts of information, but should not be used as
+/// the key of a map (since the map would have to rearrange itself when the
+/// pointer changes).
+class WeakVH : public ValueHandleBase {
+public:
+ WeakVH() : ValueHandleBase(Weak) {}
+ WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
+ WeakVH(const WeakVH &RHS)
+ : ValueHandleBase(Weak, RHS) {}
+
+ Value *operator=(Value *RHS) {
+ return ValueHandleBase::operator=(RHS);
+ }
+ Value *operator=(const ValueHandleBase &RHS) {
+ return ValueHandleBase::operator=(RHS);
+ }
+
+ operator Value*() const {
+ return getValPtr();
+ }
+};
+
+// Specialize simplify_type to allow WeakVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const WeakVH> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const WeakVH &WVH) {
+ return static_cast<Value *>(WVH);
+ }
+};
+template<> struct simplify_type<WeakVH> : public simplify_type<const WeakVH> {};
+
+/// AssertingVH - This is a Value Handle that points to a value and asserts out
+/// if the value is destroyed while the handle is still live. This is very
+/// useful for catching dangling pointer bugs and other things which can be
+/// non-obvious. One particularly useful place to use this is as the Key of a
+/// map. Dangling pointer bugs often lead to really subtle bugs that only occur
+/// if another object happens to get allocated to the same address as the old
+/// one. Using an AssertingVH ensures that an assert is triggered as soon as
+/// the bad delete occurs.
+///
+/// Note that an AssertingVH handle does *not* follow values across RAUW
+/// operations. This means that RAUW's need to explicitly update the
+/// AssertingVH's as it moves. This is required because in non-assert mode this
+/// class turns into a trivial wrapper around a pointer.
+template <typename ValueTy>
+class AssertingVH
+#ifndef NDEBUG
+ : public ValueHandleBase
+#endif
+ {
+
+#ifndef NDEBUG
+ ValueTy *getValPtr() const {
+ return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
+ }
+ void setValPtr(ValueTy *P) {
+ ValueHandleBase::operator=(GetAsValue(P));
+ }
+#else
+ ValueTy *ThePtr;
+ ValueTy *getValPtr() const { return ThePtr; }
+ void setValPtr(ValueTy *P) { ThePtr = P; }
+#endif
+
+ // Convert a ValueTy*, which may be const, to the type the base
+ // class expects.
+ static Value *GetAsValue(Value *V) { return V; }
+ static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
+
+public:
+#ifndef NDEBUG
+ AssertingVH() : ValueHandleBase(Assert) {}
+ AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
+ AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
+#else
+ AssertingVH() : ThePtr(0) {}
+ AssertingVH(ValueTy *P) : ThePtr(P) {}
+#endif
+
+ operator ValueTy*() const {
+ return getValPtr();
+ }
+
+ ValueTy *operator=(ValueTy *RHS) {
+ setValPtr(RHS);
+ return getValPtr();
+ }
+ ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
+ setValPtr(RHS.getValPtr());
+ return getValPtr();
+ }
+
+ ValueTy *operator->() const { return getValPtr(); }
+ ValueTy &operator*() const { return *getValPtr(); }
+};
+
+// Specialize simplify_type to allow AssertingVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const AssertingVH<Value> > {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const AssertingVH<Value> &AVH) {
+ return static_cast<Value *>(AVH);
+ }
+};
+template<> struct simplify_type<AssertingVH<Value> >
+ : public simplify_type<const AssertingVH<Value> > {};
+
+// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
+template<typename T>
+struct DenseMapInfo<AssertingVH<T> > {
+ typedef DenseMapInfo<T*> PointerInfo;
+ static inline AssertingVH<T> getEmptyKey() {
+ return AssertingVH<T>(PointerInfo::getEmptyKey());
+ }
+ static inline T* getTombstoneKey() {
+ return AssertingVH<T>(PointerInfo::getTombstoneKey());
+ }
+ static unsigned getHashValue(const AssertingVH<T> &Val) {
+ return PointerInfo::getHashValue(Val);
+ }
+ static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
+ return LHS == RHS;
+ }
+};
+
+template <typename T>
+struct isPodLike<AssertingVH<T> > {
+#ifdef NDEBUG
+ static const bool value = true;
+#else
+ static const bool value = false;
+#endif
+};
+
+
+/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
+/// even across RAUW operations.
+///
+/// TrackingVH is designed for situations where a client needs to hold a handle
+/// to a Value (or subclass) across some operations which may move that value,
+/// but should never destroy it or replace it with some unacceptable type.
+///
+/// It is an error to do anything with a TrackingVH whose value has been
+/// destroyed, except to destruct it.
+///
+/// It is an error to attempt to replace a value with one of a type which is
+/// incompatible with any of its outstanding TrackingVHs.
+template<typename ValueTy>
+class TrackingVH : public ValueHandleBase {
+ void CheckValidity() const {
+ Value *VP = ValueHandleBase::getValPtr();
+
+ // Null is always ok.
+ if (!VP) return;
+
+ // Check that this value is valid (i.e., it hasn't been deleted). We
+ // explicitly delay this check until access to avoid requiring clients to be
+ // unnecessarily careful w.r.t. destruction.
+ assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
+
+ // Check that the value is a member of the correct subclass. We would like
+ // to check this property on assignment for better debugging, but we don't
+ // want to require a virtual interface on this VH. Instead we allow RAUW to
+ // replace this value with a value of an invalid type, and check it here.
+ assert(isa<ValueTy>(VP) &&
+ "Tracked Value was replaced by one with an invalid type!");
+ }
+
+ ValueTy *getValPtr() const {
+ CheckValidity();
+ return (ValueTy*)ValueHandleBase::getValPtr();
+ }
+ void setValPtr(ValueTy *P) {
+ CheckValidity();
+ ValueHandleBase::operator=(GetAsValue(P));
+ }
+
+ // Convert a ValueTy*, which may be const, to the type the base
+ // class expects.
+ static Value *GetAsValue(Value *V) { return V; }
+ static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
+
+public:
+ TrackingVH() : ValueHandleBase(Tracking) {}
+ TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
+ TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
+
+ operator ValueTy*() const {
+ return getValPtr();
+ }
+
+ ValueTy *operator=(ValueTy *RHS) {
+ setValPtr(RHS);
+ return getValPtr();
+ }
+ ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
+ setValPtr(RHS.getValPtr());
+ return getValPtr();
+ }
+
+ ValueTy *operator->() const { return getValPtr(); }
+ ValueTy &operator*() const { return *getValPtr(); }
+};
+
+// Specialize simplify_type to allow TrackingVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const TrackingVH<Value> > {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) {
+ return static_cast<Value *>(AVH);
+ }
+};
+template<> struct simplify_type<TrackingVH<Value> >
+ : public simplify_type<const TrackingVH<Value> > {};
+
+/// CallbackVH - This is a value handle that allows subclasses to define
+/// callbacks that run when the underlying Value has RAUW called on it or is
+/// destroyed. This class can be used as the key of a map, as long as the user
+/// takes it out of the map before calling setValPtr() (since the map has to
+/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this
+/// class has a vtable and a virtual destructor.
+class CallbackVH : public ValueHandleBase {
+protected:
+ CallbackVH(const CallbackVH &RHS)
+ : ValueHandleBase(Callback, RHS) {}
+
+ virtual ~CallbackVH();
+
+ void setValPtr(Value *P) {
+ ValueHandleBase::operator=(P);
+ }
+
+public:
+ CallbackVH() : ValueHandleBase(Callback) {}
+ CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
+
+ operator Value*() const {
+ return getValPtr();
+ }
+
+ /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may
+ /// call any non-virtual Value method on getValPtr(), but no subclass methods.
+ /// If WeakVH were implemented as a CallbackVH, it would use this method to
+ /// call setValPtr(NULL). AssertingVH would use this method to cause an
+ /// assertion failure.
+ ///
+ /// All implementations must remove the reference from this object to the
+ /// Value that's being destroyed.
+ virtual void deleted() {
+ setValPtr(NULL);
+ }
+
+ /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
+ /// _before_ any of the uses have actually been replaced. If WeakVH were
+ /// implemented as a CallbackVH, it would use this method to call
+ /// setValPtr(new_value). AssertingVH would do nothing in this method.
+ virtual void allUsesReplacedWith(Value *) {}
+};
+
+// Specialize simplify_type to allow CallbackVH to participate in
+// dyn_cast, isa, etc.
+template<typename From> struct simplify_type;
+template<> struct simplify_type<const CallbackVH> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const CallbackVH &CVH) {
+ return static_cast<Value *>(CVH);
+ }
+};
+template<> struct simplify_type<CallbackVH>
+ : public simplify_type<const CallbackVH> {};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/Win64EH.h b/contrib/llvm/include/llvm/Support/Win64EH.h
new file mode 100644
index 000000000000..8d74e10be003
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/Win64EH.h
@@ -0,0 +1,100 @@
+//===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants and structures used for implementing
+// exception handling on Win64 platforms. For more information, see
+// http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_WIN64EH_H
+#define LLVM_SUPPORT_WIN64EH_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+namespace Win64EH {
+
+/// UnwindOpcodes - Enumeration whose values specify a single operation in
+/// the prolog of a function.
+enum UnwindOpcodes {
+ UOP_PushNonVol = 0,
+ UOP_AllocLarge,
+ UOP_AllocSmall,
+ UOP_SetFPReg,
+ UOP_SaveNonVol,
+ UOP_SaveNonVolBig,
+ UOP_SaveXMM128 = 8,
+ UOP_SaveXMM128Big,
+ UOP_PushMachFrame
+};
+
+/// UnwindCode - This union describes a single operation in a function prolog,
+/// or part thereof.
+union UnwindCode {
+ struct {
+ uint8_t codeOffset;
+ uint8_t unwindOp:4,
+ opInfo:4;
+ } u;
+ uint16_t frameOffset;
+};
+
+enum {
+ /// UNW_ExceptionHandler - Specifies that this function has an exception
+ /// handler.
+ UNW_ExceptionHandler = 0x01,
+ /// UNW_TerminateHandler - Specifies that this function has a termination
+ /// handler.
+ UNW_TerminateHandler = 0x02,
+ /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
+ /// another one.
+ UNW_ChainInfo = 0x04
+};
+
+/// RuntimeFunction - An entry in the table of functions with unwind info.
+struct RuntimeFunction {
+ uint64_t startAddress;
+ uint64_t endAddress;
+ uint64_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];
+
+ void *getLanguageSpecificData() {
+ return reinterpret_cast<void *>(&unwindCodes[(numCodes+1) & ~1]);
+ }
+ uint64_t getLanguageSpecificHandlerOffset() {
+ return *reinterpret_cast<uint64_t *>(getLanguageSpecificData());
+ }
+ void setLanguageSpecificHandlerOffset(uint64_t offset) {
+ *reinterpret_cast<uint64_t *>(getLanguageSpecificData()) = offset;
+ }
+ RuntimeFunction *getChainedFunctionEntry() {
+ return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
+ }
+ void *getExceptionData() {
+ return reinterpret_cast<void *>(reinterpret_cast<uint64_t *>(
+ getLanguageSpecificData())+1);
+ }
+};
+
+
+} // End of namespace Win64EH
+} // End of namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm/include/llvm/Support/YAMLParser.h
new file mode 100644
index 000000000000..47206b3c6d9d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/YAMLParser.h
@@ -0,0 +1,552 @@
+//===--- YAMLParser.h - Simple YAML parser --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a YAML 1.2 parser.
+//
+// See http://www.yaml.org/spec/1.2/spec.html for the full standard.
+//
+// This currently does not implement the following:
+// * Multi-line literal folding.
+// * Tag resolution.
+// * UTF-16.
+// * BOMs anywhere other than the first Unicode scalar value in the file.
+//
+// The most important class here is Stream. This represents a YAML stream with
+// 0, 1, or many documents.
+//
+// SourceMgr sm;
+// StringRef input = getInput();
+// yaml::Stream stream(input, sm);
+//
+// for (yaml::document_iterator di = stream.begin(), de = stream.end();
+// di != de; ++di) {
+// yaml::Node *n = di->getRoot();
+// if (n) {
+// // Do something with n...
+// } else
+// break;
+// }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_YAML_PARSER_H
+#define LLVM_SUPPORT_YAML_PARSER_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/SMLoc.h"
+
+#include <limits>
+#include <utility>
+
+namespace llvm {
+class MemoryBuffer;
+class SourceMgr;
+class raw_ostream;
+class Twine;
+
+namespace yaml {
+
+class document_iterator;
+class Document;
+class Node;
+class Scanner;
+struct Token;
+
+/// @brief Dump all the tokens in this stream to OS.
+/// @returns true if there was an error, false otherwise.
+bool dumpTokens(StringRef Input, raw_ostream &);
+
+/// @brief Scans all tokens in input without outputting anything. This is used
+/// for benchmarking the tokenizer.
+/// @returns true if there was an error, false otherwise.
+bool scanTokens(StringRef Input);
+
+/// @brief Escape \a Input for a double quoted scalar.
+std::string escape(StringRef Input);
+
+/// @brief This class represents a YAML stream potentially containing multiple
+/// documents.
+class Stream {
+public:
+ Stream(StringRef Input, SourceMgr &);
+ ~Stream();
+
+ document_iterator begin();
+ document_iterator end();
+ void skip();
+ bool failed();
+ bool validate() {
+ skip();
+ return !failed();
+ }
+
+ void printError(Node *N, const Twine &Msg);
+
+private:
+ OwningPtr<Scanner> scanner;
+ OwningPtr<Document> CurrentDoc;
+
+ friend class Document;
+
+ /// @brief Validate a %YAML x.x directive.
+ void handleYAMLDirective(const Token &);
+};
+
+/// @brief Abstract base class for all Nodes.
+class Node {
+public:
+ enum NodeKind {
+ NK_Null,
+ NK_Scalar,
+ NK_KeyValue,
+ NK_Mapping,
+ NK_Sequence,
+ NK_Alias
+ };
+
+ Node(unsigned int Type, OwningPtr<Document>&, StringRef Anchor);
+
+ /// @brief Get the value of the anchor attached to this node. If it does not
+ /// have one, getAnchor().size() will be 0.
+ StringRef getAnchor() const { return Anchor; }
+
+ SMRange getSourceRange() const { return SourceRange; }
+ void setSourceRange(SMRange SR) { SourceRange = SR; }
+
+ // These functions forward to Document and Scanner.
+ Token &peekNext();
+ Token getNext();
+ Node *parseBlockNode();
+ BumpPtrAllocator &getAllocator();
+ void setError(const Twine &Message, Token &Location) const;
+ bool failed() const;
+
+ 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
+ , size_t Alignment = 16) throw() {
+ return Alloc.Allocate(Size, Alignment);
+ }
+
+ void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t) throw() {
+ Alloc.Deallocate(Ptr);
+ }
+
+protected:
+ OwningPtr<Document> &Doc;
+ SMRange SourceRange;
+
+ void operator delete(void *) throw() {}
+
+ virtual ~Node() {}
+
+private:
+ unsigned int TypeID;
+ StringRef Anchor;
+};
+
+/// @brief A null value.
+///
+/// Example:
+/// !!null null
+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;
+ }
+};
+
+/// @brief A scalar node is an opaque datum that can be presented as a
+/// series of zero or more Unicode scalar values.
+///
+/// Example:
+/// Adena
+class ScalarNode : public Node {
+public:
+ ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Val)
+ : Node(NK_Scalar, D, Anchor)
+ , Value(Val) {
+ SMLoc Start = SMLoc::getFromPointer(Val.begin());
+ SMLoc End = SMLoc::getFromPointer(Val.end() - 1);
+ SourceRange = SMRange(Start, End);
+ }
+
+ // Return Value without any escaping or folding or other fun YAML stuff. This
+ // is the exact bytes that are contained in the file (after conversion to
+ // utf8).
+ StringRef getRawValue() const { return Value; }
+
+ /// @brief Gets the value of this node as a StringRef.
+ ///
+ /// @param Storage is used to store the content of the returned StringRef iff
+ /// it requires any modification from how it appeared in the source.
+ /// 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;
+ }
+
+private:
+ StringRef Value;
+
+ StringRef unescapeDoubleQuoted( StringRef UnquotedValue
+ , StringRef::size_type Start
+ , SmallVectorImpl<char> &Storage) const;
+};
+
+/// @brief A key and value pair. While not technically a Node under the YAML
+/// representation graph, it is easier to treat them this way.
+///
+/// TODO: Consider making this not a child of Node.
+///
+/// Example:
+/// Section: .text
+class KeyValueNode : public Node {
+public:
+ KeyValueNode(OwningPtr<Document> &D)
+ : Node(NK_KeyValue, D, StringRef())
+ , Key(0)
+ , Value(0)
+ {}
+
+ /// @brief Parse and return the key.
+ ///
+ /// This may be called multiple times.
+ ///
+ /// @returns The key, or nullptr if failed() == true.
+ Node *getKey();
+
+ /// @brief Parse and return the value.
+ ///
+ /// This may be called multiple times.
+ ///
+ /// @returns The value, or nullptr if failed() == true.
+ Node *getValue();
+
+ virtual void skip() {
+ getKey()->skip();
+ getValue()->skip();
+ }
+
+ static inline bool classof(const KeyValueNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_KeyValue;
+ }
+
+private:
+ Node *Key;
+ Node *Value;
+};
+
+/// @brief This is an iterator abstraction over YAML collections shared by both
+/// sequences and maps.
+///
+/// BaseT must have a ValueT* member named CurrentEntry and a member function
+/// increment() which must set CurrentEntry to 0 to create an end iterator.
+template <class BaseT, class ValueT>
+class basic_collection_iterator
+ : public std::iterator<std::forward_iterator_tag, ValueT> {
+public:
+ basic_collection_iterator() : Base(0) {}
+ basic_collection_iterator(BaseT *B) : Base(B) {}
+
+ ValueT *operator ->() const {
+ assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
+ return Base->CurrentEntry;
+ }
+
+ ValueT &operator *() const {
+ assert(Base && Base->CurrentEntry &&
+ "Attempted to dereference end iterator!");
+ return *Base->CurrentEntry;
+ }
+
+ operator ValueT*() const {
+ assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
+ return Base->CurrentEntry;
+ }
+
+ bool operator !=(const basic_collection_iterator &Other) const {
+ if(Base != Other.Base)
+ return true;
+ return (Base && Other.Base) && Base->CurrentEntry
+ != Other.Base->CurrentEntry;
+ }
+
+ basic_collection_iterator &operator++() {
+ assert(Base && "Attempted to advance iterator past end!");
+ Base->increment();
+ // Create an end iterator.
+ if (Base->CurrentEntry == 0)
+ Base = 0;
+ return *this;
+ }
+
+private:
+ BaseT *Base;
+};
+
+// The following two templates are used for both MappingNode and Sequence Node.
+template <class CollectionType>
+typename CollectionType::iterator begin(CollectionType &C) {
+ assert(C.IsAtBeginning && "You may only iterate over a collection once!");
+ C.IsAtBeginning = false;
+ typename CollectionType::iterator ret(&C);
+ ++ret;
+ return ret;
+}
+
+template <class CollectionType>
+void skip(CollectionType &C) {
+ // TODO: support skipping from the middle of a parsed collection ;/
+ assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
+ if (C.IsAtBeginning)
+ for (typename CollectionType::iterator i = begin(C), e = C.end();
+ i != e; ++i)
+ i->skip();
+}
+
+/// @brief Represents a YAML map created from either a block map for a flow map.
+///
+/// This parses the YAML stream as increment() is called.
+///
+/// Example:
+/// Name: _main
+/// Scope: Global
+class MappingNode : public Node {
+public:
+ enum MappingType {
+ MT_Block,
+ MT_Flow,
+ MT_Inline //< An inline mapping node is used for "[key: value]".
+ };
+
+ MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT)
+ : Node(NK_Mapping, D, Anchor)
+ , Type(MT)
+ , IsAtBeginning(true)
+ , IsAtEnd(false)
+ , CurrentEntry(0)
+ {}
+
+ friend class basic_collection_iterator<MappingNode, KeyValueNode>;
+ typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
+ template <class T> friend typename T::iterator yaml::begin(T &);
+ template <class T> friend void yaml::skip(T &);
+
+ iterator begin() {
+ return yaml::begin(*this);
+ }
+
+ iterator end() { return iterator(); }
+
+ virtual void skip() {
+ yaml::skip(*this);
+ }
+
+ static inline bool classof(const MappingNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Mapping;
+ }
+
+private:
+ MappingType Type;
+ bool IsAtBeginning;
+ bool IsAtEnd;
+ KeyValueNode *CurrentEntry;
+
+ void increment();
+};
+
+/// @brief Represents a YAML sequence created from either a block sequence for a
+/// flow sequence.
+///
+/// This parses the YAML stream as increment() is called.
+///
+/// Example:
+/// - Hello
+/// - World
+class SequenceNode : public Node {
+public:
+ enum SequenceType {
+ ST_Block,
+ ST_Flow,
+ // Use for:
+ //
+ // key:
+ // - val1
+ // - val2
+ //
+ // As a BlockMappingEntry and BlockEnd are not created in this case.
+ ST_Indentless
+ };
+
+ SequenceNode(OwningPtr<Document> &D, StringRef Anchor, SequenceType ST)
+ : Node(NK_Sequence, D, Anchor)
+ , SeqType(ST)
+ , IsAtBeginning(true)
+ , IsAtEnd(false)
+ , WasPreviousTokenFlowEntry(true) // Start with an imaginary ','.
+ , CurrentEntry(0)
+ {}
+
+ friend class basic_collection_iterator<SequenceNode, Node>;
+ typedef basic_collection_iterator<SequenceNode, Node> iterator;
+ template <class T> friend typename T::iterator yaml::begin(T &);
+ template <class T> friend void yaml::skip(T &);
+
+ void increment();
+
+ iterator begin() {
+ return yaml::begin(*this);
+ }
+
+ iterator end() { return iterator(); }
+
+ virtual void skip() {
+ yaml::skip(*this);
+ }
+
+ static inline bool classof(const SequenceNode *) { return true; }
+ static inline bool classof(const Node *N) {
+ return N->getType() == NK_Sequence;
+ }
+
+private:
+ SequenceType SeqType;
+ bool IsAtBeginning;
+ bool IsAtEnd;
+ bool WasPreviousTokenFlowEntry;
+ Node *CurrentEntry;
+};
+
+/// @brief Represents an alias to a Node with an anchor.
+///
+/// Example:
+/// *AnchorName
+class AliasNode : public Node {
+public:
+ AliasNode(OwningPtr<Document> &D, StringRef Val)
+ : Node(NK_Alias, D, StringRef()), Name(Val) {}
+
+ 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;
+ }
+
+private:
+ StringRef Name;
+};
+
+/// @brief A YAML Stream is a sequence of Documents. A document contains a root
+/// node.
+class Document {
+public:
+ /// @brief Root for parsing a node. Returns a single node.
+ Node *parseBlockNode();
+
+ Document(Stream &ParentStream);
+
+ /// @brief Finish parsing the current document and return true if there are
+ /// more. Return false otherwise.
+ bool skip();
+
+ /// @brief Parse and return the root level node.
+ Node *getRoot() {
+ if (Root)
+ return Root;
+ return Root = parseBlockNode();
+ }
+
+private:
+ friend class Node;
+ friend class document_iterator;
+
+ /// @brief Stream to read tokens from.
+ Stream &stream;
+
+ /// @brief Used to allocate nodes to. All are destroyed without calling their
+ /// destructor when the document is destroyed.
+ BumpPtrAllocator NodeAllocator;
+
+ /// @brief The root node. Used to support skipping a partially parsed
+ /// document.
+ Node *Root;
+
+ Token &peekNext();
+ Token getNext();
+ void setError(const Twine &Message, Token &Location) const;
+ bool failed() const;
+
+ void handleTagDirective(const Token &Tag) {
+ // TODO: Track tags.
+ }
+
+ /// @brief Parse %BLAH directives and return true if any were encountered.
+ bool parseDirectives();
+
+ /// @brief Consume the next token and error if it is not \a TK.
+ bool expectToken(int TK);
+};
+
+/// @brief Iterator abstraction for Documents over a Stream.
+class document_iterator {
+public:
+ document_iterator() : Doc(NullDoc) {}
+ document_iterator(OwningPtr<Document> &D) : Doc(D) {}
+
+ bool operator ==(const document_iterator &Other) {
+ return Doc == Other.Doc;
+ }
+ bool operator !=(const document_iterator &Other) {
+ return !(*this == Other);
+ }
+
+ document_iterator operator ++() {
+ if (!Doc->skip()) {
+ Doc.reset(0);
+ } else {
+ Stream &S = Doc->stream;
+ Doc.reset(new Document(S));
+ }
+ return *this;
+ }
+
+ Document &operator *() {
+ return *Doc;
+ }
+
+ OwningPtr<Document> &operator ->() {
+ return Doc;
+ }
+
+private:
+ static OwningPtr<Document> NullDoc;
+ OwningPtr<Document> &Doc;
+};
+
+}
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/circular_raw_ostream.h b/contrib/llvm/include/llvm/Support/circular_raw_ostream.h
new file mode 100644
index 000000000000..2b3c329b5861
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/circular_raw_ostream.h
@@ -0,0 +1,171 @@
+//===-- llvm/Support/circular_raw_ostream.h - Buffered streams --*- 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 raw_ostream implementations for streams to do circular
+// buffering of their output.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H
+#define LLVM_SUPPORT_CIRCULAR_RAW_OSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm
+{
+ /// circular_raw_ostream - A raw_ostream which *can* save its data
+ /// to a circular buffer, or can pass it through directly to an
+ /// underlying stream if specified with a buffer of zero.
+ ///
+ class circular_raw_ostream : public raw_ostream {
+ public:
+ /// TAKE_OWNERSHIP - Tell this stream that it owns the underlying
+ /// stream and is responsible for cleanup, memory management
+ /// issues, etc.
+ ///
+ static const bool TAKE_OWNERSHIP = true;
+
+ /// REFERENCE_ONLY - Tell this stream it should not manage the
+ /// held stream.
+ ///
+ static const bool REFERENCE_ONLY = false;
+
+ private:
+ /// TheStream - The real stream we output to. We set it to be
+ /// unbuffered, since we're already doing our own buffering.
+ ///
+ raw_ostream *TheStream;
+
+ /// OwnsStream - Are we responsible for managing the underlying
+ /// stream?
+ ///
+ bool OwnsStream;
+
+ /// BufferSize - The size of the buffer in bytes.
+ ///
+ size_t BufferSize;
+
+ /// BufferArray - The actual buffer storage.
+ ///
+ char *BufferArray;
+
+ /// Cur - Pointer to the current output point in BufferArray.
+ ///
+ char *Cur;
+
+ /// Filled - Indicate whether the buffer has been completely
+ /// filled. This helps avoid garbage output.
+ ///
+ bool Filled;
+
+ /// Banner - A pointer to a banner to print before dumping the
+ /// log.
+ ///
+ const char *Banner;
+
+ /// flushBuffer - Dump the contents of the buffer to Stream.
+ ///
+ void flushBuffer(void) {
+ if (Filled)
+ // Write the older portion of the buffer.
+ TheStream->write(Cur, BufferArray + BufferSize - Cur);
+ // Write the newer portion of the buffer.
+ TheStream->write(BufferArray, Cur - BufferArray);
+ Cur = BufferArray;
+ Filled = false;
+ }
+
+ virtual void write_impl(const char *Ptr, size_t Size);
+
+ /// 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();
+ }
+
+ public:
+ /// circular_raw_ostream - Construct an optionally
+ /// circular-buffered stream, handing it an underlying stream to
+ /// do the "real" output.
+ ///
+ /// As a side effect, if BuffSize is nonzero, the given Stream is
+ /// set to be Unbuffered. This is because circular_raw_ostream
+ /// does its own buffering, so it doesn't want another layer of
+ /// buffering to be happening underneath it.
+ ///
+ /// "Owns" tells the circular_raw_ostream whether it is
+ /// responsible for managing the held stream, doing memory
+ /// management of it, etc.
+ ///
+ circular_raw_ostream(raw_ostream &Stream, const char *Header,
+ size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
+ : raw_ostream(/*unbuffered*/true),
+ TheStream(0),
+ OwnsStream(Owns),
+ BufferSize(BuffSize),
+ BufferArray(0),
+ Filled(false),
+ Banner(Header) {
+ if (BufferSize != 0)
+ BufferArray = new char[BufferSize];
+ Cur = BufferArray;
+ setStream(Stream, Owns);
+ }
+ explicit circular_raw_ostream()
+ : raw_ostream(/*unbuffered*/true),
+ TheStream(0),
+ OwnsStream(REFERENCE_ONLY),
+ BufferArray(0),
+ Filled(false),
+ Banner("") {
+ Cur = BufferArray;
+ }
+
+ ~circular_raw_ostream() {
+ flush();
+ flushBufferWithBanner();
+ releaseStream();
+ delete[] BufferArray;
+ }
+
+ /// setStream - Tell the circular_raw_ostream to output a
+ /// different stream. "Owns" tells circular_raw_ostream whether
+ /// it should take responsibility for managing the underlying
+ /// stream.
+ ///
+ void setStream(raw_ostream &Stream, bool Owns = REFERENCE_ONLY) {
+ releaseStream();
+ TheStream = &Stream;
+ OwnsStream = Owns;
+ }
+
+ /// flushBufferWithBanner - Force output of the buffer along with
+ /// a small header.
+ ///
+ void flushBufferWithBanner(void);
+
+ private:
+ /// releaseStream - Delete the held stream if needed. Otherwise,
+ /// transfer the buffer settings from this circular_raw_ostream
+ /// back to the underlying stream.
+ ///
+ void releaseStream() {
+ if (!TheStream)
+ return;
+ if (OwnsStream)
+ delete TheStream;
+ }
+ };
+} // end llvm namespace
+
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/raw_os_ostream.h b/contrib/llvm/include/llvm/Support/raw_os_ostream.h
new file mode 100644
index 000000000000..4f5d3612da18
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/raw_os_ostream.h
@@ -0,0 +1,42 @@
+//===- raw_os_ostream.h - std::ostream adaptor for raw_ostream --*- 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 raw_os_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_OS_OSTREAM_H
+#define LLVM_SUPPORT_RAW_OS_OSTREAM_H
+
+#include "llvm/Support/raw_ostream.h"
+#include <iosfwd>
+
+namespace llvm {
+
+/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
+/// simple adaptor class. It does not check for output errors; clients should
+/// 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);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() const;
+
+public:
+ raw_os_ostream(std::ostream &O) : OS(O) {}
+ ~raw_os_ostream();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/raw_ostream.h b/contrib/llvm/include/llvm/Support/raw_ostream.h
new file mode 100644
index 000000000000..6c5d4787e0f5
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/raw_ostream.h
@@ -0,0 +1,496 @@
+//===--- raw_ostream.h - Raw output stream ----------------------*- 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 raw_ostream class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
+#define LLVM_SUPPORT_RAW_OSTREAM_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class format_object_base;
+ template <typename T>
+ class SmallVectorImpl;
+
+/// raw_ostream - This class implements an extremely fast bulk output stream
+/// that can *only* output to a stream. It does not support seeking, reopening,
+/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
+/// a chunk at a time.
+class raw_ostream {
+private:
+ // Do not implement. raw_ostream is noncopyable.
+ void operator=(const raw_ostream &);
+ raw_ostream(const raw_ostream &);
+
+ /// The buffer is handled in such a way that the buffer is
+ /// uninitialized, unbuffered, or out of space when OutBufCur >=
+ /// OutBufEnd. Thus a single comparison suffices to determine if we
+ /// need to take the slow path to write a single character.
+ ///
+ /// The buffer is in one of three states:
+ /// 1. Unbuffered (BufferMode == Unbuffered)
+ /// 1. Uninitialized (BufferMode != Unbuffered && OutBufStart == 0).
+ /// 2. Buffered (BufferMode != Unbuffered && OutBufStart != 0 &&
+ /// OutBufEnd - OutBufStart >= 1).
+ ///
+ /// If buffered, then the raw_ostream owns the buffer if (BufferMode ==
+ /// InternalBuffer); otherwise the buffer has been set via SetBuffer and is
+ /// managed by the subclass.
+ ///
+ /// If a subclass installs an external buffer using SetBuffer then it can wait
+ /// for a \see write_impl() call to handle the data which has been put into
+ /// this buffer.
+ char *OutBufStart, *OutBufEnd, *OutBufCur;
+
+ enum BufferKind {
+ Unbuffered = 0,
+ InternalBuffer,
+ ExternalBuffer
+ } BufferMode;
+
+public:
+ // color order matches ANSI escape sequence, don't change
+ enum Colors {
+ BLACK=0,
+ RED,
+ GREEN,
+ YELLOW,
+ BLUE,
+ MAGENTA,
+ CYAN,
+ WHITE,
+ SAVEDCOLOR
+ };
+
+ explicit raw_ostream(bool unbuffered=false)
+ : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
+ // Start out ready to flush.
+ OutBufStart = OutBufEnd = OutBufCur = 0;
+ }
+
+ virtual ~raw_ostream();
+
+ /// tell - Return the current offset with the file.
+ uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); }
+
+ //===--------------------------------------------------------------------===//
+ // Configuration Interface
+ //===--------------------------------------------------------------------===//
+
+ /// SetBuffered - Set the stream to be buffered, with an automatically
+ /// determined buffer size.
+ void SetBuffered();
+
+ /// SetBufferSize - Set the stream to be buffered, using the
+ /// specified buffer size.
+ void SetBufferSize(size_t Size) {
+ flush();
+ SetBufferAndMode(new char[Size], Size, InternalBuffer);
+ }
+
+ size_t GetBufferSize() const {
+ // If we're supposed to be buffered but haven't actually gotten around
+ // to allocating the buffer yet, return the value that would be used.
+ if (BufferMode != Unbuffered && OutBufStart == 0)
+ return preferred_buffer_size();
+
+ // Otherwise just return the size of the allocated buffer.
+ return OutBufEnd - OutBufStart;
+ }
+
+ /// SetUnbuffered - Set the stream to be unbuffered. When
+ /// unbuffered, the stream will flush after every write. This routine
+ /// will also flush the buffer immediately when the stream is being
+ /// set to unbuffered.
+ void SetUnbuffered() {
+ flush();
+ SetBufferAndMode(0, 0, Unbuffered);
+ }
+
+ size_t GetNumBytesInBuffer() const {
+ return OutBufCur - OutBufStart;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Data Output Interface
+ //===--------------------------------------------------------------------===//
+
+ void flush() {
+ if (OutBufCur != OutBufStart)
+ flush_nonempty();
+ }
+
+ raw_ostream &operator<<(char C) {
+ if (OutBufCur >= OutBufEnd)
+ return write(C);
+ *OutBufCur++ = C;
+ return *this;
+ }
+
+ raw_ostream &operator<<(unsigned char C) {
+ if (OutBufCur >= OutBufEnd)
+ return write(C);
+ *OutBufCur++ = C;
+ return *this;
+ }
+
+ raw_ostream &operator<<(signed char C) {
+ if (OutBufCur >= OutBufEnd)
+ return write(C);
+ *OutBufCur++ = C;
+ return *this;
+ }
+
+ raw_ostream &operator<<(StringRef Str) {
+ // Inline fast path, particularly for strings with a known length.
+ size_t Size = Str.size();
+
+ // Make sure we can use the fast path.
+ if (OutBufCur+Size > OutBufEnd)
+ return write(Str.data(), Size);
+
+ memcpy(OutBufCur, Str.data(), Size);
+ OutBufCur += Size;
+ return *this;
+ }
+
+ raw_ostream &operator<<(const char *Str) {
+ // Inline fast path, particularly for constant strings where a sufficiently
+ // smart compiler will simplify strlen.
+
+ return this->operator<<(StringRef(Str));
+ }
+
+ raw_ostream &operator<<(const std::string &Str) {
+ // Avoid the fast path, it would only increase code size for a marginal win.
+ return write(Str.data(), Str.length());
+ }
+
+ raw_ostream &operator<<(unsigned long N);
+ raw_ostream &operator<<(long N);
+ raw_ostream &operator<<(unsigned long long N);
+ raw_ostream &operator<<(long long N);
+ raw_ostream &operator<<(const void *P);
+ raw_ostream &operator<<(unsigned int N) {
+ return this->operator<<(static_cast<unsigned long>(N));
+ }
+
+ raw_ostream &operator<<(int N) {
+ return this->operator<<(static_cast<long>(N));
+ }
+
+ raw_ostream &operator<<(double N);
+
+ /// write_hex - Output \arg 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
+ /// anything that doesn't satisfy std::isprint into an escape sequence.
+ raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
+
+ raw_ostream &write(unsigned char C);
+ raw_ostream &write(const char *Ptr, size_t Size);
+
+ // Formatted output, see the format() function in Support/Format.h.
+ raw_ostream &operator<<(const format_object_base &Fmt);
+
+ /// indent - Insert 'NumSpaces' spaces.
+ raw_ostream &indent(unsigned NumSpaces);
+
+
+ /// Changes the foreground color of text that will be output from this point
+ /// forward.
+ /// @param colors ANSI color to use, the special SAVEDCOLOR can be used to
+ /// change only the bold attribute, and keep colors untouched
+ /// @param bold bold/brighter text, default false
+ /// @param bg if true change the background, default: change foreground
+ /// @returns itself so it can be used within << invocations
+ virtual raw_ostream &changeColor(enum Colors, bool = false, bool = false) {
+ return *this; }
+
+ /// Resets the colors to terminal defaults. Call this when you are done
+ /// outputting colored text, or before program exit.
+ virtual raw_ostream &resetColor() { return *this; }
+
+ /// Reverses the forground and background colors.
+ virtual raw_ostream &reverseColor() { return *this; }
+
+ /// This function determines if this stream 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.
+ virtual bool is_displayed() const { return false; }
+
+ //===--------------------------------------------------------------------===//
+ // Subclass Interface
+ //===--------------------------------------------------------------------===//
+
+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.
+ ///
+ /// 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
+ /// is guaranteed to be the start of the buffer.
+ /// \arg Size - The number of bytes to be written.
+ ///
+ /// \invariant { Size > 0 }
+ virtual void write_impl(const char *Ptr, size_t Size) = 0;
+
+ // An out of line virtual method to provide a home for the class vtable.
+ virtual void handle();
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() const = 0;
+
+protected:
+ /// SetBuffer - Use the provided buffer as the raw_ostream buffer. This is
+ /// intended for use only by subclasses which can arrange for the output to go
+ /// directly into the desired output buffer, instead of being copied on each
+ /// flush.
+ void SetBuffer(char *BufferStart, size_t Size) {
+ SetBufferAndMode(BufferStart, Size, ExternalBuffer);
+ }
+
+ /// preferred_buffer_size - Return an efficient buffer size for the
+ /// underlying output mechanism.
+ virtual size_t preferred_buffer_size() const;
+
+ /// getBufferStart - Return the beginning of the current stream buffer, or 0
+ /// if the stream is unbuffered.
+ const char *getBufferStart() const { return OutBufStart; }
+
+ //===--------------------------------------------------------------------===//
+ // Private Interface
+ //===--------------------------------------------------------------------===//
+private:
+ /// SetBufferAndMode - Install the given buffer and mode.
+ void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode);
+
+ /// flush_nonempty - Flush the current buffer, which is known to be
+ /// non-empty. This outputs the currently buffered data and resets
+ /// the buffer to empty.
+ void flush_nonempty();
+
+ /// copy_to_buffer - Copy data into the buffer. Size must not be
+ /// greater than the number of unused bytes in the buffer.
+ void copy_to_buffer(const char *Ptr, size_t Size);
+};
+
+//===----------------------------------------------------------------------===//
+// File Output Streams
+//===----------------------------------------------------------------------===//
+
+/// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
+///
+class raw_fd_ostream : public raw_ostream {
+ int FD;
+ bool ShouldClose;
+
+ /// Error This flag is true if an error of any kind has been detected.
+ ///
+ bool Error;
+
+ /// Controls whether the stream should attempt to use atomic writes, when
+ /// possible.
+ bool UseAtomicWrites;
+
+ uint64_t pos;
+
+ /// write_impl - See raw_ostream::write_impl.
+ virtual void write_impl(const char *Ptr, size_t Size);
+
+ /// 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; }
+
+ /// preferred_buffer_size - Determine an efficient buffer size.
+ virtual size_t preferred_buffer_size() const;
+
+ /// error_detected - Set the flag indicating that an output error has
+ /// been encountered.
+ void error_detected() { Error = true; }
+
+public:
+
+ enum {
+ /// F_Excl - When opening a file, this flag makes raw_fd_ostream
+ /// report an error if the file already exists.
+ F_Excl = 1,
+
+ /// F_Append - When opening a file, if it already exists append to the
+ /// existing file instead of returning an error. This may not be specified
+ /// with F_Excl.
+ F_Append = 2,
+
+ /// F_Binary - The file should be opened in binary mode on platforms that
+ /// make this distinction.
+ F_Binary = 4
+ };
+
+ /// raw_fd_ostream - Open the specified file for writing. If an error occurs,
+ /// information about the error is put into ErrorInfo, and the stream should
+ /// be immediately destroyed; the string will be empty if no error occurred.
+ /// This allows optional flags to control how the file will be opened.
+ ///
+ /// As a special case, if Filename is "-", then the stream will use
+ /// STDOUT_FILENO instead of opening a file. Note that it will still consider
+ /// itself to own the file descriptor. In particular, it will close the
+ /// file descriptor when it is done (this is necessary to detect
+ /// output errors).
+ raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
+ unsigned Flags = 0);
+
+ /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If
+ /// ShouldClose is true, this closes the file when the stream is destroyed.
+ raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false);
+
+ ~raw_fd_ostream();
+
+ /// close - Manually flush the stream and close the file.
+ /// Note that this does not call fsync.
+ void close();
+
+ /// seek - Flushes the stream and repositions the underlying file descriptor
+ /// position to the offset specified from the beginning of the file.
+ uint64_t seek(uint64_t off);
+
+ /// SetUseAtomicWrite - Set the stream to attempt to use atomic writes for
+ /// individual output routines where possible.
+ ///
+ /// Note that because raw_ostream's are typically buffered, this flag is only
+ /// sensible when used on unbuffered streams which will flush their output
+ /// immediately.
+ void SetUseAtomicWrites(bool Value) {
+ UseAtomicWrites = Value;
+ }
+
+ virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
+ bool bg=false);
+ virtual raw_ostream &resetColor();
+
+ virtual raw_ostream &reverseColor();
+
+ virtual bool is_displayed() const;
+
+ /// has_error - Return the value of the flag in this raw_fd_ostream indicating
+ /// whether an output error has been encountered.
+ /// This doesn't implicitly flush any pending output. Also, it doesn't
+ /// guarantee to detect all errors unless the the stream has been closed.
+ bool has_error() const {
+ return Error;
+ }
+
+ /// clear_error - Set the flag read by has_error() to false. If the error
+ /// flag is set at the time when this raw_ostream's destructor is called,
+ /// report_fatal_error is called to report the error. Use clear_error()
+ /// after handling the error to avoid this behavior.
+ ///
+ /// "Errors should never pass silently.
+ /// Unless explicitly silenced."
+ /// - from The Zen of Python, by Tim Peters
+ ///
+ void clear_error() {
+ Error = false;
+ }
+};
+
+/// outs() - This returns a reference to a raw_ostream for standard output.
+/// Use it like: outs() << "foo" << "bar";
+raw_ostream &outs();
+
+/// errs() - This returns a reference to a raw_ostream for standard error.
+/// Use it like: errs() << "foo" << "bar";
+raw_ostream &errs();
+
+/// nulls() - This returns a reference to a raw_ostream which simply discards
+/// output.
+raw_ostream &nulls();
+
+//===----------------------------------------------------------------------===//
+// Output Stream Adaptors
+//===----------------------------------------------------------------------===//
+
+/// raw_string_ostream - A raw_ostream that writes to an std::string. This is a
+/// simple adaptor class. This class does not encounter output errors.
+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);
+
+ /// 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(); }
+public:
+ explicit raw_string_ostream(std::string &O) : OS(O) {}
+ ~raw_string_ostream();
+
+ /// str - Flushes the stream contents to the target string and returns
+ /// the string's reference.
+ std::string& str() {
+ flush();
+ return OS;
+ }
+};
+
+/// raw_svector_ostream - A raw_ostream that writes to an SmallVector or
+/// SmallString. This is a simple adaptor class. This class does not
+/// encounter output errors.
+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);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() const;
+public:
+ /// Construct a new raw_svector_ostream.
+ ///
+ /// \arg 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();
+
+ /// resync - This is called when the SmallVector we're appending to is changed
+ /// outside of the raw_svector_ostream's control. It is only safe to do this
+ /// if the raw_svector_ostream has previously been flushed.
+ void resync();
+
+ /// str - Flushes the stream contents to the target vector and return a
+ /// StringRef for the vector contents.
+ StringRef str();
+};
+
+/// 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);
+
+ /// current_pos - Return the current position within the stream, not
+ /// counting the bytes currently in the buffer.
+ virtual uint64_t current_pos() const;
+
+public:
+ explicit raw_null_ostream() {}
+ ~raw_null_ostream();
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/system_error.h b/contrib/llvm/include/llvm/Support/system_error.h
new file mode 100644
index 000000000000..af812069b9fe
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/system_error.h
@@ -0,0 +1,903 @@
+//===---------------------------- system_error ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This was lifted from libc++ and modified for C++03. This is called
+// system_error even though it does not define that class because that's what
+// it's called in C++0x. We don't define system_error because it is only used
+// for exception handling, which we don't use in LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
+#define LLVM_SYSTEM_SYSTEM_ERROR_H
+
+/*
+ system_error synopsis
+
+namespace std
+{
+
+class error_category
+{
+public:
+ virtual ~error_category();
+
+ error_category(const error_category&) = delete;
+ error_category& operator=(const error_category&) = delete;
+
+ virtual const char* name() const = 0;
+ virtual error_condition default_error_condition(int ev) const;
+ virtual bool equivalent(int code, const error_condition& condition) const;
+ virtual bool equivalent(const error_code& code, int condition) const;
+ virtual std::string message(int ev) const = 0;
+
+ bool operator==(const error_category& rhs) const;
+ bool operator!=(const error_category& rhs) const;
+ bool operator<(const error_category& rhs) const;
+};
+
+const error_category& generic_category();
+const error_category& system_category();
+
+template <class T> struct is_error_code_enum
+ : public false_type {};
+
+template <class T> struct is_error_condition_enum
+ : public false_type {};
+
+class error_code
+{
+public:
+ // constructors:
+ error_code();
+ error_code(int val, const error_category& cat);
+ template <class ErrorCodeEnum>
+ error_code(ErrorCodeEnum e);
+
+ // modifiers:
+ void assign(int val, const error_category& cat);
+ template <class ErrorCodeEnum>
+ error_code& operator=(ErrorCodeEnum e);
+ void clear();
+
+ // observers:
+ int value() const;
+ const error_category& category() const;
+ error_condition default_error_condition() const;
+ std::string message() const;
+ explicit operator bool() const;
+};
+
+// non-member functions:
+bool operator<(const error_code& lhs, const error_code& rhs);
+template <class charT, class traits>
+ basic_ostream<charT,traits>&
+ operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
+
+class error_condition
+{
+public:
+ // constructors:
+ error_condition();
+ error_condition(int val, const error_category& cat);
+ template <class ErrorConditionEnum>
+ error_condition(ErrorConditionEnum e);
+
+ // modifiers:
+ void assign(int val, const error_category& cat);
+ template <class ErrorConditionEnum>
+ error_condition& operator=(ErrorConditionEnum e);
+ void clear();
+
+ // observers:
+ int value() const;
+ const error_category& category() const;
+ std::string message() const;
+ explicit operator bool() const;
+};
+
+bool operator<(const error_condition& lhs, const error_condition& rhs);
+
+class system_error
+ : public runtime_error
+{
+public:
+ system_error(error_code ec, const std::string& what_arg);
+ system_error(error_code ec, const char* what_arg);
+ system_error(error_code ec);
+ system_error(int ev, const error_category& ecat, const std::string& what_arg);
+ system_error(int ev, const error_category& ecat, const char* what_arg);
+ system_error(int ev, const error_category& ecat);
+
+ const error_code& code() const throw();
+ const char* what() const throw();
+};
+
+enum class errc
+{
+ address_family_not_supported, // EAFNOSUPPORT
+ address_in_use, // EADDRINUSE
+ address_not_available, // EADDRNOTAVAIL
+ already_connected, // EISCONN
+ argument_list_too_long, // E2BIG
+ argument_out_of_domain, // EDOM
+ bad_address, // EFAULT
+ bad_file_descriptor, // EBADF
+ bad_message, // EBADMSG
+ broken_pipe, // EPIPE
+ connection_aborted, // ECONNABORTED
+ connection_already_in_progress, // EALREADY
+ connection_refused, // ECONNREFUSED
+ connection_reset, // ECONNRESET
+ cross_device_link, // EXDEV
+ destination_address_required, // EDESTADDRREQ
+ device_or_resource_busy, // EBUSY
+ directory_not_empty, // ENOTEMPTY
+ executable_format_error, // ENOEXEC
+ file_exists, // EEXIST
+ file_too_large, // EFBIG
+ filename_too_long, // ENAMETOOLONG
+ function_not_supported, // ENOSYS
+ host_unreachable, // EHOSTUNREACH
+ identifier_removed, // EIDRM
+ illegal_byte_sequence, // EILSEQ
+ inappropriate_io_control_operation, // ENOTTY
+ interrupted, // EINTR
+ invalid_argument, // EINVAL
+ invalid_seek, // ESPIPE
+ io_error, // EIO
+ is_a_directory, // EISDIR
+ message_size, // EMSGSIZE
+ network_down, // ENETDOWN
+ network_reset, // ENETRESET
+ network_unreachable, // ENETUNREACH
+ no_buffer_space, // ENOBUFS
+ no_child_process, // ECHILD
+ no_link, // ENOLINK
+ no_lock_available, // ENOLCK
+ no_message_available, // ENODATA
+ no_message, // ENOMSG
+ no_protocol_option, // ENOPROTOOPT
+ no_space_on_device, // ENOSPC
+ no_stream_resources, // ENOSR
+ no_such_device_or_address, // ENXIO
+ no_such_device, // ENODEV
+ no_such_file_or_directory, // ENOENT
+ no_such_process, // ESRCH
+ not_a_directory, // ENOTDIR
+ not_a_socket, // ENOTSOCK
+ not_a_stream, // ENOSTR
+ not_connected, // ENOTCONN
+ not_enough_memory, // ENOMEM
+ not_supported, // ENOTSUP
+ operation_canceled, // ECANCELED
+ operation_in_progress, // EINPROGRESS
+ operation_not_permitted, // EPERM
+ operation_not_supported, // EOPNOTSUPP
+ operation_would_block, // EWOULDBLOCK
+ owner_dead, // EOWNERDEAD
+ permission_denied, // EACCES
+ protocol_error, // EPROTO
+ protocol_not_supported, // EPROTONOSUPPORT
+ read_only_file_system, // EROFS
+ resource_deadlock_would_occur, // EDEADLK
+ resource_unavailable_try_again, // EAGAIN
+ result_out_of_range, // ERANGE
+ state_not_recoverable, // ENOTRECOVERABLE
+ stream_timeout, // ETIME
+ text_file_busy, // ETXTBSY
+ timed_out, // ETIMEDOUT
+ too_many_files_open_in_system, // ENFILE
+ too_many_files_open, // EMFILE
+ too_many_links, // EMLINK
+ too_many_symbolic_link_levels, // ELOOP
+ value_too_large, // EOVERFLOW
+ wrong_protocol_type // EPROTOTYPE
+};
+
+template <> struct is_error_condition_enum<errc> : true_type { }
+
+error_code make_error_code(errc e);
+error_condition make_error_condition(errc e);
+
+// Comparison operators:
+bool operator==(const error_code& lhs, const error_code& rhs);
+bool operator==(const error_code& lhs, const error_condition& rhs);
+bool operator==(const error_condition& lhs, const error_code& rhs);
+bool operator==(const error_condition& lhs, const error_condition& rhs);
+bool operator!=(const error_code& lhs, const error_code& rhs);
+bool operator!=(const error_code& lhs, const error_condition& rhs);
+bool operator!=(const error_condition& lhs, const error_code& rhs);
+bool operator!=(const error_condition& lhs, const error_condition& rhs);
+
+template <> struct hash<std::error_code>;
+
+} // std
+
+*/
+
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/type_traits.h"
+#include <cerrno>
+#include <string>
+
+// This must be here instead of a .inc file because it is used in the definition
+// of the enum values below.
+#ifdef LLVM_ON_WIN32
+
+ // The following numbers were taken from VS2010.
+# ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT 102
+# endif
+# ifndef EADDRINUSE
+# define EADDRINUSE 100
+# endif
+# ifndef EADDRNOTAVAIL
+# define EADDRNOTAVAIL 101
+# endif
+# ifndef EISCONN
+# define EISCONN 113
+# endif
+# ifndef E2BIG
+# define E2BIG 7
+# endif
+# ifndef EDOM
+# define EDOM 33
+# endif
+# ifndef EFAULT
+# define EFAULT 14
+# endif
+# ifndef EBADF
+# define EBADF 9
+# endif
+# ifndef EBADMSG
+# define EBADMSG 104
+# endif
+# ifndef EPIPE
+# define EPIPE 32
+# endif
+# ifndef ECONNABORTED
+# define ECONNABORTED 106
+# endif
+# ifndef EALREADY
+# define EALREADY 103
+# endif
+# ifndef ECONNREFUSED
+# define ECONNREFUSED 107
+# endif
+# ifndef ECONNRESET
+# define ECONNRESET 108
+# endif
+# ifndef EXDEV
+# define EXDEV 18
+# endif
+# ifndef EDESTADDRREQ
+# define EDESTADDRREQ 109
+# endif
+# ifndef EBUSY
+# define EBUSY 16
+# endif
+# ifndef ENOTEMPTY
+# define ENOTEMPTY 41
+# endif
+# ifndef ENOEXEC
+# define ENOEXEC 8
+# endif
+# ifndef EEXIST
+# define EEXIST 17
+# endif
+# ifndef EFBIG
+# define EFBIG 27
+# endif
+# ifndef ENAMETOOLONG
+# define ENAMETOOLONG 38
+# endif
+# ifndef ENOSYS
+# define ENOSYS 40
+# endif
+# ifndef EHOSTUNREACH
+# define EHOSTUNREACH 110
+# endif
+# ifndef EIDRM
+# define EIDRM 111
+# endif
+# ifndef EILSEQ
+# define EILSEQ 42
+# endif
+# ifndef ENOTTY
+# define ENOTTY 25
+# endif
+# ifndef EINTR
+# define EINTR 4
+# endif
+# ifndef EINVAL
+# define EINVAL 22
+# endif
+# ifndef ESPIPE
+# define ESPIPE 29
+# endif
+# ifndef EIO
+# define EIO 5
+# endif
+# ifndef EISDIR
+# define EISDIR 21
+# endif
+# ifndef EMSGSIZE
+# define EMSGSIZE 115
+# endif
+# ifndef ENETDOWN
+# define ENETDOWN 116
+# endif
+# ifndef ENETRESET
+# define ENETRESET 117
+# endif
+# ifndef ENETUNREACH
+# define ENETUNREACH 118
+# endif
+# ifndef ENOBUFS
+# define ENOBUFS 119
+# endif
+# ifndef ECHILD
+# define ECHILD 10
+# endif
+# ifndef ENOLINK
+# define ENOLINK 121
+# endif
+# ifndef ENOLCK
+# define ENOLCK 39
+# endif
+# ifndef ENODATA
+# define ENODATA 120
+# endif
+# ifndef ENOMSG
+# define ENOMSG 122
+# endif
+# ifndef ENOPROTOOPT
+# define ENOPROTOOPT 123
+# endif
+# ifndef ENOSPC
+# define ENOSPC 28
+# endif
+# ifndef ENOSR
+# define ENOSR 124
+# endif
+# ifndef ENXIO
+# define ENXIO 6
+# endif
+# ifndef ENODEV
+# define ENODEV 19
+# endif
+# ifndef ENOENT
+# define ENOENT 2
+# endif
+# ifndef ESRCH
+# define ESRCH 3
+# endif
+# ifndef ENOTDIR
+# define ENOTDIR 20
+# endif
+# ifndef ENOTSOCK
+# define ENOTSOCK 128
+# endif
+# ifndef ENOSTR
+# define ENOSTR 125
+# endif
+# ifndef ENOTCONN
+# define ENOTCONN 126
+# endif
+# ifndef ENOMEM
+# define ENOMEM 12
+# endif
+# ifndef ENOTSUP
+# define ENOTSUP 129
+# endif
+# ifndef ECANCELED
+# define ECANCELED 105
+# endif
+# ifndef EINPROGRESS
+# define EINPROGRESS 112
+# endif
+# ifndef EPERM
+# define EPERM 1
+# endif
+# ifndef EOPNOTSUPP
+# define EOPNOTSUPP 130
+# endif
+# ifndef EWOULDBLOCK
+# define EWOULDBLOCK 140
+# endif
+# ifndef EOWNERDEAD
+# define EOWNERDEAD 133
+# endif
+# ifndef EACCES
+# define EACCES 13
+# endif
+# ifndef EPROTO
+# define EPROTO 134
+# endif
+# ifndef EPROTONOSUPPORT
+# define EPROTONOSUPPORT 135
+# endif
+# ifndef EROFS
+# define EROFS 30
+# endif
+# ifndef EDEADLK
+# define EDEADLK 36
+# endif
+# ifndef EAGAIN
+# define EAGAIN 11
+# endif
+# ifndef ERANGE
+# define ERANGE 34
+# endif
+# ifndef ENOTRECOVERABLE
+# define ENOTRECOVERABLE 127
+# endif
+# ifndef ETIME
+# define ETIME 137
+# endif
+# ifndef ETXTBSY
+# define ETXTBSY 139
+# endif
+# ifndef ETIMEDOUT
+# define ETIMEDOUT 138
+# endif
+# ifndef ENFILE
+# define ENFILE 23
+# endif
+# ifndef EMFILE
+# define EMFILE 24
+# endif
+# ifndef EMLINK
+# define EMLINK 31
+# endif
+# ifndef ELOOP
+# define ELOOP 114
+# endif
+# ifndef EOVERFLOW
+# define EOVERFLOW 132
+# endif
+# ifndef EPROTOTYPE
+# define EPROTOTYPE 136
+# endif
+#endif
+
+namespace llvm {
+
+// is_error_code_enum
+
+template <class Tp> struct is_error_code_enum : public false_type {};
+
+// is_error_condition_enum
+
+template <class Tp> struct is_error_condition_enum : public false_type {};
+
+// Some error codes are not present on all platforms, so we provide equivalents
+// for them:
+
+//enum class errc
+struct errc {
+enum _ {
+ success = 0,
+ address_family_not_supported = EAFNOSUPPORT,
+ address_in_use = EADDRINUSE,
+ address_not_available = EADDRNOTAVAIL,
+ already_connected = EISCONN,
+ argument_list_too_long = E2BIG,
+ argument_out_of_domain = EDOM,
+ bad_address = EFAULT,
+ bad_file_descriptor = EBADF,
+#ifdef EBADMSG
+ bad_message = EBADMSG,
+#else
+ bad_message = EINVAL,
+#endif
+ broken_pipe = EPIPE,
+ connection_aborted = ECONNABORTED,
+ connection_already_in_progress = EALREADY,
+ connection_refused = ECONNREFUSED,
+ connection_reset = ECONNRESET,
+ cross_device_link = EXDEV,
+ destination_address_required = EDESTADDRREQ,
+ device_or_resource_busy = EBUSY,
+ directory_not_empty = ENOTEMPTY,
+ executable_format_error = ENOEXEC,
+ file_exists = EEXIST,
+ file_too_large = EFBIG,
+ filename_too_long = ENAMETOOLONG,
+ function_not_supported = ENOSYS,
+ host_unreachable = EHOSTUNREACH,
+ identifier_removed = EIDRM,
+ illegal_byte_sequence = EILSEQ,
+ inappropriate_io_control_operation = ENOTTY,
+ interrupted = EINTR,
+ invalid_argument = EINVAL,
+ invalid_seek = ESPIPE,
+ io_error = EIO,
+ is_a_directory = EISDIR,
+ message_size = EMSGSIZE,
+ network_down = ENETDOWN,
+ network_reset = ENETRESET,
+ network_unreachable = ENETUNREACH,
+ no_buffer_space = ENOBUFS,
+ no_child_process = ECHILD,
+#ifdef ENOLINK
+ no_link = ENOLINK,
+#else
+ no_link = EINVAL,
+#endif
+ no_lock_available = ENOLCK,
+#ifdef ENODATA
+ no_message_available = ENODATA,
+#else
+ no_message_available = ENOMSG,
+#endif
+ no_message = ENOMSG,
+ no_protocol_option = ENOPROTOOPT,
+ no_space_on_device = ENOSPC,
+#ifdef ENOSR
+ no_stream_resources = ENOSR,
+#else
+ no_stream_resources = ENOMEM,
+#endif
+ no_such_device_or_address = ENXIO,
+ no_such_device = ENODEV,
+ no_such_file_or_directory = ENOENT,
+ no_such_process = ESRCH,
+ not_a_directory = ENOTDIR,
+ not_a_socket = ENOTSOCK,
+#ifdef ENOSTR
+ not_a_stream = ENOSTR,
+#else
+ not_a_stream = EINVAL,
+#endif
+ not_connected = ENOTCONN,
+ not_enough_memory = ENOMEM,
+ not_supported = ENOTSUP,
+#ifdef ECANCELED
+ operation_canceled = ECANCELED,
+#else
+ operation_canceled = EINVAL,
+#endif
+ operation_in_progress = EINPROGRESS,
+ operation_not_permitted = EPERM,
+ operation_not_supported = EOPNOTSUPP,
+ operation_would_block = EWOULDBLOCK,
+#ifdef EOWNERDEAD
+ owner_dead = EOWNERDEAD,
+#else
+ owner_dead = EINVAL,
+#endif
+ permission_denied = EACCES,
+#ifdef EPROTO
+ protocol_error = EPROTO,
+#else
+ protocol_error = EINVAL,
+#endif
+ protocol_not_supported = EPROTONOSUPPORT,
+ read_only_file_system = EROFS,
+ resource_deadlock_would_occur = EDEADLK,
+ resource_unavailable_try_again = EAGAIN,
+ result_out_of_range = ERANGE,
+#ifdef ENOTRECOVERABLE
+ state_not_recoverable = ENOTRECOVERABLE,
+#else
+ state_not_recoverable = EINVAL,
+#endif
+#ifdef ETIME
+ stream_timeout = ETIME,
+#else
+ stream_timeout = ETIMEDOUT,
+#endif
+ text_file_busy = ETXTBSY,
+ timed_out = ETIMEDOUT,
+ too_many_files_open_in_system = ENFILE,
+ too_many_files_open = EMFILE,
+ too_many_links = EMLINK,
+ too_many_symbolic_link_levels = ELOOP,
+ value_too_large = EOVERFLOW,
+ wrong_protocol_type = EPROTOTYPE
+};
+
+ _ v_;
+
+ errc(_ v) : v_(v) {}
+ operator int() const {return v_;}
+};
+
+template <> struct is_error_condition_enum<errc> : true_type { };
+
+template <> struct is_error_condition_enum<errc::_> : true_type { };
+
+class error_condition;
+class error_code;
+
+// class error_category
+
+class _do_message;
+
+class error_category
+{
+public:
+ virtual ~error_category();
+
+private:
+ error_category();
+ error_category(const error_category&);// = delete;
+ error_category& operator=(const error_category&);// = delete;
+
+public:
+ virtual const char* name() const = 0;
+ virtual error_condition default_error_condition(int _ev) const;
+ virtual bool equivalent(int _code, const error_condition& _condition) const;
+ virtual bool equivalent(const error_code& _code, int _condition) const;
+ virtual std::string message(int _ev) const = 0;
+
+ bool operator==(const error_category& _rhs) const {return this == &_rhs;}
+
+ bool operator!=(const error_category& _rhs) const {return !(*this == _rhs);}
+
+ bool operator< (const error_category& _rhs) const {return this < &_rhs;}
+
+ friend class _do_message;
+};
+
+class _do_message : public error_category
+{
+public:
+ virtual std::string message(int ev) const;
+};
+
+const error_category& generic_category();
+const error_category& system_category();
+
+/// Get the error_category used for errno values from POSIX functions. This is
+/// the same as the system_category on POSIX systems, but is the same as the
+/// generic_category on Windows.
+const error_category& posix_category();
+
+class error_condition
+{
+ int _val_;
+ const error_category* _cat_;
+public:
+ error_condition() : _val_(0), _cat_(&generic_category()) {}
+
+ error_condition(int _val, const error_category& _cat)
+ : _val_(_val), _cat_(&_cat) {}
+
+ template <class E>
+ error_condition(E _e, typename enable_if_c<
+ is_error_condition_enum<E>::value
+ >::type* = 0)
+ {*this = make_error_condition(_e);}
+
+ void assign(int _val, const error_category& _cat) {
+ _val_ = _val;
+ _cat_ = &_cat;
+ }
+
+ template <class E>
+ typename enable_if_c
+ <
+ is_error_condition_enum<E>::value,
+ error_condition&
+ >::type
+ operator=(E _e)
+ {*this = make_error_condition(_e); return *this;}
+
+ void clear() {
+ _val_ = 0;
+ _cat_ = &generic_category();
+ }
+
+ int value() const {return _val_;}
+
+ const error_category& category() const {return *_cat_;}
+ std::string message() const;
+
+ typedef void (*unspecified_bool_type)();
+ static void unspecified_bool_true() {}
+
+ operator unspecified_bool_type() const { // true if error
+ return _val_ == 0 ? 0 : unspecified_bool_true;
+ }
+};
+
+inline error_condition make_error_condition(errc _e) {
+ return error_condition(static_cast<int>(_e), generic_category());
+}
+
+inline bool operator<(const error_condition& _x, const error_condition& _y) {
+ return _x.category() < _y.category()
+ || (_x.category() == _y.category() && _x.value() < _y.value());
+}
+
+// error_code
+
+class error_code {
+ int _val_;
+ const error_category* _cat_;
+public:
+ error_code() : _val_(0), _cat_(&system_category()) {}
+
+ static error_code success() {
+ return error_code();
+ }
+
+ error_code(int _val, const error_category& _cat)
+ : _val_(_val), _cat_(&_cat) {}
+
+ template <class E>
+ error_code(E _e, typename enable_if_c<
+ is_error_code_enum<E>::value
+ >::type* = 0) {
+ *this = make_error_code(_e);
+ }
+
+ void assign(int _val, const error_category& _cat) {
+ _val_ = _val;
+ _cat_ = &_cat;
+ }
+
+ template <class E>
+ typename enable_if_c
+ <
+ is_error_code_enum<E>::value,
+ error_code&
+ >::type
+ operator=(E _e)
+ {*this = make_error_code(_e); return *this;}
+
+ void clear() {
+ _val_ = 0;
+ _cat_ = &system_category();
+ }
+
+ int value() const {return _val_;}
+
+ const error_category& category() const {return *_cat_;}
+
+ error_condition default_error_condition() const
+ {return _cat_->default_error_condition(_val_);}
+
+ std::string message() const;
+
+ typedef void (*unspecified_bool_type)();
+ static void unspecified_bool_true() {}
+
+ operator unspecified_bool_type() const { // true if error
+ return _val_ == 0 ? 0 : unspecified_bool_true;
+ }
+};
+
+inline error_code make_error_code(errc _e) {
+ return error_code(static_cast<int>(_e), generic_category());
+}
+
+inline bool operator<(const error_code& _x, const error_code& _y) {
+ return _x.category() < _y.category()
+ || (_x.category() == _y.category() && _x.value() < _y.value());
+}
+
+inline bool operator==(const error_code& _x, const error_code& _y) {
+ return _x.category() == _y.category() && _x.value() == _y.value();
+}
+
+inline bool operator==(const error_code& _x, const error_condition& _y) {
+ return _x.category().equivalent(_x.value(), _y)
+ || _y.category().equivalent(_x, _y.value());
+}
+
+inline bool operator==(const error_condition& _x, const error_code& _y) {
+ return _y == _x;
+}
+
+inline bool operator==(const error_condition& _x, const error_condition& _y) {
+ return _x.category() == _y.category() && _x.value() == _y.value();
+}
+
+inline bool operator!=(const error_code& _x, const error_code& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_code& _x, const error_condition& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_condition& _x, const error_code& _y) {
+ return !(_x == _y);
+}
+
+inline bool operator!=(const error_condition& _x, const error_condition& _y) {
+ return !(_x == _y);
+}
+
+// Windows errors.
+
+// To construct an error_code after an API error:
+//
+// error_code( ::GetLastError(), system_category() )
+struct windows_error {
+enum _ {
+ success = 0,
+ // These names and values are based on Windows WinError.h
+ // This is not a complete list. Add to this list if you need to explicitly
+ // check for it.
+ invalid_function = 1, // ERROR_INVALID_FUNCTION,
+ file_not_found = 2, // ERROR_FILE_NOT_FOUND,
+ path_not_found = 3, // ERROR_PATH_NOT_FOUND,
+ too_many_open_files = 4, // ERROR_TOO_MANY_OPEN_FILES,
+ access_denied = 5, // ERROR_ACCESS_DENIED,
+ invalid_handle = 6, // ERROR_INVALID_HANDLE,
+ arena_trashed = 7, // ERROR_ARENA_TRASHED,
+ not_enough_memory = 8, // ERROR_NOT_ENOUGH_MEMORY,
+ invalid_block = 9, // ERROR_INVALID_BLOCK,
+ bad_environment = 10, // ERROR_BAD_ENVIRONMENT,
+ bad_format = 11, // ERROR_BAD_FORMAT,
+ invalid_access = 12, // ERROR_INVALID_ACCESS,
+ outofmemory = 14, // ERROR_OUTOFMEMORY,
+ invalid_drive = 15, // ERROR_INVALID_DRIVE,
+ current_directory = 16, // ERROR_CURRENT_DIRECTORY,
+ not_same_device = 17, // ERROR_NOT_SAME_DEVICE,
+ no_more_files = 18, // ERROR_NO_MORE_FILES,
+ write_protect = 19, // ERROR_WRITE_PROTECT,
+ bad_unit = 20, // ERROR_BAD_UNIT,
+ not_ready = 21, // ERROR_NOT_READY,
+ bad_command = 22, // ERROR_BAD_COMMAND,
+ crc = 23, // ERROR_CRC,
+ bad_length = 24, // ERROR_BAD_LENGTH,
+ seek = 25, // ERROR_SEEK,
+ not_dos_disk = 26, // ERROR_NOT_DOS_DISK,
+ sector_not_found = 27, // ERROR_SECTOR_NOT_FOUND,
+ out_of_paper = 28, // ERROR_OUT_OF_PAPER,
+ write_fault = 29, // ERROR_WRITE_FAULT,
+ read_fault = 30, // ERROR_READ_FAULT,
+ gen_failure = 31, // ERROR_GEN_FAILURE,
+ sharing_violation = 32, // ERROR_SHARING_VIOLATION,
+ lock_violation = 33, // ERROR_LOCK_VIOLATION,
+ wrong_disk = 34, // ERROR_WRONG_DISK,
+ sharing_buffer_exceeded = 36, // ERROR_SHARING_BUFFER_EXCEEDED,
+ handle_eof = 38, // ERROR_HANDLE_EOF,
+ handle_disk_full = 39, // ERROR_HANDLE_DISK_FULL,
+ rem_not_list = 51, // ERROR_REM_NOT_LIST,
+ dup_name = 52, // ERROR_DUP_NAME,
+ bad_net_path = 53, // ERROR_BAD_NETPATH,
+ network_busy = 54, // ERROR_NETWORK_BUSY,
+ file_exists = 80, // ERROR_FILE_EXISTS,
+ cannot_make = 82, // ERROR_CANNOT_MAKE,
+ broken_pipe = 109, // ERROR_BROKEN_PIPE,
+ open_failed = 110, // ERROR_OPEN_FAILED,
+ buffer_overflow = 111, // ERROR_BUFFER_OVERFLOW,
+ disk_full = 112, // ERROR_DISK_FULL,
+ insufficient_buffer = 122, // ERROR_INSUFFICIENT_BUFFER,
+ lock_failed = 167, // ERROR_LOCK_FAILED,
+ busy = 170, // ERROR_BUSY,
+ cancel_violation = 173, // ERROR_CANCEL_VIOLATION,
+ already_exists = 183 // ERROR_ALREADY_EXISTS
+};
+ _ v_;
+
+ windows_error(_ v) : v_(v) {}
+ explicit windows_error(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+};
+
+
+template <> struct is_error_code_enum<windows_error> : true_type { };
+
+template <> struct is_error_code_enum<windows_error::_> : true_type { };
+
+inline error_code make_error_code(windows_error e) {
+ return error_code(static_cast<int>(e), system_category());
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Support/type_traits.h b/contrib/llvm/include/llvm/Support/type_traits.h
new file mode 100644
index 000000000000..a3a551f851f3
--- /dev/null
+++ b/contrib/llvm/include/llvm/Support/type_traits.h
@@ -0,0 +1,205 @@
+//===- llvm/Support/type_traits.h - Simplfied type traits -------*- 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 template class that determines if a type is a class or
+// not. The basic mechanism, based on using the pointer to member function of
+// a zero argument to a function was "boosted" from the boost type_traits
+// library. See http://www.boost.org/ for all the gory details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
+#define LLVM_SUPPORT_TYPE_TRAITS_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstddef>
+#include <utility>
+
+// This is actually the conforming implementation which works with abstract
+// classes. However, enough compilers have trouble with it that most will use
+// the one in boost/type_traits/object_traits.hpp. This implementation actually
+// works with VC7.0, but other interactions seem to fail when we use it.
+
+namespace llvm {
+
+namespace dont_use
+{
+ // These two functions should never be used. They are helpers to
+ // the is_class template below. They cannot be located inside
+ // is_class because doing so causes at least GCC to think that
+ // the value of the "value" enumerator is not constant. Placing
+ // them out here (for some strange reason) allows the sizeof
+ // operator against them to magically be constant. This is
+ // important to make the is_class<T>::value idiom zero cost. it
+ // evaluates to a constant 1 or 0 depending on whether the
+ // parameter T is a class or not (respectively).
+ template<typename T> char is_class_helper(void(T::*)());
+ template<typename T> double is_class_helper(...);
+}
+
+template <typename T>
+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)) };
+};
+
+
+/// isPodLike - This is a type trait that is used to determine whether a given
+/// type can be copied around with memcpy instead of running ctors etc.
+template <typename T>
+struct isPodLike {
+ // If we don't know anything else, we can (at least) assume that all non-class
+ // types are PODs.
+ static const bool value = !is_class<T>::value;
+};
+
+// std::pair's are pod-like if their elements are.
+template<typename T, typename U>
+struct isPodLike<std::pair<T, U> > {
+ static const bool value = isPodLike<T>::value && isPodLike<U>::value;
+};
+
+
+template <class T, T v>
+struct integral_constant {
+ typedef T value_type;
+ static const value_type value = v;
+ typedef integral_constant<T,v> type;
+ operator value_type() { return value; }
+};
+
+typedef integral_constant<bool, true> true_type;
+typedef integral_constant<bool, false> false_type;
+
+/// \brief Metafunction that determines whether the two given types are
+/// equivalent.
+template<typename T, typename U> struct is_same : public false_type {};
+template<typename T> struct is_same<T, T> : public true_type {};
+
+/// \brief Metafunction that removes const qualification from a type.
+template <typename T> struct remove_const { typedef T type; };
+template <typename T> struct remove_const<const T> { typedef T type; };
+
+/// \brief Metafunction that removes volatile qualification from a type.
+template <typename T> struct remove_volatile { typedef T type; };
+template <typename T> struct remove_volatile<volatile T> { typedef T type; };
+
+/// \brief Metafunction that removes both const and volatile qualification from
+/// a type.
+template <typename T> struct remove_cv {
+ typedef typename remove_const<typename remove_volatile<T>::type>::type type;
+};
+
+/// \brief Helper to implement is_integral metafunction.
+template <typename T> struct is_integral_impl : false_type {};
+template <> struct is_integral_impl< bool> : true_type {};
+template <> struct is_integral_impl< char> : true_type {};
+template <> struct is_integral_impl< signed char> : true_type {};
+template <> struct is_integral_impl<unsigned char> : true_type {};
+template <> struct is_integral_impl< wchar_t> : true_type {};
+template <> struct is_integral_impl< short> : true_type {};
+template <> struct is_integral_impl<unsigned short> : true_type {};
+template <> struct is_integral_impl< int> : true_type {};
+template <> struct is_integral_impl<unsigned int> : true_type {};
+template <> struct is_integral_impl< long> : true_type {};
+template <> struct is_integral_impl<unsigned long> : true_type {};
+template <> struct is_integral_impl< long long> : true_type {};
+template <> struct is_integral_impl<unsigned long long> : true_type {};
+
+/// \brief Metafunction that determines whether the given type is an integral
+/// type.
+template <typename T>
+struct is_integral : is_integral_impl<T> {};
+
+/// \brief Metafunction to remove reference from a type.
+template <typename T> struct remove_reference { typedef T type; };
+template <typename T> struct remove_reference<T&> { typedef T type; };
+
+/// \brief Metafunction that determines whether the given type is a pointer
+/// type.
+template <typename T> struct is_pointer : false_type {};
+template <typename T> struct is_pointer<T*> : true_type {};
+template <typename T> struct is_pointer<T* const> : true_type {};
+template <typename T> struct is_pointer<T* volatile> : true_type {};
+template <typename T> struct is_pointer<T* const volatile> : true_type {};
+
+/// \brief Metafunction that determines whether the given type is either an
+/// integral type or an enumeration type.
+///
+/// Note that this accepts potentially more integral types than we whitelist
+/// above for is_integral because it is based on merely being convertible
+/// implicitly to an integral type.
+template <typename T> class is_integral_or_enum {
+ // Provide an overload which can be called with anything implicitly
+ // convertible to an unsigned long long. This should catch integer types and
+ // enumeration types at least. We blacklist classes with conversion operators
+ // below.
+ static double check_int_convertible(unsigned long long);
+ static char check_int_convertible(...);
+
+ typedef typename remove_reference<T>::type UnderlyingT;
+ static UnderlyingT &nonce_instance;
+
+public:
+ enum {
+ 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)))
+ };
+};
+
+// enable_if_c - Enable/disable a template based on a metafunction
+template<bool Cond, typename T = void>
+struct enable_if_c {
+ typedef T type;
+};
+
+template<typename T> struct enable_if_c<false, T> { };
+
+// enable_if - Enable/disable a template based on a metafunction
+template<typename Cond, typename T = void>
+struct enable_if : public enable_if_c<Cond::value, T> { };
+
+namespace dont_use {
+ template<typename Base> char base_of_helper(const volatile Base*);
+ template<typename Base> double base_of_helper(...);
+}
+
+/// is_base_of - Metafunction to determine whether one type is a base class of
+/// (or identical to) another type.
+template<typename Base, typename Derived>
+struct is_base_of {
+ static const bool value
+ = is_class<Base>::value && is_class<Derived>::value &&
+ sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0));
+};
+
+// remove_pointer - Metafunction to turn Foo* into Foo. Defined in
+// C++0x [meta.trans.ptr].
+template <typename T> struct remove_pointer { typedef T type; };
+template <typename T> struct remove_pointer<T*> { typedef T type; };
+template <typename T> struct remove_pointer<T*const> { typedef T type; };
+template <typename T> struct remove_pointer<T*volatile> { typedef T type; };
+template <typename T> struct remove_pointer<T*const volatile> {
+ typedef T type; };
+
+template <bool, typename T, typename F>
+struct conditional { typedef T type; };
+
+template <typename T, typename F>
+struct conditional<false, T, F> { typedef F type; };
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/SymbolTableListTraits.h b/contrib/llvm/include/llvm/SymbolTableListTraits.h
new file mode 100644
index 000000000000..91a4eb99ff0d
--- /dev/null
+++ b/contrib/llvm/include/llvm/SymbolTableListTraits.h
@@ -0,0 +1,79 @@
+//===-- llvm/SymbolTableListTraits.h - Traits for iplist --------*- 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 generic class that is used to implement the automatic
+// symbol table manipulation that occurs when you put (for example) a named
+// instruction into a basic block.
+//
+// The way that this is implemented is by using a special traits class with the
+// intrusive list that makes up the list of instructions in a basic block. When
+// a new element is added to the list of instructions, the traits class is
+// notified, allowing the symbol table to be updated.
+//
+// This generic class implements the traits class. It must be generic so that
+// it can work for all uses it, which include lists of instructions, basic
+// blocks, arguments, functions, global variables, etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYMBOLTABLELISTTRAITS_H
+#define LLVM_SYMBOLTABLELISTTRAITS_H
+
+#include "llvm/ADT/ilist.h"
+
+namespace llvm {
+class ValueSymbolTable;
+
+template<typename NodeTy> class ilist_iterator;
+template<typename NodeTy, typename Traits> class iplist;
+template<typename Ty> struct ilist_traits;
+
+// ValueSubClass - The type of objects that I hold, e.g. Instruction.
+// ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
+//
+template<typename ValueSubClass, typename ItemParentClass>
+class SymbolTableListTraits : public ilist_default_traits<ValueSubClass> {
+ typedef ilist_traits<ValueSubClass> TraitsClass;
+public:
+ SymbolTableListTraits() {}
+
+ /// getListOwner - Return the object that owns this list. If this is a list
+ /// of instructions, it returns the BasicBlock that owns them.
+ ItemParentClass *getListOwner() {
+ typedef iplist<ValueSubClass> ItemParentClass::*Sublist;
+ size_t Offset(size_t(&((ItemParentClass*)0->*ItemParentClass::
+ getSublistAccess(static_cast<ValueSubClass*>(0)))));
+ iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this));
+ return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
+ Offset);
+ }
+
+ static iplist<ValueSubClass> &getList(ItemParentClass *Par) {
+ return Par->*(Par->getSublistAccess((ValueSubClass*)0));
+ }
+
+ static ValueSymbolTable *getSymTab(ItemParentClass *Par) {
+ return Par ? toPtr(Par->getValueSymbolTable()) : 0;
+ }
+
+ void addNodeToList(ValueSubClass *V);
+ void removeNodeFromList(ValueSubClass *V);
+ void transferNodesFromList(ilist_traits<ValueSubClass> &L2,
+ ilist_iterator<ValueSubClass> first,
+ ilist_iterator<ValueSubClass> last);
+//private:
+ template<typename TPtr>
+ void setSymTabObject(TPtr *, TPtr);
+ static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
+ static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/TableGen/Error.h b/contrib/llvm/include/llvm/TableGen/Error.h
new file mode 100644
index 000000000000..fd5f805ffc96
--- /dev/null
+++ b/contrib/llvm/include/llvm/TableGen/Error.h
@@ -0,0 +1,48 @@
+//===- llvm/TableGen/Error.h - tblgen error handling helpers ----*- 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 error handling helper routines to pretty-print diagnostic
+// messages from tblgen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_ERROR_H
+#define LLVM_TABLEGEN_ERROR_H
+
+#include "llvm/Support/SourceMgr.h"
+
+namespace llvm {
+
+class TGError {
+ SMLoc Loc;
+ std::string Message;
+public:
+ TGError(SMLoc loc, const std::string &message) : Loc(loc), Message(message) {}
+
+ SMLoc getLoc() const { return Loc; }
+ const std::string &getMessage() const { return Message; }
+};
+
+void PrintWarning(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(SMLoc ErrorLoc, const Twine &Msg);
+void PrintError(const char *Loc, const Twine &Msg);
+void PrintError(const Twine &Msg);
+void PrintError(const TGError &Error);
+
+
+extern SourceMgr SrcMgr;
+
+
+} // end namespace "llvm"
+
+#endif
diff --git a/contrib/llvm/include/llvm/TableGen/Main.h b/contrib/llvm/include/llvm/TableGen/Main.h
new file mode 100644
index 000000000000..deaef4a9908a
--- /dev/null
+++ b/contrib/llvm/include/llvm/TableGen/Main.h
@@ -0,0 +1,26 @@
+//===- llvm/TableGen/Main.h - tblgen entry point ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the common entry point for tblgen tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_MAIN_H
+#define LLVM_TABLEGEN_MAIN_H
+
+namespace llvm {
+
+class TableGenAction;
+
+/// Run the table generator, performing the specified Action on parsed records.
+int TableGenMain(char *argv0, TableGenAction &Action);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/TableGen/Record.h b/contrib/llvm/include/llvm/TableGen/Record.h
new file mode 100644
index 000000000000..3aea1aeaead3
--- /dev/null
+++ b/contrib/llvm/include/llvm/TableGen/Record.h
@@ -0,0 +1,1625 @@
+//===- llvm/TableGen/Record.h - Classes for Table Records -------*- 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 main TableGen data structures, including the TableGen
+// types, values, and high-level data structures.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_RECORD_H
+#define LLVM_TABLEGEN_RECORD_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+
+namespace llvm {
+class raw_ostream;
+
+// RecTy subclasses.
+class BitRecTy;
+class BitsRecTy;
+class IntRecTy;
+class StringRecTy;
+class ListRecTy;
+class DagRecTy;
+class RecordRecTy;
+
+// Init subclasses.
+class Init;
+class UnsetInit;
+class BitInit;
+class BitsInit;
+class IntInit;
+class StringInit;
+class ListInit;
+class UnOpInit;
+class BinOpInit;
+class TernOpInit;
+class DefInit;
+class DagInit;
+class TypedInit;
+class VarInit;
+class FieldInit;
+class VarBitInit;
+class VarListElementInit;
+
+// Other classes.
+class Record;
+class RecordVal;
+struct MultiClass;
+class RecordKeeper;
+
+//===----------------------------------------------------------------------===//
+// Type Classes
+//===----------------------------------------------------------------------===//
+
+class RecTy {
+ ListRecTy *ListTy;
+ virtual void anchor();
+public:
+ RecTy() : ListTy(0) {}
+ virtual ~RecTy() {}
+
+ virtual std::string getAsString() const = 0;
+ void print(raw_ostream &OS) const { OS << getAsString(); }
+ void dump() const;
+
+ /// typeIsConvertibleTo - Return true if all values of 'this' type can be
+ /// converted to the specified type.
+ virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
+
+ /// getListTy - Returns the type representing list<this>.
+ ListRecTy *getListTy();
+
+public: // These methods should only be called from subclasses of Init
+ virtual Init *convertValue( UnsetInit *UI) { return 0; }
+ virtual Init *convertValue( BitInit *BI) { return 0; }
+ virtual Init *convertValue( BitsInit *BI) { return 0; }
+ virtual Init *convertValue( IntInit *II) { return 0; }
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue( UnOpInit *UI) {
+ return convertValue((TypedInit*)UI);
+ }
+ virtual Init *convertValue( BinOpInit *UI) {
+ return convertValue((TypedInit*)UI);
+ }
+ virtual Init *convertValue( TernOpInit *UI) {
+ return convertValue((TypedInit*)UI);
+ }
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( TypedInit *TI) { return 0; }
+ virtual Init *convertValue( VarInit *VI) {
+ return convertValue((TypedInit*)VI);
+ }
+ virtual Init *convertValue( FieldInit *FI) {
+ 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; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
+ Ty.print(OS);
+ return OS;
+}
+
+
+/// BitRecTy - 'bit' - Represent a single bit
+///
+class BitRecTy : public RecTy {
+ static BitRecTy Shared;
+ BitRecTy() {}
+public:
+ static BitRecTy *get() { return &Shared; }
+
+ virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+ virtual Init *convertValue( BitInit *BI) { return (Init*)BI; }
+ virtual Init *convertValue( BitsInit *BI);
+ virtual Init *convertValue( IntInit *II);
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TypedInit *TI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const { return "bit"; }
+
+ 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; }
+
+};
+
+
+// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
+/// BitsRecTy - 'bits&lt;n&gt;' - Represent a fixed number of bits
+///
+class BitsRecTy : public RecTy {
+ unsigned Size;
+ explicit BitsRecTy(unsigned Sz) : Size(Sz) {}
+public:
+ static BitsRecTy *get(unsigned Sz);
+
+ unsigned getNumBits() const { return Size; }
+
+ virtual Init *convertValue( UnsetInit *UI);
+ virtual Init *convertValue( BitInit *UI);
+ virtual Init *convertValue( BitsInit *BI);
+ virtual Init *convertValue( IntInit *II);
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TypedInit *TI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const;
+
+ 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; }
+
+};
+
+
+/// IntRecTy - 'int' - Represent an integer value of no particular size
+///
+class IntRecTy : public RecTy {
+ static IntRecTy Shared;
+ IntRecTy() {}
+public:
+ static IntRecTy *get() { return &Shared; }
+
+ virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+ virtual Init *convertValue( BitInit *BI);
+ virtual Init *convertValue( BitsInit *BI);
+ virtual Init *convertValue( IntInit *II) { return (Init*)II; }
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TypedInit *TI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const { return "int"; }
+
+ 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; }
+
+};
+
+/// StringRecTy - 'string' - Represent an string value
+///
+class StringRecTy : public RecTy {
+ static StringRecTy Shared;
+ StringRecTy() {}
+public:
+ static StringRecTy *get() { return &Shared; }
+
+ virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+ virtual Init *convertValue( BitInit *BI) { return 0; }
+ virtual Init *convertValue( BitsInit *BI) { return 0; }
+ virtual Init *convertValue( IntInit *II) { return 0; }
+ virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue( UnOpInit *BO);
+ virtual Init *convertValue( BinOpInit *BO);
+ virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( TypedInit *TI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const { return "string"; }
+
+ 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
+// the specified type.
+/// ListRecTy - 'list&lt;Ty&gt;' - Represent a list of values, all of which must
+/// be of the specified type.
+///
+class ListRecTy : public RecTy {
+ RecTy *Ty;
+ explicit ListRecTy(RecTy *T) : Ty(T) {}
+ friend ListRecTy *RecTy::getListTy();
+public:
+ static ListRecTy *get(RecTy *T) { return T->getListTy(); }
+ RecTy *getElementType() const { return Ty; }
+
+ virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+ virtual Init *convertValue( BitInit *BI) { return 0; }
+ virtual Init *convertValue( BitsInit *BI) { return 0; }
+ virtual Init *convertValue( IntInit *II) { return 0; }
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI);
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TypedInit *TI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const;
+
+ 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; }
+};
+
+/// DagRecTy - 'dag' - Represent a dag fragment
+///
+class DagRecTy : public RecTy {
+ static DagRecTy Shared;
+ DagRecTy() {}
+public:
+ static DagRecTy *get() { return &Shared; }
+
+ virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+ virtual Init *convertValue( BitInit *BI) { return 0; }
+ virtual Init *convertValue( BitsInit *BI) { return 0; }
+ virtual Init *convertValue( IntInit *II) { return 0; }
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( DefInit *DI) { return 0; }
+ virtual Init *convertValue( UnOpInit *BO);
+ virtual Init *convertValue( BinOpInit *BO);
+ virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+ virtual Init *convertValue( DagInit *CI) { return (Init*)CI; }
+ virtual Init *convertValue( TypedInit *TI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const { return "dag"; }
+
+ 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; }
+};
+
+
+/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
+/// (R32 X = EAX).
+///
+class RecordRecTy : public RecTy {
+ Record *Rec;
+ explicit RecordRecTy(Record *R) : Rec(R) {}
+ friend class Record;
+public:
+ static RecordRecTy *get(Record *R);
+
+ Record *getRecord() const { return Rec; }
+
+ virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
+ virtual Init *convertValue( BitInit *BI) { return 0; }
+ virtual Init *convertValue( BitsInit *BI) { return 0; }
+ virtual Init *convertValue( IntInit *II) { return 0; }
+ virtual Init *convertValue(StringInit *SI) { return 0; }
+ virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue(VarBitInit *VB) { return 0; }
+ virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
+ virtual Init *convertValue( DefInit *DI);
+ virtual Init *convertValue( DagInit *DI) { return 0; }
+ virtual Init *convertValue( TypedInit *VI);
+ virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
+ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const;
+
+ 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;
+};
+
+/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// Return 0 if no such type exists.
+///
+RecTy *resolveTypes(RecTy *T1, RecTy *T2);
+
+//===----------------------------------------------------------------------===//
+// Initializer Classes
+//===----------------------------------------------------------------------===//
+
+class Init {
+ Init(const Init &); // Do not define.
+ Init &operator=(const Init &); // Do not define.
+ virtual void anchor();
+
+protected:
+ Init(void) {}
+
+public:
+ virtual ~Init() {}
+
+ /// isComplete - This virtual method should be overridden by values that may
+ /// not be completely specified yet.
+ virtual bool isComplete() const { return true; }
+
+ /// print - Print out this value.
+ void print(raw_ostream &OS) const { OS << getAsString(); }
+
+ /// getAsString - Convert this value to a string form.
+ virtual std::string getAsString() const = 0;
+ /// getAsUnquotedString - Convert this value to a string form,
+ /// without adding quote markers. This primaruly affects
+ /// StringInits where we will not surround the string value with
+ /// quotes.
+ virtual std::string getAsUnquotedString() const { return getAsString(); }
+
+ /// dump - Debugging method that may be called through a debugger, just
+ /// invokes print on stderr.
+ void dump() const;
+
+ /// convertInitializerTo - This virtual function is a simple call-back
+ /// function that should be overridden to call the appropriate
+ /// RecTy::convertValue method.
+ ///
+ virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
+
+ /// convertInitializerBitRange - This method is used to implement the bitrange
+ /// selection operator. Given an initializer, it selects the specified bits
+ /// out, returning them as a new init of bits type. If it is not legal to use
+ /// the bit subscript operator on this initializer, return null.
+ ///
+ virtual Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
+ return 0;
+ }
+
+ /// convertInitListSlice - This method is used to implement the list slice
+ /// selection operator. Given an initializer, it selects the specified list
+ /// elements, returning them as a new init of list type. If it is not legal
+ /// to take a slice of this, return null.
+ ///
+ virtual Init *
+ convertInitListSlice(const std::vector<unsigned> &Elements) const {
+ return 0;
+ }
+
+ /// getFieldType - This method is used to implement the FieldInit class.
+ /// Implementors of this method should return the type of the named field if
+ /// they are of record type.
+ ///
+ virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
+
+ /// getFieldInit - This method complements getFieldType to return the
+ /// initializer for the specified field. If getFieldType returns non-null
+ /// this method should return non-null, otherwise it returns null.
+ ///
+ virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const {
+ return 0;
+ }
+
+ /// resolveReferences - This method is used by classes that refer to other
+ /// variables which may not be defined at the time the expression is formed.
+ /// If a value is set for the variable later, this method will be called on
+ /// users of the value to allow the value to propagate out.
+ ///
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const {
+ return const_cast<Init *>(this);
+ }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
+ I.print(OS); return OS;
+}
+
+/// TypedInit - This is the common super-class of types that have a specific,
+/// explicit, type.
+///
+class TypedInit : public Init {
+ RecTy *Ty;
+
+ TypedInit(const TypedInit &Other); // Do not define.
+ TypedInit &operator=(const TypedInit &Other); // Do not define.
+
+protected:
+ explicit TypedInit(RecTy *T) : Ty(T) {}
+
+public:
+ RecTy *getType() const { return Ty; }
+
+ virtual Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
+ virtual Init *
+ convertInitListSlice(const std::vector<unsigned> &Elements) const;
+
+ /// getFieldType - This method is used to implement the FieldInit class.
+ /// Implementors of this method should return the type of the named field if
+ /// they are of record type.
+ ///
+ virtual RecTy *getFieldType(const std::string &FieldName) const;
+
+ /// resolveBitReference - This method is used to implement
+ /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
+ /// simply return the resolved value, otherwise we return null.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const = 0;
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const = 0;
+};
+
+
+/// 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.
+ virtual void anchor();
+
+public:
+ static UnsetInit *get();
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<UnsetInit *>(this));
+ }
+
+ virtual bool isComplete() const { return false; }
+ virtual std::string getAsString() const { return "?"; }
+};
+
+
+/// BitInit - true/false - Represent a concrete initializer for a bit.
+///
+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.
+ virtual void anchor();
+
+public:
+ static BitInit *get(bool V);
+
+ bool getValue() const { return Value; }
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<BitInit *>(this));
+ }
+
+ virtual std::string getAsString() const { return Value ? "1" : "0"; }
+};
+
+/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
+/// It contains a vector of bits, whose size is determined by the type.
+///
+class BitsInit : public Init, public FoldingSetNode {
+ std::vector<Init*> Bits;
+
+ BitsInit(ArrayRef<Init *> Range) : Bits(Range.begin(), Range.end()) {}
+
+ BitsInit(const BitsInit &Other); // Do not define.
+ BitsInit &operator=(const BitsInit &Other); // Do not define.
+
+public:
+ static BitsInit *get(ArrayRef<Init *> Range);
+
+ void Profile(FoldingSetNodeID &ID) const;
+
+ unsigned getNumBits() const { return Bits.size(); }
+
+ Init *getBit(unsigned Bit) const {
+ assert(Bit < Bits.size() && "Bit index out of range!");
+ return Bits[Bit];
+ }
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<BitsInit *>(this));
+ }
+ virtual Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
+
+ virtual bool isComplete() const {
+ for (unsigned i = 0; i != getNumBits(); ++i)
+ if (!getBit(i)->isComplete()) return false;
+ return true;
+ }
+ bool allInComplete() const {
+ for (unsigned i = 0; i != getNumBits(); ++i)
+ if (getBit(i)->isComplete()) return false;
+ return true;
+ }
+ virtual std::string getAsString() const;
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+};
+
+
+/// IntInit - 7 - Represent an initalization by a literal integer value.
+///
+class IntInit : public TypedInit {
+ int64_t Value;
+
+ explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {}
+
+ IntInit(const IntInit &Other); // Do not define.
+ IntInit &operator=(const IntInit &Other); // Do note define.
+
+public:
+ static IntInit *get(int64_t V);
+
+ int64_t getValue() const { return Value; }
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<IntInit *>(this));
+ }
+ virtual Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
+
+ virtual std::string getAsString() const;
+
+ /// resolveBitReference - This method is used to implement
+ /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
+ /// simply return the resolved value, otherwise we return null.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const {
+ llvm_unreachable("Illegal bit reference off int");
+ }
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const {
+ llvm_unreachable("Illegal element reference off int");
+ }
+};
+
+
+/// StringInit - "foo" - Represent an initialization by a string value.
+///
+class StringInit : public TypedInit {
+ std::string Value;
+
+ explicit StringInit(const std::string &V)
+ : TypedInit(StringRecTy::get()), Value(V) {}
+
+ StringInit(const StringInit &Other); // Do not define.
+ StringInit &operator=(const StringInit &Other); // Do not define.
+ virtual void anchor();
+
+public:
+ static StringInit *get(StringRef);
+
+ const std::string &getValue() const { return Value; }
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<StringInit *>(this));
+ }
+
+ virtual std::string getAsString() const { return "\"" + Value + "\""; }
+ virtual std::string getAsUnquotedString() const { return Value; }
+
+ /// resolveBitReference - This method is used to implement
+ /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
+ /// simply return the resolved value, otherwise we return null.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const {
+ llvm_unreachable("Illegal bit reference off string");
+ }
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const {
+ llvm_unreachable("Illegal element reference off string");
+ }
+};
+
+/// ListInit - [AL, AH, CL] - Represent a list of defs
+///
+class ListInit : public TypedInit, public FoldingSetNode {
+ std::vector<Init*> Values;
+public:
+ typedef std::vector<Init*>::const_iterator const_iterator;
+
+private:
+ explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy)
+ : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {}
+
+ ListInit(const ListInit &Other); // Do not define.
+ ListInit &operator=(const ListInit &Other); // Do not define.
+
+public:
+ static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
+
+ void Profile(FoldingSetNodeID &ID) const;
+
+ unsigned getSize() const { return Values.size(); }
+ Init *getElement(unsigned i) const {
+ assert(i < Values.size() && "List element index out of range!");
+ return Values[i];
+ }
+
+ Record *getElementAsRecord(unsigned i) const;
+
+ Init *convertInitListSlice(const std::vector<unsigned> &Elements) const;
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<ListInit *>(this));
+ }
+
+ /// resolveReferences - This method is used by classes that refer to other
+ /// variables which may not be defined at the time they expression is formed.
+ /// If a value is set for the variable later, this method will be called on
+ /// users of the value to allow the value to propagate out.
+ ///
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+
+ ArrayRef<Init*> getValues() const { return Values; }
+
+ inline const_iterator begin() const { return Values.begin(); }
+ inline const_iterator end () const { return Values.end(); }
+
+ inline size_t size () const { return Values.size(); }
+ inline bool empty() const { return Values.empty(); }
+
+ /// resolveBitReference - This method is used to implement
+ /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
+ /// simply return the resolved value, otherwise we return null.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const {
+ llvm_unreachable("Illegal bit reference off list");
+ }
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const;
+};
+
+
+/// OpInit - Base class for operators
+///
+class OpInit : public TypedInit {
+ OpInit(const OpInit &Other); // Do not define.
+ OpInit &operator=(OpInit &Other); // Do not define.
+
+protected:
+ explicit OpInit(RecTy *Type) : TypedInit(Type) {}
+
+public:
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
+
+ virtual int getNumOperands() const = 0;
+ virtual Init *getOperand(int i) const = 0;
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<OpInit *>(this));
+ }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const;
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const;
+};
+
+
+/// UnOpInit - !op (X) - Transform an init.
+///
+class UnOpInit : public OpInit {
+public:
+ enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
+private:
+ UnaryOp Opc;
+ Init *LHS;
+
+ UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
+ : OpInit(Type), Opc(opc), LHS(lhs) {}
+
+ UnOpInit(const UnOpInit &Other); // Do not define.
+ UnOpInit &operator=(const UnOpInit &Other); // Do not define.
+
+public:
+ static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) const {
+ assert(Operands.size() == 1 &&
+ "Wrong number of operands for unary operation");
+ return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
+ }
+
+ int getNumOperands() const { return 1; }
+ Init *getOperand(int i) const {
+ assert(i == 0 && "Invalid operand id for unary operator");
+ return getOperand();
+ }
+
+ UnaryOp getOpcode() const { return Opc; }
+ Init *getOperand() const { return LHS; }
+
+ // 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 *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+};
+
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public OpInit {
+public:
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
+private:
+ BinaryOp Opc;
+ Init *LHS, *RHS;
+
+ BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
+ OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {}
+
+ BinOpInit(const BinOpInit &Other); // Do not define.
+ BinOpInit &operator=(const BinOpInit &Other); // Do not define.
+
+public:
+ static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
+ RecTy *Type);
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) const {
+ assert(Operands.size() == 2 &&
+ "Wrong number of operands for binary operation");
+ return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
+ }
+
+ int getNumOperands() const { return 2; }
+ Init *getOperand(int i) const {
+ assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
+ if (i == 0) {
+ return getLHS();
+ } else {
+ return getRHS();
+ }
+ }
+
+ BinaryOp getOpcode() const { return Opc; }
+ Init *getLHS() const { return LHS; }
+ Init *getRHS() const { return RHS; }
+
+ // 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 *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+};
+
+/// TernOpInit - !op (X, Y, Z) - Combine two inits.
+///
+class TernOpInit : public OpInit {
+public:
+ enum TernaryOp { SUBST, FOREACH, IF };
+private:
+ TernaryOp Opc;
+ Init *LHS, *MHS, *RHS;
+
+ TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
+ RecTy *Type) :
+ OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
+
+ TernOpInit(const TernOpInit &Other); // Do not define.
+ TernOpInit &operator=(const TernOpInit &Other); // Do not define.
+
+public:
+ static TernOpInit *get(TernaryOp opc, Init *lhs,
+ Init *mhs, Init *rhs,
+ RecTy *Type);
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) const {
+ assert(Operands.size() == 3 &&
+ "Wrong number of operands for ternary operation");
+ return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
+ getType());
+ }
+
+ int getNumOperands() const { return 3; }
+ Init *getOperand(int i) const {
+ assert((i == 0 || i == 1 || i == 2) &&
+ "Invalid operand id for ternary operator");
+ if (i == 0) {
+ return getLHS();
+ } else if (i == 1) {
+ return getMHS();
+ } else {
+ return getRHS();
+ }
+ }
+
+ TernaryOp getOpcode() const { return Opc; }
+ Init *getLHS() const { return LHS; }
+ Init *getMHS() const { return MHS; }
+ Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+
+ virtual bool isComplete() const { return false; }
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+};
+
+
+/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
+///
+class VarInit : public TypedInit {
+ Init *VarName;
+
+ explicit VarInit(const std::string &VN, RecTy *T)
+ : TypedInit(T), VarName(StringInit::get(VN)) {}
+ explicit VarInit(Init *VN, RecTy *T)
+ : TypedInit(T), VarName(VN) {}
+
+ VarInit(const VarInit &Other); // Do not define.
+ VarInit &operator=(const VarInit &Other); // Do not define.
+
+public:
+ static VarInit *get(const std::string &VN, RecTy *T);
+ static VarInit *get(Init *VN, RecTy *T);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<VarInit *>(this));
+ }
+
+ const std::string &getName() const;
+ Init *getNameInit() const { return VarName; }
+ std::string getNameInitAsString() const {
+ return getNameInit()->getAsUnquotedString();
+ }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const;
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const;
+
+ virtual RecTy *getFieldType(const std::string &FieldName) const;
+ virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const;
+
+ /// resolveReferences - This method is used by classes that refer to other
+ /// variables which may not be defined at the time they expression is formed.
+ /// If a value is set for the variable later, this method will be called on
+ /// users of the value to allow the value to propagate out.
+ ///
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const { return getName(); }
+};
+
+
+/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
+///
+class VarBitInit : public Init {
+ TypedInit *TI;
+ unsigned Bit;
+
+ VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
+ assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) &&
+ ((BitsRecTy*)T->getType())->getNumBits() > B &&
+ "Illegal VarBitInit expression!");
+ }
+
+ VarBitInit(const VarBitInit &Other); // Do not define.
+ VarBitInit &operator=(const VarBitInit &Other); // Do not define.
+
+public:
+ static VarBitInit *get(TypedInit *T, unsigned B);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<VarBitInit *>(this));
+ }
+
+ TypedInit *getVariable() const { return TI; }
+ unsigned getBitNum() const { return Bit; }
+
+ virtual std::string getAsString() const;
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+};
+
+/// VarListElementInit - List[4] - Represent access to one element of a var or
+/// field.
+class VarListElementInit : public TypedInit {
+ TypedInit *TI;
+ 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()) &&
+ "Illegal VarBitInit expression!");
+ }
+
+ VarListElementInit(const VarListElementInit &Other); // Do not define.
+ VarListElementInit &operator=(const VarListElementInit &Other); // Do
+ // not
+ // define.
+
+public:
+ static VarListElementInit *get(TypedInit *T, unsigned E);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<VarListElementInit *>(this));
+ }
+
+ TypedInit *getVariable() const { return TI; }
+ unsigned getElementNum() const { return Element; }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const;
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R,
+ const RecordVal *RV,
+ unsigned Elt) const;
+
+ virtual std::string getAsString() const;
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+};
+
+/// DefInit - AL - Represent a reference to a 'def' in the description
+///
+class DefInit : public TypedInit {
+ Record *Def;
+
+ DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {}
+ friend class Record;
+
+ DefInit(const DefInit &Other); // Do not define.
+ DefInit &operator=(const DefInit &Other); // Do not define.
+
+public:
+ static DefInit *get(Record*);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<DefInit *>(this));
+ }
+
+ Record *getDef() const { return Def; }
+
+ //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
+
+ virtual RecTy *getFieldType(const std::string &FieldName) const;
+ virtual Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const;
+
+ virtual std::string getAsString() const;
+
+ /// resolveBitReference - This method is used to implement
+ /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
+ /// simply return the resolved value, otherwise we return null.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const {
+ llvm_unreachable("Illegal bit reference off def");
+ }
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const {
+ llvm_unreachable("Illegal element reference off def");
+ }
+};
+
+
+/// FieldInit - X.Y - Represent a reference to a subfield of a variable
+///
+class FieldInit : public TypedInit {
+ Init *Rec; // Record we are referring to
+ std::string FieldName; // Field we are accessing
+
+ FieldInit(Init *R, const std::string &FN)
+ : TypedInit(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.
+
+public:
+ static FieldInit *get(Init *R, const std::string &FN);
+ static FieldInit *get(Init *R, const Init *FN);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<FieldInit *>(this));
+ }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const;
+ virtual Init *resolveListElementReference(Record &R,
+ const RecordVal *RV,
+ unsigned Elt) const;
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const {
+ return Rec->getAsString() + "." + FieldName;
+ }
+};
+
+/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required
+/// to have at least one value then a (possibly empty) list of arguments. Each
+/// argument can have a name associated with it.
+///
+class DagInit : public TypedInit, public FoldingSetNode {
+ Init *Val;
+ std::string ValName;
+ std::vector<Init*> Args;
+ std::vector<std::string> ArgNames;
+
+ DagInit(Init *V, const std::string &VN,
+ ArrayRef<Init *> ArgRange,
+ ArrayRef<std::string> NameRange)
+ : TypedInit(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.
+
+public:
+ static DagInit *get(Init *V, const std::string &VN,
+ ArrayRef<Init *> ArgRange,
+ ArrayRef<std::string> NameRange);
+ static DagInit *get(Init *V, const std::string &VN,
+ const std::vector<
+ std::pair<Init*, std::string> > &args);
+
+ void Profile(FoldingSetNodeID &ID) const;
+
+ virtual Init *convertInitializerTo(RecTy *Ty) const {
+ return Ty->convertValue(const_cast<DagInit *>(this));
+ }
+
+ Init *getOperator() const { return Val; }
+
+ const std::string &getName() const { return ValName; }
+
+ unsigned getNumArgs() const { return Args.size(); }
+ Init *getArg(unsigned Num) const {
+ assert(Num < Args.size() && "Arg number out of range!");
+ return Args[Num];
+ }
+ const std::string &getArgName(unsigned Num) const {
+ assert(Num < ArgNames.size() && "Arg number out of range!");
+ return ArgNames[Num];
+ }
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+
+ typedef std::vector<Init*>::const_iterator const_arg_iterator;
+ typedef std::vector<std::string>::const_iterator const_name_iterator;
+
+ inline const_arg_iterator arg_begin() const { return Args.begin(); }
+ inline const_arg_iterator arg_end () const { return Args.end(); }
+
+ inline size_t arg_size () const { return Args.size(); }
+ inline bool arg_empty() const { return Args.empty(); }
+
+ inline const_name_iterator name_begin() const { return ArgNames.begin(); }
+ inline const_name_iterator name_end () const { return ArgNames.end(); }
+
+ inline size_t name_size () const { return ArgNames.size(); }
+ inline bool name_empty() const { return ArgNames.empty(); }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) const {
+ llvm_unreachable("Illegal bit reference off dag");
+ }
+
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const {
+ llvm_unreachable("Illegal element reference off dag");
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// High-Level Classes
+//===----------------------------------------------------------------------===//
+
+class RecordVal {
+ Init *Name;
+ RecTy *Ty;
+ unsigned Prefix;
+ Init *Value;
+public:
+ RecordVal(Init *N, RecTy *T, unsigned P);
+ RecordVal(const std::string &N, RecTy *T, unsigned P);
+
+ const std::string &getName() const;
+ const Init *getNameInit() const { return Name; }
+ std::string getNameInitAsString() const {
+ return getNameInit()->getAsUnquotedString();
+ }
+
+ unsigned getPrefix() const { return Prefix; }
+ RecTy *getType() const { return Ty; }
+ Init *getValue() const { return Value; }
+
+ bool setValue(Init *V) {
+ if (V) {
+ Value = V->convertInitializerTo(Ty);
+ return Value == 0;
+ }
+ Value = 0;
+ return false;
+ }
+
+ void dump() const;
+ void print(raw_ostream &OS, bool PrintSem = true) const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
+ RV.print(OS << " ");
+ return OS;
+}
+
+class Record {
+ static unsigned LastID;
+
+ // Unique record ID.
+ unsigned ID;
+ Init *Name;
+ SMLoc Loc;
+ std::vector<Init *> TemplateArgs;
+ std::vector<RecordVal> Values;
+ std::vector<Record*> SuperClasses;
+
+ // Tracks Record instances. Not owned by Record.
+ RecordKeeper &TrackedRecords;
+
+ DefInit *TheInit;
+
+ void init();
+ void checkName();
+
+public:
+
+ // Constructs a record.
+ explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) :
+ ID(LastID++), Name(StringInit::get(N)), Loc(loc), TrackedRecords(records),
+ TheInit(0) {
+ init();
+ }
+ explicit Record(Init *N, SMLoc loc, RecordKeeper &records) :
+ ID(LastID++), Name(N), Loc(loc), TrackedRecords(records), TheInit(0) {
+ init();
+ }
+ ~Record() {}
+
+
+ static unsigned getNewUID() { return LastID++; }
+
+
+ unsigned getID() const { return ID; }
+
+ const std::string &getName() const;
+ Init *getNameInit() const {
+ return Name;
+ }
+ const std::string getNameInitAsString() const {
+ return getNameInit()->getAsUnquotedString();
+ }
+
+ void setName(Init *Name); // Also updates RecordKeeper.
+ void setName(const std::string &Name); // Also updates RecordKeeper.
+
+ SMLoc getLoc() const { return Loc; }
+
+ /// get the corresponding DefInit.
+ DefInit *getDefInit();
+
+ const std::vector<Init *> &getTemplateArgs() const {
+ return TemplateArgs;
+ }
+ const std::vector<RecordVal> &getValues() const { return Values; }
+ const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
+
+ bool isTemplateArg(Init *Name) const {
+ for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
+ if (TemplateArgs[i] == Name) return true;
+ return false;
+ }
+ bool isTemplateArg(StringRef Name) const {
+ return isTemplateArg(StringInit::get(Name.str()));
+ }
+
+ const RecordVal *getValue(const Init *Name) const {
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ if (Values[i].getNameInit() == Name) return &Values[i];
+ return 0;
+ }
+ const RecordVal *getValue(StringRef Name) const {
+ return getValue(StringInit::get(Name));
+ }
+ RecordVal *getValue(const Init *Name) {
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ if (Values[i].getNameInit() == Name) return &Values[i];
+ return 0;
+ }
+ RecordVal *getValue(StringRef Name) {
+ return getValue(StringInit::get(Name));
+ }
+
+ void addTemplateArg(Init *Name) {
+ assert(!isTemplateArg(Name) && "Template arg already defined!");
+ TemplateArgs.push_back(Name);
+ }
+ void addTemplateArg(StringRef Name) {
+ addTemplateArg(StringInit::get(Name.str()));
+ }
+
+ void addValue(const RecordVal &RV) {
+ assert(getValue(RV.getNameInit()) == 0 && "Value already added!");
+ Values.push_back(RV);
+ if (Values.size() > 1)
+ // Keep NAME at the end of the list. It makes record dumps a
+ // bit prettier and allows TableGen tests to be written more
+ // naturally. Tests can use CHECK-NEXT to look for Record
+ // fields they expect to see after a def. They can't do that if
+ // NAME is the first Record field.
+ std::swap(Values[Values.size() - 2], Values[Values.size() - 1]);
+ }
+
+ void removeValue(Init *Name) {
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ if (Values[i].getNameInit() == Name) {
+ Values.erase(Values.begin()+i);
+ return;
+ }
+ llvm_unreachable("Cannot remove an entry that does not exist!");
+ }
+
+ void removeValue(StringRef Name) {
+ removeValue(StringInit::get(Name.str()));
+ }
+
+ bool isSubClassOf(const Record *R) const {
+ for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+ if (SuperClasses[i] == R)
+ return true;
+ return false;
+ }
+
+ bool isSubClassOf(StringRef Name) const {
+ for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
+ if (SuperClasses[i]->getNameInitAsString() == Name)
+ return true;
+ return false;
+ }
+
+ void addSuperClass(Record *R) {
+ assert(!isSubClassOf(R) && "Already subclassing record!");
+ SuperClasses.push_back(R);
+ }
+
+ /// resolveReferences - If there are any field references that refer to fields
+ /// that have been filled in, we can propagate the values now.
+ ///
+ void resolveReferences() { resolveReferencesTo(0); }
+
+ /// resolveReferencesTo - If anything in this record refers to RV, replace the
+ /// reference to RV with the RHS of RV. If RV is null, we resolve all
+ /// possible references.
+ void resolveReferencesTo(const RecordVal *RV);
+
+ RecordKeeper &getRecords() const {
+ return TrackedRecords;
+ }
+
+ void dump() const;
+
+ //===--------------------------------------------------------------------===//
+ // High-level methods useful to tablegen back-ends
+ //
+
+ /// getValueInit - Return the initializer for a value with the specified name,
+ /// or throw an exception if the field does not exist.
+ ///
+ Init *getValueInit(StringRef FieldName) const;
+
+ /// getValueAsString - This method looks up the specified field and returns
+ /// its value as a string, throwing an exception if the field does not exist
+ /// or if the value is not a string.
+ ///
+ std::string getValueAsString(StringRef FieldName) const;
+
+ /// getValueAsBitsInit - This method looks up the specified field and returns
+ /// its value as a BitsInit, throwing an exception if the field does not exist
+ /// or if the value is not the right type.
+ ///
+ BitsInit *getValueAsBitsInit(StringRef FieldName) const;
+
+ /// getValueAsListInit - This method looks up the specified field and returns
+ /// its value as a ListInit, throwing an exception if the field does not exist
+ /// or if the value is not the right type.
+ ///
+ ListInit *getValueAsListInit(StringRef FieldName) const;
+
+ /// getValueAsListOfDefs - This method looks up the specified field and
+ /// returns its value as a vector of records, throwing an exception if the
+ /// field does not exist or if the value is not the right type.
+ ///
+ std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
+
+ /// getValueAsListOfInts - This method looks up the specified field and
+ /// returns its value as a vector of integers, throwing an exception if the
+ /// field does not exist or if the value is not the right type.
+ ///
+ std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
+
+ /// getValueAsListOfStrings - This method looks up the specified field and
+ /// returns its value as a vector of strings, throwing an exception if the
+ /// field does not exist or if the value is not the right type.
+ ///
+ std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const;
+
+ /// getValueAsDef - This method looks up the specified field and returns its
+ /// value as a Record, throwing an exception if the field does not exist or if
+ /// the value is not the right type.
+ ///
+ Record *getValueAsDef(StringRef FieldName) const;
+
+ /// getValueAsBit - This method looks up the specified field and returns its
+ /// value as a bit, throwing an exception if the field does not exist or if
+ /// the value is not the right type.
+ ///
+ bool getValueAsBit(StringRef FieldName) const;
+
+ /// getValueAsInt - This method looks up the specified field and returns its
+ /// value as an int64_t, throwing an exception if the field does not exist or
+ /// if the value is not the right type.
+ ///
+ int64_t getValueAsInt(StringRef FieldName) const;
+
+ /// getValueAsDag - This method looks up the specified field and returns its
+ /// value as an Dag, throwing an exception if the field does not exist or if
+ /// the value is not the right type.
+ ///
+ DagInit *getValueAsDag(StringRef FieldName) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const Record &R);
+
+struct MultiClass {
+ Record Rec; // Placeholder for template args and Name.
+ typedef std::vector<Record*> RecordVector;
+ RecordVector DefPrototypes;
+
+ void dump() const;
+
+ MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
+ Rec(Name, Loc, Records) {}
+};
+
+class RecordKeeper {
+ std::map<std::string, Record*> Classes, Defs;
+
+public:
+ ~RecordKeeper() {
+ for (std::map<std::string, Record*>::iterator I = Classes.begin(),
+ E = Classes.end(); I != E; ++I)
+ delete I->second;
+ for (std::map<std::string, Record*>::iterator I = Defs.begin(),
+ E = Defs.end(); I != E; ++I)
+ delete I->second;
+ }
+
+ const std::map<std::string, Record*> &getClasses() const { return Classes; }
+ const std::map<std::string, Record*> &getDefs() const { return Defs; }
+
+ Record *getClass(const std::string &Name) const {
+ std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
+ return I == Classes.end() ? 0 : I->second;
+ }
+ Record *getDef(const std::string &Name) const {
+ std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
+ return I == Defs.end() ? 0 : I->second;
+ }
+ void addClass(Record *R) {
+ assert(getClass(R->getNameInitAsString()) == 0 && "Class already exists!");
+ Classes.insert(std::make_pair(R->getNameInitAsString(), R));
+ }
+ void addDef(Record *R) {
+ assert(getDef(R->getNameInitAsString()) == 0 && "Def already exists!");
+ Defs.insert(std::make_pair(R->getNameInitAsString(), R));
+ }
+
+ /// removeClass - Remove, but do not delete, the specified record.
+ ///
+ void removeClass(const std::string &Name) {
+ assert(Classes.count(Name) && "Class does not exist!");
+ Classes.erase(Name);
+ }
+ /// removeDef - Remove, but do not delete, the specified record.
+ ///
+ void removeDef(const std::string &Name) {
+ assert(Defs.count(Name) && "Def does not exist!");
+ Defs.erase(Name);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // High-level helper methods, useful for tablegen backends...
+
+ /// getAllDerivedDefinitions - This method returns all concrete definitions
+ /// that derive from the specified class name. If a class with the specified
+ /// name does not exist, an exception is thrown.
+ std::vector<Record*>
+ getAllDerivedDefinitions(const std::string &ClassName) const;
+
+ void dump() const;
+};
+
+/// LessRecord - Sorting predicate to sort record pointers by name.
+///
+struct LessRecord {
+ bool operator()(const Record *Rec1, const Record *Rec2) const {
+ return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
+ }
+};
+
+/// LessRecordFieldName - Sorting predicate to sort record pointers by their
+/// name field.
+///
+struct LessRecordFieldName {
+ bool operator()(const Record *Rec1, const Record *Rec2) const {
+ return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
+ }
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
+
+/// QualifyName - Return an Init with a qualifier prefix referring
+/// to CurRec's name.
+Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
+ Init *Name, const std::string &Scoper);
+
+/// QualifyName - Return an Init with a qualifier prefix referring
+/// to CurRec's name.
+Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
+ const std::string &Name, const std::string &Scoper);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/TableGen/TableGenAction.h b/contrib/llvm/include/llvm/TableGen/TableGenAction.h
new file mode 100644
index 000000000000..733ae626447c
--- /dev/null
+++ b/contrib/llvm/include/llvm/TableGen/TableGenAction.h
@@ -0,0 +1,35 @@
+//===- 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/contrib/llvm/include/llvm/TableGen/TableGenBackend.h b/contrib/llvm/include/llvm/TableGen/TableGenBackend.h
new file mode 100644
index 000000000000..3ebcd92d0e48
--- /dev/null
+++ b/contrib/llvm/include/llvm/TableGen/TableGenBackend.h
@@ -0,0 +1,43 @@
+//===- llvm/TableGen/TableGenBackend.h - Backend base class -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The TableGenBackend class is provided as a common interface for all TableGen
+// backends. It provides useful services and an standardized interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_TABLEGENBACKEND_H
+#define LLVM_TABLEGEN_TABLEGENBACKEND_H
+
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class Record;
+class RecordKeeper;
+
+struct TableGenBackend {
+ virtual void anchor();
+ virtual ~TableGenBackend() {}
+
+ // run - All TableGen backends should implement the run method, which should
+ // be the main entry point.
+ virtual void run(raw_ostream &OS) = 0;
+
+
+public: // Useful helper routines...
+ /// EmitSourceFileHeader - Output a LLVM style file header to the specified
+ /// ostream.
+ void EmitSourceFileHeader(StringRef Desc, raw_ostream &OS) const;
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/Mangler.h b/contrib/llvm/include/llvm/Target/Mangler.h
new file mode 100644
index 000000000000..d5e165e58b91
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/Mangler.h
@@ -0,0 +1,73 @@
+//===-- llvm/Target/Mangler.h - Self-contained name mangler -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for various backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANGLER_H
+#define LLVM_SUPPORT_MANGLER_H
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+class Twine;
+class GlobalValue;
+template <typename T> class SmallVectorImpl;
+class MCContext;
+class MCSymbol;
+class TargetData;
+
+class Mangler {
+public:
+ enum ManglerPrefixTy {
+ Default, ///< Emit default string before each symbol.
+ Private, ///< Emit "private" prefix before each symbol.
+ LinkerPrivate ///< Emit "linker private" prefix before each symbol.
+ };
+
+private:
+ MCContext &Context;
+ const TargetData &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
+ /// ones.
+ ///
+ DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
+
+ /// NextAnonGlobalID - This simple counter is used to unique value names.
+ ///
+ unsigned NextAnonGlobalID;
+
+public:
+ Mangler(MCContext &context, const TargetData &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.
+ void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
+ ManglerPrefixTy PrefixTy = Mangler::Default);
+};
+
+} // End llvm namespace
+
+#endif // LLVM_SUPPORT_MANGLER_H
diff --git a/contrib/llvm/include/llvm/Target/Target.td b/contrib/llvm/include/llvm/Target/Target.td
new file mode 100644
index 000000000000..fa1ec5594522
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/Target.td
@@ -0,0 +1,928 @@
+//===- Target.td - Target Independent TableGen interface ---*- 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 the target-independent interfaces which should be
+// implemented by each target which is using a TableGen based code generator.
+//
+//===----------------------------------------------------------------------===//
+
+// Include all information about LLVM intrinsics.
+include "llvm/Intrinsics.td"
+
+//===----------------------------------------------------------------------===//
+// Register file description - These classes are used to fill in the target
+// description classes.
+
+class RegisterClass; // Forward def
+
+// SubRegIndex - Use instances of SubRegIndex to identify subregisters.
+class SubRegIndex<list<SubRegIndex> comps = []> {
+ string Namespace = "";
+
+ // ComposedOf - A list of two SubRegIndex instances, [A, B].
+ // This indicates that this SubRegIndex is the result of composing A and B.
+ list<SubRegIndex> ComposedOf = comps;
+}
+
+// RegAltNameIndex - The alternate name set to use for register operands of
+// this register class when printing.
+class RegAltNameIndex {
+ string Namespace = "";
+}
+def NoRegAltName : RegAltNameIndex;
+
+// Register - You should define one instance of this class for each register
+// in the target machine. String n will become the "name" of the register.
+class Register<string n, list<string> altNames = []> {
+ string Namespace = "";
+ string AsmName = n;
+ list<string> AltNames = altNames;
+
+ // Aliases - A list of registers that this register overlaps with. A read or
+ // modification of this register can potentially read or modify the aliased
+ // registers.
+ list<Register> Aliases = [];
+
+ // SubRegs - A list of registers that are parts of this register. Note these
+ // are "immediate" sub-registers and the registers within the list do not
+ // themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX],
+ // not [AX, AH, AL].
+ list<Register> SubRegs = [];
+
+ // SubRegIndices - For each register in SubRegs, specify the SubRegIndex used
+ // to address it. Sub-sub-register indices are automatically inherited from
+ // SubRegs.
+ list<SubRegIndex> SubRegIndices = [];
+
+ // RegAltNameIndices - The alternate name indices which are valid for this
+ // register.
+ list<RegAltNameIndex> RegAltNameIndices = [];
+
+ // CompositeIndices - Specify subreg indices that don't correspond directly to
+ // a register in SubRegs and are not inherited. The following formats are
+ // supported:
+ //
+ // (a) Identity - Reg:a == Reg
+ // (a b) Alias - Reg:a == Reg:b
+ // (a b,c) Composite - Reg:a == (Reg:b):c
+ //
+ // This can be used to disambiguate a sub-sub-register that exists in more
+ // than one subregister and other weird stuff.
+ list<dag> CompositeIndices = [];
+
+ // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register.
+ // These values can be determined by locating the <target>.h file in the
+ // directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The
+ // order of these names correspond to the enumeration used by gcc. A value of
+ // -1 indicates that the gcc number is undefined and -2 that register number
+ // is invalid for this mode/flavour.
+ list<int> DwarfNumbers = [];
+
+ // CostPerUse - Additional cost of instructions using this register compared
+ // to other registers in its class. The register allocator will try to
+ // minimize the number of instructions using a register with a CostPerUse.
+ // This is used by the x86-64 and ARM Thumb targets where some registers
+ // require larger instruction encodings.
+ int CostPerUse = 0;
+
+ // CoveredBySubRegs - When this bit is set, the value of this register is
+ // completely determined by the value of its sub-registers. For example, the
+ // x86 register AX is covered by its sub-registers AL and AH, but EAX is not
+ // covered by its sub-register AX.
+ bit CoveredBySubRegs = 0;
+}
+
+// RegisterWithSubRegs - This can be used to define instances of Register which
+// need to specify sub-registers.
+// List "subregs" specifies which registers are sub-registers to this one. This
+// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc.
+// This allows the code generator to be careful not to put two values with
+// overlapping live ranges into registers which alias.
+class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
+ let SubRegs = subregs;
+}
+
+// RegisterClass - Now that all of the registers are defined, and aliases
+// between registers are defined, specify which registers belong to which
+// register classes. This also defines the default allocation order of
+// registers by register allocators.
+//
+class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
+ dag regList, RegAltNameIndex idx = NoRegAltName> {
+ string Namespace = namespace;
+
+ // RegType - Specify the list ValueType of the registers in this register
+ // class. Note that all registers in a register class must have the same
+ // ValueTypes. This is a list because some targets permit storing different
+ // types in same register, for example vector values with 128-bit total size,
+ // but different count/size of items, like SSE on x86.
+ //
+ list<ValueType> RegTypes = regTypes;
+
+ // Size - Specify the spill size in bits of the registers. A default value of
+ // zero lets tablgen pick an appropriate size.
+ int Size = 0;
+
+ // Alignment - Specify the alignment required of the registers when they are
+ // stored or loaded to memory.
+ //
+ int Alignment = alignment;
+
+ // CopyCost - This value is used to specify the cost of copying a value
+ // between two registers in this register class. The default value is one
+ // meaning it takes a single instruction to perform the copying. A negative
+ // value means copying is extremely expensive or impossible.
+ int CopyCost = 1;
+
+ // MemberList - Specify which registers are in this class. If the
+ // allocation_order_* method are not specified, this also defines the order of
+ // allocation used by the register allocator.
+ //
+ dag MemberList = regList;
+
+ // AltNameIndex - The alternate register name to use when printing operands
+ // of this register class. Every register in the register class must have
+ // a valid alternate name for the given index.
+ RegAltNameIndex altNameIndex = idx;
+
+ // SubRegClasses - Specify the register class of subregisters as a list of
+ // dags: (RegClass SubRegIndex, SubRegindex, ...)
+ list<dag> SubRegClasses = [];
+
+ // isAllocatable - Specify that the register class can be used for virtual
+ // registers and register allocation. Some register classes are only used to
+ // model instruction operand constraints, and should have isAllocatable = 0.
+ bit isAllocatable = 1;
+
+ // AltOrders - List of alternative allocation orders. The default order is
+ // MemberList itself, and that is good enough for most targets since the
+ // register allocators automatically remove reserved registers and move
+ // callee-saved registers to the end.
+ list<dag> AltOrders = [];
+
+ // AltOrderSelect - The body of a function that selects the allocation order
+ // to use in a given machine function. The code will be inserted in a
+ // function like this:
+ //
+ // static inline unsigned f(const MachineFunction &MF) { ... }
+ //
+ // The function should return 0 to select the default order defined by
+ // MemberList, 1 to select the first AltOrders entry and so on.
+ code AltOrderSelect = [{}];
+}
+
+// The memberList in a RegisterClass is a dag of set operations. TableGen
+// evaluates these set operations and expand them into register lists. These
+// are the most common operation, see test/TableGen/SetTheory.td for more
+// examples of what is possible:
+//
+// (add R0, R1, R2) - Set Union. Each argument can be an individual register, a
+// register class, or a sub-expression. This is also the way to simply list
+// registers.
+//
+// (sub GPR, SP) - Set difference. Subtract the last arguments from the first.
+//
+// (and GPR, CSR) - Set intersection. All registers from the first set that are
+// also in the second set.
+//
+// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of
+// numbered registers.
+//
+// (shl GPR, 4) - Remove the first N elements.
+//
+// (trunc GPR, 4) - Truncate after the first N elements.
+//
+// (rotl GPR, 1) - Rotate N places to the left.
+//
+// (rotr GPR, 1) - Rotate N places to the right.
+//
+// (decimate GPR, 2) - Pick every N'th element, starting with the first.
+//
+// (interleave A, B, ...) - Interleave the elements from each argument list.
+//
+// All of these operators work on ordered sets, not lists. That means
+// duplicates are removed from sub-expressions.
+
+// Set operators. The rest is defined in TargetSelectionDAG.td.
+def sequence;
+def decimate;
+def interleave;
+
+// RegisterTuples - Automatically generate super-registers by forming tuples of
+// sub-registers. This is useful for modeling register sequence constraints
+// with pseudo-registers that are larger than the architectural registers.
+//
+// The sub-register lists are zipped together:
+//
+// def EvenOdd : RegisterTuples<[sube, subo], [(add R0, R2), (add R1, R3)]>;
+//
+// Generates the same registers as:
+//
+// let SubRegIndices = [sube, subo] in {
+// def R0_R1 : RegisterWithSubRegs<"", [R0, R1]>;
+// def R2_R3 : RegisterWithSubRegs<"", [R2, R3]>;
+// }
+//
+// The generated pseudo-registers inherit super-classes and fields from their
+// first sub-register. Most fields from the Register class are inferred, and
+// the AsmName and Dwarf numbers are cleared.
+//
+// RegisterTuples instances can be used in other set operations to form
+// register classes and so on. This is the only way of using the generated
+// registers.
+class RegisterTuples<list<SubRegIndex> Indices, list<dag> Regs> {
+ // SubRegs - N lists of registers to be zipped up. Super-registers are
+ // synthesized from the first element of each SubRegs list, the second
+ // element and so on.
+ list<dag> SubRegs = Regs;
+
+ // SubRegIndices - N SubRegIndex instances. This provides the names of the
+ // sub-registers in the synthesized super-registers.
+ list<SubRegIndex> SubRegIndices = Indices;
+
+ // Compose sub-register indices like in a normal Register.
+ list<dag> CompositeIndices = [];
+}
+
+
+//===----------------------------------------------------------------------===//
+// DwarfRegNum - This class provides a mapping of the llvm register enumeration
+// to the register numbering used by gcc and gdb. These values are used by a
+// debug information writer to describe where values may be located during
+// execution.
+class DwarfRegNum<list<int> Numbers> {
+ // DwarfNumbers - Numbers used internally by gcc/gdb to identify the register.
+ // These values can be determined by locating the <target>.h file in the
+ // directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The
+ // order of these names correspond to the enumeration used by gcc. A value of
+ // -1 indicates that the gcc number is undefined and -2 that register number
+ // is invalid for this mode/flavour.
+ list<int> DwarfNumbers = Numbers;
+}
+
+// DwarfRegAlias - This class declares that a given register uses the same dwarf
+// numbers as another one. This is useful for making it clear that the two
+// registers do have the same number. It also lets us build a mapping
+// from dwarf register number to llvm register.
+class DwarfRegAlias<Register reg> {
+ Register DwarfAlias = reg;
+}
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for scheduling
+//
+include "llvm/Target/TargetSchedule.td"
+
+class Predicate; // Forward def
+
+//===----------------------------------------------------------------------===//
+// Instruction set description - These classes correspond to the C++ classes in
+// the Target/TargetInstrInfo.h file.
+//
+class Instruction {
+ string Namespace = "";
+
+ dag OutOperandList; // An dag containing the MI def operand list.
+ dag InOperandList; // An dag containing the MI use operand list.
+ string AsmString = ""; // The .s format to print the instruction with.
+
+ // Pattern - Set to the DAG pattern for this instruction, if we know of one,
+ // otherwise, uninitialized.
+ list<dag> Pattern;
+
+ // The follow state will eventually be inferred automatically from the
+ // instruction pattern.
+
+ list<Register> Uses = []; // Default to using no non-operand registers
+ list<Register> Defs = []; // Default to modifying no non-operand registers
+
+ // Predicates - List of predicates which will be turned into isel matching
+ // code.
+ list<Predicate> Predicates = [];
+
+ // Size - Size of encoded instruction, or zero if the size cannot be determined
+ // from the opcode.
+ int Size = 0;
+
+ // DecoderNamespace - The "namespace" in which this instruction exists, on
+ // targets like ARM which multiple ISA namespaces exist.
+ string DecoderNamespace = "";
+
+ // Code size, for instruction selection.
+ // FIXME: What does this actually mean?
+ int CodeSize = 0;
+
+ // Added complexity passed onto matching pattern.
+ int AddedComplexity = 0;
+
+ // These bits capture information about the high-level semantics of the
+ // instruction.
+ bit isReturn = 0; // Is this instruction a return instruction?
+ bit isBranch = 0; // Is this instruction a branch instruction?
+ bit isIndirectBranch = 0; // Is this instruction an indirect branch?
+ bit isCompare = 0; // Is this instruction a comparison instruction?
+ bit isMoveImm = 0; // Is this instruction a move immediate instruction?
+ bit isBitcast = 0; // Is this instruction a bitcast instruction?
+ bit isBarrier = 0; // Can control flow fall through this instruction?
+ bit isCall = 0; // Is this instruction a call instruction?
+ bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand?
+ bit mayLoad = 0; // Is it possible for this inst to read memory?
+ bit mayStore = 0; // Is it possible for this inst to write memory?
+ bit isConvertibleToThreeAddress = 0; // Can this 2-addr instruction promote?
+ bit isCommutable = 0; // Is this 3 operand instruction commutable?
+ bit isTerminator = 0; // Is this part of the terminator for a basic block?
+ bit isReMaterializable = 0; // Is this instruction re-materializable?
+ bit isPredicable = 0; // Is this instruction predicable?
+ bit hasDelaySlot = 0; // Does this instruction have an delay slot?
+ bit usesCustomInserter = 0; // Pseudo instr needing special help.
+ bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook.
+ bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains?
+ bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction?
+ bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
+ bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
+ bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
+ bit isPseudo = 0; // Is this instruction a pseudo-instruction?
+ // If so, won't have encoding information for
+ // the [MC]CodeEmitter stuff.
+
+ // Side effect flags - When set, the flags have these meanings:
+ //
+ // hasSideEffects - The instruction has side effects that are not
+ // captured by any operands of the instruction or other flags.
+ //
+ // neverHasSideEffects - Set on an instruction with no pattern if it has no
+ // side effects.
+ bit hasSideEffects = 0;
+ bit neverHasSideEffects = 0;
+
+ // Is this instruction a "real" instruction (with a distinct machine
+ // encoding), or is it a pseudo instruction used for codegen modeling
+ // purposes.
+ // FIXME: For now this is distinct from isPseudo, above, as code-gen-only
+ // instructions can (and often do) still have encoding information
+ // associated with them. Once we've migrated all of them over to true
+ // pseudo-instructions that are lowered to real instructions prior to
+ // the printer/emitter, we can remove this attribute and just use isPseudo.
+ //
+ // The intended use is:
+ // isPseudo: Does not have encoding information and should be expanded,
+ // at the latest, during lowering to MCInst.
+ //
+ // isCodeGenOnly: Does have encoding information and can go through to the
+ // CodeEmitter unchanged, but duplicates a canonical instruction
+ // definition's encoding and should be ignored when constructing the
+ // assembler match tables.
+ bit isCodeGenOnly = 0;
+
+ // Is this instruction a pseudo instruction for use by the assembler parser.
+ bit isAsmParserOnly = 0;
+
+ InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
+
+ string Constraints = ""; // OperandConstraint, e.g. $src = $dst.
+
+ /// DisableEncoding - List of operand names (e.g. "$op1,$op2") that should not
+ /// be encoded into the output machineinstr.
+ string DisableEncoding = "";
+
+ string PostEncoderMethod = "";
+ string DecoderMethod = "";
+
+ /// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
+ bits<64> TSFlags = 0;
+
+ ///@name Assembler Parser Support
+ ///@{
+
+ string AsmMatchConverter = "";
+
+ ///@}
+}
+
+/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
+/// Which instruction it expands to and how the operands map from the
+/// pseudo.
+class PseudoInstExpansion<dag Result> {
+ dag ResultInst = Result; // The instruction to generate.
+ bit isPseudo = 1;
+}
+
+/// Predicates - These are extra conditionals which are turned into instruction
+/// selector matching code. Currently each predicate is just a string.
+class Predicate<string cond> {
+ string CondString = cond;
+
+ /// AssemblerMatcherPredicate - If this feature can be used by the assembler
+ /// matcher, this is true. Targets should set this by inheriting their
+ /// feature from the AssemblerPredicate class in addition to Predicate.
+ bit AssemblerMatcherPredicate = 0;
+
+ /// AssemblerCondString - Name of the subtarget feature being tested used
+ /// as alternative condition string used for assembler matcher.
+ /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0".
+ /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0".
+ /// It can also list multiple features separated by ",".
+ /// e.g. "ModeThumb,FeatureThumb2" is translated to
+ /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
+ string AssemblerCondString = "";
+}
+
+/// NoHonorSignDependentRounding - This predicate is true if support for
+/// sign-dependent-rounding is not enabled.
+def NoHonorSignDependentRounding
+ : Predicate<"!TM.Options.HonorSignDependentRoundingFPMath()">;
+
+class Requires<list<Predicate> preds> {
+ list<Predicate> Predicates = preds;
+}
+
+/// ops definition - This is just a simple marker used to identify the operand
+/// list for an instruction. outs and ins are identical both syntactically and
+/// semanticallyr; they are used to define def operands and use operands to
+/// improve readibility. This should be used like this:
+/// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar.
+def ops;
+def outs;
+def ins;
+
+/// variable_ops definition - Mark this instruction as taking a variable number
+/// of operands.
+def variable_ops;
+
+
+/// PointerLikeRegClass - Values that are designed to have pointer width are
+/// derived from this. TableGen treats the register class as having a symbolic
+/// type that it doesn't know, and resolves the actual regclass to use by using
+/// the TargetRegisterInfo::getPointerRegClass() hook at codegen time.
+class PointerLikeRegClass<int Kind> {
+ int RegClassKind = Kind;
+}
+
+
+/// ptr_rc definition - Mark this operand as being a pointer value whose
+/// register class is resolved dynamically via a callback to TargetInstrInfo.
+/// FIXME: We should probably change this to a class which contain a list of
+/// flags. But currently we have but one flag.
+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;
+
+/// AsmOperandClass - Representation for the kinds of operands which the target
+/// specific parser can create and the assembly matcher may need to distinguish.
+///
+/// Operand classes are used to define the order in which instructions are
+/// matched, to ensure that the instruction which gets matched for any
+/// particular list of operands is deterministic.
+///
+/// The target specific parser must be able to classify a parsed operand into a
+/// unique class which does not partially overlap with any other classes. It can
+/// match a subset of some other class, in which case the super class field
+/// should be defined.
+class AsmOperandClass {
+ /// The name to use for this class, which should be usable as an enum value.
+ string Name = ?;
+
+ /// The super classes of this operand.
+ list<AsmOperandClass> SuperClasses = [];
+
+ /// The name of the method on the target specific operand to call to test
+ /// whether the operand is an instance of this class. If not set, this will
+ /// default to "isFoo", where Foo is the AsmOperandClass name. The method
+ /// signature should be:
+ /// bool isFoo() const;
+ string PredicateMethod = ?;
+
+ /// The name of the method on the target specific operand to call to add the
+ /// target specific operand to an MCInst. If not set, this will default to
+ /// "addFooOperands", where Foo is the AsmOperandClass name. The method
+ /// signature should be:
+ /// void addFooOperands(MCInst &Inst, unsigned N) const;
+ string RenderMethod = ?;
+
+ /// The name of the method on the target specific operand to call to custom
+ /// handle the operand parsing. This is useful when the operands do not relate
+ /// to immediates or registers and are very instruction specific (as flags to
+ /// set in a processor register, coprocessor number, ...).
+ string ParserMethod = ?;
+}
+
+def ImmAsmOperand : AsmOperandClass {
+ let Name = "Imm";
+}
+
+/// Operand Types - These provide the built-in operand types that may be used
+/// by a target. Targets can optionally provide their own operand types as
+/// needed, though this should not be needed for RISC targets.
+class Operand<ValueType ty> {
+ ValueType Type = ty;
+ string PrintMethod = "printOperand";
+ string EncoderMethod = "";
+ string DecoderMethod = "";
+ string AsmOperandLowerMethod = ?;
+ string OperandType = "OPERAND_UNKNOWN";
+ dag MIOperandInfo = (ops);
+
+ // ParserMatchClass - The "match class" that operands of this type fit
+ // in. Match classes are used to define the order in which instructions are
+ // match, to ensure that which instructions gets matched is deterministic.
+ //
+ // The target specific parser must be able to classify an parsed operand into
+ // a unique class, which does not partially overlap with any other classes. It
+ // can match a subset of some other class, in which case the AsmOperandClass
+ // should declare the other operand as one of its super classes.
+ AsmOperandClass ParserMatchClass = ImmAsmOperand;
+}
+
+class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
+ // RegClass - The register class of the operand.
+ RegisterClass RegClass = regclass;
+ // PrintMethod - The target method to call to print register operands of
+ // this type. The method normally will just use an alt-name index to look
+ // up the name to print. Default to the generic printOperand().
+ string PrintMethod = pm;
+ // ParserMatchClass - The "match class" that operands of this type fit
+ // in. Match classes are used to define the order in which instructions are
+ // match, to ensure that which instructions gets matched is deterministic.
+ //
+ // The target specific parser must be able to classify an parsed operand into
+ // a unique class, which does not partially overlap with any other classes. It
+ // can match a subset of some other class, in which case the AsmOperandClass
+ // should declare the other operand as one of its super classes.
+ AsmOperandClass ParserMatchClass;
+}
+
+let OperandType = "OPERAND_IMMEDIATE" in {
+def i1imm : Operand<i1>;
+def i8imm : Operand<i8>;
+def i16imm : Operand<i16>;
+def i32imm : Operand<i32>;
+def i64imm : Operand<i64>;
+
+def f32imm : Operand<f32>;
+def f64imm : Operand<f64>;
+}
+
+/// zero_reg definition - Special node to stand for the zero register.
+///
+def zero_reg;
+
+/// PredicateOperand - This can be used to define a predicate operand for an
+/// instruction. OpTypes specifies the MIOperandInfo for the operand, and
+/// AlwaysVal specifies the value of this predicate when set to "always
+/// execute".
+class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal>
+ : Operand<ty> {
+ let MIOperandInfo = OpTypes;
+ dag DefaultOps = AlwaysVal;
+}
+
+/// OptionalDefOperand - This is used to define a optional definition operand
+/// for an instruction. DefaultOps is the register the operand represents if
+/// none is supplied, e.g. zero_reg.
+class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops>
+ : Operand<ty> {
+ let MIOperandInfo = OpTypes;
+ dag DefaultOps = defaultops;
+}
+
+
+// InstrInfo - This class should only be instantiated once to provide parameters
+// which are global to the target machine.
+//
+class InstrInfo {
+ // Target can specify its instructions in either big or little-endian formats.
+ // For instance, while both Sparc and PowerPC are big-endian platforms, the
+ // Sparc manual specifies its instructions in the format [31..0] (big), while
+ // PowerPC specifies them using the format [0..31] (little).
+ bit isLittleEndianEncoding = 0;
+}
+
+// Standard Pseudo Instructions.
+// This list must match TargetOpcodes.h and CodeGenTarget.cpp.
+// Only these instructions are allowed in the TargetOpcode namespace.
+let isCodeGenOnly = 1, isPseudo = 1, Namespace = "TargetOpcode" in {
+def PHI : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "PHINODE";
+}
+def INLINEASM : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "";
+ let neverHasSideEffects = 1; // Note side effect is encoded in an operand.
+}
+def PROLOG_LABEL : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$id);
+ let AsmString = "";
+ let hasCtrlDep = 1;
+ let isNotDuplicable = 1;
+}
+def EH_LABEL : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$id);
+ let AsmString = "";
+ let hasCtrlDep = 1;
+ let isNotDuplicable = 1;
+}
+def GC_LABEL : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$id);
+ let AsmString = "";
+ let hasCtrlDep = 1;
+ let isNotDuplicable = 1;
+}
+def KILL : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+}
+def EXTRACT_SUBREG : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+}
+def INSERT_SUBREG : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+ let Constraints = "$supersrc = $dst";
+}
+def IMPLICIT_DEF : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+ let isReMaterializable = 1;
+ let isAsCheapAsAMove = 1;
+}
+def SUBREG_TO_REG : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+}
+def COPY_TO_REGCLASS : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$src, i32imm:$regclass);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+ let isAsCheapAsAMove = 1;
+}
+def DBG_VALUE : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "DBG_VALUE";
+ let neverHasSideEffects = 1;
+}
+def REG_SEQUENCE : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+ let isAsCheapAsAMove = 1;
+}
+def COPY : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$src);
+ let AsmString = "";
+ let neverHasSideEffects = 1;
+ let isAsCheapAsAMove = 1;
+}
+def BUNDLE : Instruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins variable_ops);
+ let AsmString = "BUNDLE";
+}
+}
+
+//===----------------------------------------------------------------------===//
+// AsmParser - This class can be implemented by targets that wish to implement
+// .s file parsing.
+//
+// Subtargets can have multiple different assembly parsers (e.g. AT&T vs Intel
+// syntax on X86 for example).
+//
+class AsmParser {
+ // AsmParserClassName - This specifies the suffix to use for the asmparser
+ // class. Generated AsmParser classes are always prefixed with the target
+ // name.
+ string AsmParserClassName = "AsmParser";
+
+ // AsmParserInstCleanup - If non-empty, this is the name of a custom member
+ // function of the AsmParser class to call on every matched instruction.
+ // This can be used to perform target specific instruction post-processing.
+ string AsmParserInstCleanup = "";
+}
+def DefaultAsmParser : AsmParser;
+
+//===----------------------------------------------------------------------===//
+// AsmParserVariant - Subtargets can have multiple different assembly parsers
+// (e.g. AT&T vs Intel syntax on X86 for example). This class can be
+// implemented by targets to describe such variants.
+//
+class AsmParserVariant {
+ // Variant - AsmParsers can be of multiple different variants. Variants are
+ // used to support targets that need to parser multiple formats for the
+ // assembly language.
+ int Variant = 0;
+
+ // CommentDelimiter - If given, the delimiter string used to recognize
+ // comments which are hard coded in the .td assembler strings for individual
+ // instructions.
+ string CommentDelimiter = "";
+
+ // RegisterPrefix - If given, the token prefix which indicates a register
+ // token. This is used by the matcher to automatically recognize hard coded
+ // register tokens as constrained registers, instead of tokens, for the
+ // purposes of matching.
+ string RegisterPrefix = "";
+}
+def DefaultAsmParserVariant : AsmParserVariant;
+
+/// AssemblerPredicate - This is a Predicate that can be used when the assembler
+/// matches instructions and aliases.
+class AssemblerPredicate<string cond> {
+ bit AssemblerMatcherPredicate = 1;
+ string AssemblerCondString = cond;
+}
+
+/// TokenAlias - This class allows targets to define assembler token
+/// operand aliases. That is, a token literal operand which is equivalent
+/// to another, canonical, token literal. For example, ARM allows:
+/// vmov.u32 s4, #0 -> vmov.i32, #0
+/// 'u32' is a more specific designator for the 32-bit integer type specifier
+/// and is legal for any instruction which accepts 'i32' as a datatype suffix.
+/// def : TokenAlias<".u32", ".i32">;
+///
+/// This works by marking the match class of 'From' as a subclass of the
+/// match class of 'To'.
+class TokenAlias<string From, string To> {
+ string FromToken = From;
+ string ToToken = To;
+}
+
+/// MnemonicAlias - This class allows targets to define assembler mnemonic
+/// aliases. This should be used when all forms of one mnemonic are accepted
+/// with a different mnemonic. For example, X86 allows:
+/// sal %al, 1 -> shl %al, 1
+/// sal %ax, %cl -> shl %ax, %cl
+/// sal %eax, %cl -> shl %eax, %cl
+/// etc. Though "sal" is accepted with many forms, all of them are directly
+/// translated to a shl, so it can be handled with (in the case of X86, it
+/// actually has one for each suffix as well):
+/// def : MnemonicAlias<"sal", "shl">;
+///
+/// Mnemonic aliases are mapped before any other translation in the match phase,
+/// and do allow Requires predicates, e.g.:
+///
+/// def : MnemonicAlias<"pushf", "pushfq">, Requires<[In64BitMode]>;
+/// def : MnemonicAlias<"pushf", "pushfl">, Requires<[In32BitMode]>;
+///
+class MnemonicAlias<string From, string To> {
+ string FromMnemonic = From;
+ string ToMnemonic = To;
+
+ // Predicates - Predicates that must be true for this remapping to happen.
+ list<Predicate> Predicates = [];
+}
+
+/// InstAlias - This defines an alternate assembly syntax that is allowed to
+/// match an instruction that has a different (more canonical) assembly
+/// representation.
+class InstAlias<string Asm, dag Result, bit Emit = 0b1> {
+ string AsmString = Asm; // The .s format to match the instruction with.
+ dag ResultInst = Result; // The MCInst to generate.
+ bit EmitAlias = Emit; // Emit the alias instead of what's aliased.
+
+ // Predicates - Predicates that must be true for this to match.
+ list<Predicate> Predicates = [];
+}
+
+//===----------------------------------------------------------------------===//
+// AsmWriter - This class can be implemented by targets that need to customize
+// the format of the .s file writer.
+//
+// Subtargets can have multiple different asmwriters (e.g. AT&T vs Intel syntax
+// on X86 for example).
+//
+class AsmWriter {
+ // AsmWriterClassName - This specifies the suffix to use for the asmwriter
+ // class. Generated AsmWriter classes are always prefixed with the target
+ // name.
+ string AsmWriterClassName = "AsmPrinter";
+
+ // Variant - AsmWriters can be of multiple different variants. Variants are
+ // used to support targets that need to emit assembly code in ways that are
+ // mostly the same for different targets, but have minor differences in
+ // syntax. If the asmstring contains {|} characters in them, this integer
+ // will specify which alternative to use. For example "{x|y|z}" with Variant
+ // == 1, will expand to "y".
+ int Variant = 0;
+
+
+ // FirstOperandColumn/OperandSpacing - If the assembler syntax uses a columnar
+ // layout, the asmwriter can actually generate output in this columns (in
+ // verbose-asm mode). These two values indicate the width of the first column
+ // (the "opcode" area) and the width to reserve for subsequent operands. When
+ // verbose asm mode is enabled, operands will be indented to respect this.
+ int FirstOperandColumn = -1;
+
+ // OperandSpacing - Space between operand columns.
+ int OperandSpacing = -1;
+
+ // isMCAsmWriter - Is this assembly writer for an MC emitter? This controls
+ // generation of the printInstruction() method. For MC printers, it takes
+ // an MCInstr* operand, otherwise it takes a MachineInstr*.
+ bit isMCAsmWriter = 0;
+}
+def DefaultAsmWriter : AsmWriter;
+
+
+//===----------------------------------------------------------------------===//
+// Target - This class contains the "global" target information
+//
+class Target {
+ // InstructionSet - Instruction set description for this target.
+ InstrInfo InstructionSet;
+
+ // AssemblyParsers - The AsmParser instances available for this target.
+ list<AsmParser> AssemblyParsers = [DefaultAsmParser];
+
+ /// AssemblyParserVariants - The AsmParserVariant instances available for
+ /// this target.
+ list<AsmParserVariant> AssemblyParserVariants = [DefaultAsmParserVariant];
+
+ // AssemblyWriters - The AsmWriter instances available for this target.
+ list<AsmWriter> AssemblyWriters = [DefaultAsmWriter];
+}
+
+//===----------------------------------------------------------------------===//
+// SubtargetFeature - A characteristic of the chip set.
+//
+class SubtargetFeature<string n, string a, string v, string d,
+ list<SubtargetFeature> i = []> {
+ // Name - Feature name. Used by command line (-mattr=) to determine the
+ // appropriate target chip.
+ //
+ string Name = n;
+
+ // Attribute - Attribute to be set by feature.
+ //
+ string Attribute = a;
+
+ // Value - Value the attribute to be set to by feature.
+ //
+ string Value = v;
+
+ // Desc - Feature description. Used by command line (-mattr=) to display help
+ // information.
+ //
+ string Desc = d;
+
+ // Implies - Features that this feature implies are present. If one of those
+ // features isn't set, then this one shouldn't be set either.
+ //
+ list<SubtargetFeature> Implies = i;
+}
+
+//===----------------------------------------------------------------------===//
+// Processor chip sets - These values represent each of the chip sets supported
+// by the scheduler. Each Processor definition requires corresponding
+// instruction itineraries.
+//
+class Processor<string n, ProcessorItineraries pi, list<SubtargetFeature> f> {
+ // Name - Chip set name. Used by command line (-mcpu=) to determine the
+ // appropriate target chip.
+ //
+ string Name = n;
+
+ // ProcItin - The scheduling information for the target processor.
+ //
+ ProcessorItineraries ProcItin = pi;
+
+ // Features - list of
+ list<SubtargetFeature> Features = f;
+}
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for calling conventions.
+//
+include "llvm/Target/TargetCallingConv.td"
+
+//===----------------------------------------------------------------------===//
+// Pull in the common support for DAG isel generation.
+//
+include "llvm/Target/TargetSelectionDAG.td"
diff --git a/contrib/llvm/include/llvm/Target/TargetCallingConv.h b/contrib/llvm/include/llvm/Target/TargetCallingConv.h
new file mode 100644
index 000000000000..a6251e7d3345
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetCallingConv.h
@@ -0,0 +1,144 @@
+//===-- llvm/Target/TargetCallingConv.h - Calling Convention ----*- 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 types for working with calling-convention information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
+#define LLVM_TARGET_TARGETCALLINGCONV_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MathExtras.h"
+#include <string>
+
+namespace llvm {
+
+namespace ISD {
+ struct ArgFlagsTy {
+ private:
+ static const uint64_t NoFlagSet = 0ULL;
+ static const uint64_t ZExt = 1ULL<<0; ///< Zero extended
+ static const uint64_t ZExtOffs = 0;
+ static const uint64_t SExt = 1ULL<<1; ///< Sign extended
+ static const uint64_t SExtOffs = 1;
+ static const uint64_t InReg = 1ULL<<2; ///< Passed in register
+ static const uint64_t InRegOffs = 2;
+ static const uint64_t SRet = 1ULL<<3; ///< Hidden struct-ret ptr
+ static const uint64_t SRetOffs = 3;
+ static const uint64_t ByVal = 1ULL<<4; ///< Struct passed by value
+ static const uint64_t ByValOffs = 4;
+ static const uint64_t Nest = 1ULL<<5; ///< Nested fn static chain
+ static const uint64_t NestOffs = 5;
+ static const uint64_t ByValAlign = 0xFULL << 6; //< Struct alignment
+ static const uint64_t ByValAlignOffs = 6;
+ static const uint64_t Split = 1ULL << 10;
+ static const uint64_t SplitOffs = 10;
+ static const uint64_t OrigAlign = 0x1FULL<<27;
+ static const uint64_t OrigAlignOffs = 27;
+ static const uint64_t ByValSize = 0xffffffffULL << 32; //< Struct size
+ static const uint64_t ByValSizeOffs = 32;
+
+ static const uint64_t One = 1ULL; //< 1 of this type, for shifts
+
+ uint64_t Flags;
+ public:
+ ArgFlagsTy() : Flags(0) { }
+
+ bool isZExt() const { return Flags & ZExt; }
+ void setZExt() { Flags |= One << ZExtOffs; }
+
+ bool isSExt() const { return Flags & SExt; }
+ void setSExt() { Flags |= One << SExtOffs; }
+
+ bool isInReg() const { return Flags & InReg; }
+ void setInReg() { Flags |= One << InRegOffs; }
+
+ bool isSRet() const { return Flags & SRet; }
+ void setSRet() { Flags |= One << SRetOffs; }
+
+ bool isByVal() const { return Flags & ByVal; }
+ void setByVal() { Flags |= One << ByValOffs; }
+
+ bool isNest() const { return Flags & Nest; }
+ void setNest() { Flags |= One << NestOffs; }
+
+ unsigned getByValAlign() const {
+ return (unsigned)
+ ((One << ((Flags & ByValAlign) >> ByValAlignOffs)) / 2);
+ }
+ void setByValAlign(unsigned A) {
+ Flags = (Flags & ~ByValAlign) |
+ (uint64_t(Log2_32(A) + 1) << ByValAlignOffs);
+ }
+
+ bool isSplit() const { return Flags & Split; }
+ void setSplit() { Flags |= One << SplitOffs; }
+
+ unsigned getOrigAlign() const {
+ return (unsigned)
+ ((One << ((Flags & OrigAlign) >> OrigAlignOffs)) / 2);
+ }
+ void setOrigAlign(unsigned A) {
+ Flags = (Flags & ~OrigAlign) |
+ (uint64_t(Log2_32(A) + 1) << OrigAlignOffs);
+ }
+
+ unsigned getByValSize() const {
+ return (unsigned)((Flags & ByValSize) >> ByValSizeOffs);
+ }
+ void setByValSize(unsigned S) {
+ Flags = (Flags & ~ByValSize) | (uint64_t(S) << ByValSizeOffs);
+ }
+
+ /// getArgFlagsString - Returns the flags as a string, eg: "zext align:4".
+ std::string getArgFlagsString();
+
+ /// getRawBits - Represent the flags as a bunch of bits.
+ uint64_t getRawBits() const { return Flags; }
+ };
+
+ /// InputArg - This struct carries flags and type information about a
+ /// single incoming (formal) argument or incoming (from the perspective
+ /// of the caller) return value virtual register.
+ ///
+ struct InputArg {
+ ArgFlagsTy Flags;
+ MVT VT;
+ bool Used;
+
+ InputArg() : VT(MVT::Other), Used(false) {}
+ InputArg(ArgFlagsTy flags, EVT vt, bool used)
+ : Flags(flags), Used(used) {
+ VT = vt.getSimpleVT();
+ }
+ };
+
+ /// OutputArg - This struct carries flags and a value for a
+ /// single outgoing (actual) argument or outgoing (from the perspective
+ /// of the caller) return value virtual register.
+ ///
+ struct OutputArg {
+ ArgFlagsTy Flags;
+ MVT VT;
+
+ /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
+ bool IsFixed;
+
+ OutputArg() : IsFixed(false) {}
+ OutputArg(ArgFlagsTy flags, EVT vt, bool isfixed)
+ : Flags(flags), IsFixed(isfixed) {
+ VT = vt.getSimpleVT();
+ }
+ };
+}
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetCallingConv.td b/contrib/llvm/include/llvm/Target/TargetCallingConv.td
new file mode 100644
index 000000000000..a53ed29f1ec1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetCallingConv.td
@@ -0,0 +1,146 @@
+//===- TargetCallingConv.td - Target Calling Conventions ---*- 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 the target-independent interfaces with which targets
+// describe their calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+class CCAction;
+class CallingConv;
+
+/// CCCustom - Calls a custom arg handling function.
+class CCCustom<string fn> : CCAction {
+ string FuncName = fn;
+}
+
+/// CCPredicateAction - Instances of this class check some predicate, then
+/// delegate to another action if the predicate is true.
+class CCPredicateAction<CCAction A> : CCAction {
+ CCAction SubAction = A;
+}
+
+/// CCIfType - If the current argument is one of the specified types, apply
+/// Action A.
+class CCIfType<list<ValueType> vts, CCAction A> : CCPredicateAction<A> {
+ list<ValueType> VTs = vts;
+}
+
+/// CCIf - If the predicate matches, apply A.
+class CCIf<string predicate, CCAction A> : CCPredicateAction<A> {
+ string Predicate = predicate;
+}
+
+/// CCIfByVal - If the current argument has ByVal parameter attribute, apply
+/// Action A.
+class CCIfByVal<CCAction A> : CCIf<"ArgFlags.isByVal()", A> {
+}
+
+/// CCIfCC - Match if the current calling convention is 'CC'.
+class CCIfCC<string CC, CCAction A>
+ : CCIf<!strconcat("State.getCallingConv() == ", CC), A> {}
+
+/// CCIfInReg - If this argument is marked with the 'inreg' attribute, apply
+/// the specified action.
+class CCIfInReg<CCAction A> : CCIf<"ArgFlags.isInReg()", A> {}
+
+/// CCIfNest - If this argument is marked with the 'nest' attribute, apply
+/// the specified action.
+class CCIfNest<CCAction A> : CCIf<"ArgFlags.isNest()", A> {}
+
+/// CCIfSplit - If this argument is marked with the 'split' attribute, apply
+/// the specified action.
+class CCIfSplit<CCAction A> : CCIf<"ArgFlags.isSplit()", A> {}
+
+/// CCIfSRet - If this argument is marked with the 'sret' attribute, apply
+/// the specified action.
+class CCIfSRet<CCAction A> : CCIf<"ArgFlags.isSRet()", A> {}
+
+/// CCIfNotVarArg - If the current function is not vararg - apply the action
+class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
+
+/// CCAssignToReg - This action matches if there is a register in the specified
+/// list that is still available. If so, it assigns the value to the first
+/// available register and succeeds.
+class CCAssignToReg<list<Register> regList> : CCAction {
+ list<Register> RegList = regList;
+}
+
+/// CCAssignToRegWithShadow - Same as CCAssignToReg, but with list of registers
+/// which became shadowed, when some register is used.
+class CCAssignToRegWithShadow<list<Register> regList,
+ list<Register> shadowList> : CCAction {
+ list<Register> RegList = regList;
+ list<Register> ShadowRegList = shadowList;
+}
+
+/// CCAssignToStack - This action always matches: it assigns the value to a
+/// stack slot of the specified size and alignment on the stack. If size is
+/// zero then the ABI size is used; if align is zero then the ABI alignment
+/// is used - these may depend on the target or subtarget.
+class CCAssignToStack<int size, int align> : CCAction {
+ int Size = size;
+ int Align = align;
+}
+
+/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a register
+/// to be shadowed.
+class CCAssignToStackWithShadow<int size, int align, Register reg> :
+ CCAssignToStack<size, align> {
+ Register ShadowReg = reg;
+}
+
+/// CCPassByVal - This action always matches: it assigns the value to a stack
+/// slot to implement ByVal aggregate parameter passing. Size and alignment
+/// specify the minimum size and alignment for the stack slot.
+class CCPassByVal<int size, int align> : CCAction {
+ int Size = size;
+ int Align = align;
+}
+
+/// CCPromoteToType - If applied, this promotes the specified current value to
+/// the specified type.
+class CCPromoteToType<ValueType destTy> : CCAction {
+ ValueType DestTy = destTy;
+}
+
+/// CCBitConvertToType - If applied, this bitconverts the specified current
+/// value to the specified type.
+class CCBitConvertToType<ValueType destTy> : CCAction {
+ ValueType DestTy = destTy;
+}
+
+/// CCPassIndirect - If applied, this stores the value to stack and passes the pointer
+/// as normal argument.
+class CCPassIndirect<ValueType destTy> : CCAction {
+ ValueType DestTy = destTy;
+}
+
+/// CCDelegateTo - This action invokes the specified sub-calling-convention. It
+/// is successful if the specified CC matches.
+class CCDelegateTo<CallingConv cc> : CCAction {
+ CallingConv CC = cc;
+}
+
+/// CallingConv - An instance of this is used to define each calling convention
+/// that the target supports.
+class CallingConv<list<CCAction> actions> {
+ list<CCAction> Actions = actions;
+}
+
+/// CalleeSavedRegs - A list of callee saved registers for a given calling
+/// convention. The order of registers is used by PrologEpilogInsertion when
+/// allocation stack slots for saved registers.
+///
+/// For each CalleeSavedRegs def, TableGen will emit a FOO_SaveList array for
+/// returning from getCalleeSavedRegs(), and a FOO_RegMask bit mask suitable for
+/// returning from getCallPreservedMask().
+class CalleeSavedRegs<dag saves> {
+ dag SaveList = saves;
+}
diff --git a/contrib/llvm/include/llvm/Target/TargetData.h b/contrib/llvm/include/llvm/Target/TargetData.h
new file mode 100644
index 000000000000..d116f392fb31
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetData.h
@@ -0,0 +1,363 @@
+//===-- llvm/Target/TargetData.h - Data size & alignment 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 target properties related to datatype size/offset/alignment
+// information. It uses lazy annotations to cache information about how
+// structure types are laid out and used.
+//
+// This structure should be created once, filled in if the defaults are not
+// correct and then passed around by const&. None of the members functions
+// require modification to the object.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETDATA_H
+#define LLVM_TARGET_TARGETDATA_H
+
+#include "llvm/Pass.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class Value;
+class Type;
+class IntegerType;
+class StructType;
+class StructLayout;
+class GlobalVariable;
+class LLVMContext;
+template<typename T>
+class ArrayRef;
+
+/// Enum used to categorize the alignment types stored by TargetAlignElem
+enum AlignTypeEnum {
+ INTEGER_ALIGN = 'i', ///< Integer type alignment
+ VECTOR_ALIGN = 'v', ///< Vector type alignment
+ FLOAT_ALIGN = 'f', ///< Floating point type alignment
+ AGGREGATE_ALIGN = 'a', ///< Aggregate alignment
+ STACK_ALIGN = 's' ///< Stack objects alignment
+};
+
+/// Target alignment element.
+///
+/// Stores the alignment data associated with a given alignment type (pointer,
+/// integer, vector, float) and type bit width.
+///
+/// @note The unusual order of elements in the structure attempts to reduce
+/// padding and make the structure slightly more cache friendly.
+struct TargetAlignElem {
+ AlignTypeEnum AlignType : 8; //< Alignment type (AlignTypeEnum)
+ unsigned ABIAlign; //< ABI alignment for this type/bitw
+ unsigned PrefAlign; //< Pref. alignment for this type/bitw
+ uint32_t TypeBitWidth; //< Type bit width
+
+ /// Initializer
+ static TargetAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width);
+ /// Equality predicate
+ bool operator==(const TargetAlignElem &rhs) const;
+};
+
+/// TargetData - 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 {
+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.
+
+ /// Alignments- Where the primitive type alignment data is stored.
+ ///
+ /// @sa init().
+ /// @note Could support multiple size pointer alignments, e.g., 32-bit
+ /// pointers vs. 64-bit pointers by extending TargetAlignment, but for now,
+ /// we don't.
+ SmallVector<TargetAlignElem, 16> Alignments;
+
+ /// InvalidAlignmentElem - This member is a signal that a requested alignment
+ /// type and bit width were not found in the SmallVector.
+ static const TargetAlignElem InvalidAlignmentElem;
+
+ // The StructType -> StructLayout map.
+ mutable void *LayoutMap;
+
+ //! Set/initialize target alignments
+ void setAlignment(AlignTypeEnum align_type, unsigned abi_align,
+ unsigned pref_align, uint32_t bit_width);
+ unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
+ bool ABIAlign, Type *Ty) const;
+ //! 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
+ /// InvalidAlignmentElem.
+ bool validAlignment(const TargetAlignElem &align) const {
+ return &align != &InvalidAlignmentElem;
+ }
+
+ /// Initialise a TargetData object with default values, ensure that the
+ /// target data pass is registered.
+ void init();
+
+public:
+ /// Default ctor.
+ ///
+ /// @note This has to exist, because this is a pass, but it should never be
+ /// used.
+ TargetData();
+
+ /// Constructs a TargetData from a specification string. See init().
+ explicit TargetData(StringRef TargetDescription)
+ : ImmutablePass(ID) {
+ std::string errMsg = parseSpecifier(TargetDescription, this);
+ assert(errMsg == "" && "Invalid target data layout string.");
+ (void)errMsg;
+ }
+
+ /// Parses a target data specification string. Returns an error message
+ /// if the string is malformed, or the empty string on success. Optionally
+ /// initialises a TargetData object if passed a non-null pointer.
+ static std::string parseSpecifier(StringRef TargetDescription, TargetData* td = 0);
+
+ /// Initialize target data from properties stored in the module.
+ explicit TargetData(const Module *M);
+
+ TargetData(const TargetData &TD) :
+ ImmutablePass(ID),
+ LittleEndian(TD.isLittleEndian()),
+ PointerMemSize(TD.PointerMemSize),
+ PointerABIAlign(TD.PointerABIAlign),
+ PointerPrefAlign(TD.PointerPrefAlign),
+ LegalIntWidths(TD.LegalIntWidths),
+ Alignments(TD.Alignments),
+ LayoutMap(0)
+ { }
+
+ ~TargetData(); // Not virtual, do not subclass this class
+
+ /// Target 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
+ /// string constructor above.
+ std::string getStringRepresentation() const;
+
+ /// isLegalInteger - This function returns true if the specified type is
+ /// known to be a native integer type supported by the CPU. For example,
+ /// i64 is not native on most 32-bit CPUs and i37 is not native on any known
+ /// one. This returns false if the integer width is not legal.
+ ///
+ /// The width is specified in bits.
+ ///
+ bool isLegalInteger(unsigned Width) const {
+ for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i)
+ if (LegalIntWidths[i] == Width)
+ return true;
+ return false;
+ }
+
+ bool isIllegalInteger(unsigned Width) const {
+ return !isLegalInteger(Width);
+ }
+
+ /// Returns true if the given alignment exceeds the natural stack alignment.
+ bool exceedsNaturalStackAlignment(unsigned Align) const {
+ return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
+ }
+
+ /// fitsInLegalInteger - This function returns true if the specified type fits
+ /// in a native integer type supported by the CPU. For example, if the CPU
+ /// only supports i32 as a native integer type, then i27 fits in a legal
+ // integer type but i45 does not.
+ bool fitsInLegalInteger(unsigned Width) const {
+ for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i)
+ if (Width <= LegalIntWidths[i])
+ return true;
+ return false;
+ }
+
+ /// Target pointer alignment
+ unsigned getPointerABIAlignment() const { return PointerABIAlign; }
+ /// 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; }
+
+ /// Size examples:
+ ///
+ /// Type SizeInBits StoreSizeInBits AllocSizeInBits[*]
+ /// ---- ---------- --------------- ---------------
+ /// i1 1 8 8
+ /// i8 8 8 8
+ /// i19 19 24 32
+ /// i32 32 32 32
+ /// i100 100 104 128
+ /// i128 128 128 128
+ /// Float 32 32 32
+ /// Double 64 64 64
+ /// X86_FP80 80 80 96
+ ///
+ /// [*] The alloc size depends on the alignment, and thus on the target.
+ /// These values are for x86-32 linux.
+
+ /// getTypeSizeInBits - Return the number of bits necessary to hold the
+ /// specified type. For example, returns 36 for i36 and 80 for x86_fp80.
+ uint64_t getTypeSizeInBits(Type* Ty) const;
+
+ /// getTypeStoreSize - Return the maximum number of bytes that may be
+ /// overwritten by storing the specified type. For example, returns 5
+ /// for i36 and 10 for x86_fp80.
+ uint64_t getTypeStoreSize(Type *Ty) const {
+ return (getTypeSizeInBits(Ty)+7)/8;
+ }
+
+ /// getTypeStoreSizeInBits - Return the maximum number of bits that may be
+ /// overwritten by storing the specified type; always a multiple of 8. For
+ /// example, returns 40 for i36 and 80 for x86_fp80.
+ uint64_t getTypeStoreSizeInBits(Type *Ty) const {
+ return 8*getTypeStoreSize(Ty);
+ }
+
+ /// getTypeAllocSize - Return the offset in bytes between successive objects
+ /// of the specified type, including alignment padding. This is the amount
+ /// that alloca reserves for this type. For example, returns 12 or 16 for
+ /// x86_fp80, depending on alignment.
+ uint64_t getTypeAllocSize(Type* Ty) const {
+ // Round up to the next alignment boundary.
+ return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty));
+ }
+
+ /// getTypeAllocSizeInBits - Return the offset in bits between successive
+ /// objects of the specified type, including alignment padding; always a
+ /// multiple of 8. This is the amount that alloca reserves for this type.
+ /// For example, returns 96 or 128 for x86_fp80, depending on alignment.
+ uint64_t getTypeAllocSizeInBits(Type* Ty) const {
+ return 8*getTypeAllocSize(Ty);
+ }
+
+ /// getABITypeAlignment - Return the minimum ABI-required alignment for the
+ /// specified type.
+ unsigned getABITypeAlignment(Type *Ty) const;
+
+ /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
+ /// an integer type of the specified bitwidth.
+ unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const;
+
+
+ /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
+ /// for the specified type when it is part of a call frame.
+ unsigned getCallFrameTypeAlignment(Type *Ty) const;
+
+
+ /// getPrefTypeAlignment - Return the preferred stack/global alignment for
+ /// the specified type. This is always at least as good as the ABI alignment.
+ unsigned getPrefTypeAlignment(Type *Ty) const;
+
+ /// getPreferredTypeAlignmentShift - Return the preferred alignment for the
+ /// specified type, returned as log2 of the value (a shift amount).
+ ///
+ 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;
+
+ /// getIndexedOffset - return the offset from the beginning of the type for
+ /// the specified indices. This is used to implement getelementptr.
+ ///
+ uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const;
+
+ /// getStructLayout - Return a StructLayout object, indicating the alignment
+ /// of the struct, its size, and the offsets of its fields. Note that this
+ /// information is lazily cached.
+ const StructLayout *getStructLayout(StructType *Ty) const;
+
+ /// getPreferredAlignment - Return the preferred alignment of the specified
+ /// global. This includes an explicitly requested alignment (if the global
+ /// has one).
+ unsigned getPreferredAlignment(const GlobalVariable *GV) const;
+
+ /// getPreferredAlignmentLog - Return the preferred alignment of the
+ /// specified global, returned in log form. This includes an explicitly
+ /// requested alignment (if the global has one).
+ unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const;
+
+ /// RoundUpAlignment - Round the specified value up to the next alignment
+ /// boundary specified by Alignment. For example, 7 rounded up to an
+ /// alignment boundary of 4 is 8. 8 rounded up to the alignment boundary of 4
+ /// is 8 because it is already aligned.
+ template <typename UIntTy>
+ static UIntTy RoundUpAlignment(UIntTy Val, unsigned Alignment) {
+ assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!");
+ return (Val + (Alignment-1)) & ~UIntTy(Alignment-1);
+ }
+
+ static char ID; // Pass identification, replacement for typeid
+};
+
+/// StructLayout - used to lazily calculate structure layout information for a
+/// target machine, based on the TargetData structure.
+///
+class StructLayout {
+ uint64_t StructSize;
+ unsigned StructAlignment;
+ unsigned NumElements;
+ uint64_t MemberOffsets[1]; // variable sized array!
+public:
+
+ uint64_t getSizeInBytes() const {
+ return StructSize;
+ }
+
+ uint64_t getSizeInBits() const {
+ return 8*StructSize;
+ }
+
+ unsigned getAlignment() const {
+ return StructAlignment;
+ }
+
+ /// getElementContainingOffset - Given a valid byte offset into the structure,
+ /// return the structure index that contains it.
+ ///
+ unsigned getElementContainingOffset(uint64_t Offset) const;
+
+ uint64_t getElementOffset(unsigned Idx) const {
+ assert(Idx < NumElements && "Invalid element idx!");
+ return MemberOffsets[Idx];
+ }
+
+ uint64_t getElementOffsetInBits(unsigned Idx) const {
+ return getElementOffset(Idx)*8;
+ }
+
+private:
+ friend class TargetData; // Only TargetData can create this class
+ StructLayout(StructType *ST, const TargetData &TD);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetELFWriterInfo.h b/contrib/llvm/include/llvm/Target/TargetELFWriterInfo.h
new file mode 100644
index 000000000000..114295e8f985
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetELFWriterInfo.h
@@ -0,0 +1,120 @@
+//===-- 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
+ };
+
+ // 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/contrib/llvm/include/llvm/Target/TargetFrameLowering.h b/contrib/llvm/include/llvm/Target/TargetFrameLowering.h
new file mode 100644
index 000000000000..d56db7b5118e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetFrameLowering.h
@@ -0,0 +1,193 @@
+//===-- llvm/Target/TargetFrameLowering.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to describe the layout of a stack frame on the target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETFRAMELOWERING_H
+#define LLVM_TARGET_TARGETFRAMELOWERING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
+#include <utility>
+#include <vector>
+
+namespace llvm {
+ class CalleeSavedInfo;
+ class MachineFunction;
+ class RegScavenger;
+
+/// Information about stack frame layout on the target. It holds the direction
+/// of stack growth, the known stack alignment on entry to each function, and
+/// the offset to the locals area.
+///
+/// The offset to the local area is the offset from the stack pointer on
+/// function entry to the first location where function data (local variables,
+/// spill locations) can be stored.
+class TargetFrameLowering {
+public:
+ enum StackDirection {
+ StackGrowsUp, // Adding to the stack increases the stack address
+ StackGrowsDown // Adding to the stack decreases the stack address
+ };
+
+ // Maps a callee saved register to a stack slot with a fixed offset.
+ struct SpillSlot {
+ unsigned Reg;
+ int Offset; // Offset relative to stack pointer on function entry.
+ };
+private:
+ StackDirection StackDir;
+ unsigned StackAlignment;
+ unsigned TransientStackAlignment;
+ int LocalAreaOffset;
+public:
+ TargetFrameLowering(StackDirection D, unsigned StackAl, int LAO,
+ unsigned TransAl = 1)
+ : StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
+ LocalAreaOffset(LAO) {}
+
+ virtual ~TargetFrameLowering();
+
+ // These methods return information that describes the abstract stack layout
+ // of the target machine.
+
+ /// getStackGrowthDirection - Return the direction the stack grows
+ ///
+ StackDirection getStackGrowthDirection() const { return StackDir; }
+
+ /// getStackAlignment - This method returns the number of bytes to which the
+ /// stack pointer must be aligned on entry to a function. Typically, this
+ /// is the largest alignment for any data object in the target.
+ ///
+ unsigned getStackAlignment() const { return StackAlignment; }
+
+ /// getTransientStackAlignment - This method returns the number of bytes to
+ /// which the stack pointer must be aligned at all times, even between
+ /// calls.
+ ///
+ unsigned getTransientStackAlignment() const {
+ return TransientStackAlignment;
+ }
+
+ /// getOffsetOfLocalArea - This method returns the offset of the local area
+ /// from the stack pointer on entrance to a function.
+ ///
+ int getOffsetOfLocalArea() const { return LocalAreaOffset; }
+
+ /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
+ /// pairs, that contains an entry for each callee saved register that must be
+ /// spilled to a particular stack location if it is spilled.
+ ///
+ /// Each entry in this array contains a <register,offset> pair, indicating the
+ /// fixed offset from the incoming stack pointer that each register should be
+ /// spilled at. If a register is not listed here, the code generator is
+ /// allowed to spill it anywhere it chooses.
+ ///
+ virtual const SpillSlot *
+ getCalleeSavedSpillSlots(unsigned &NumEntries) const {
+ NumEntries = 0;
+ return 0;
+ }
+
+ /// targetHandlesStackFrameRounding - Returns true if the target is
+ /// responsible for rounding up the stack frame (probably at emitPrologue
+ /// time).
+ virtual bool targetHandlesStackFrameRounding() const {
+ return false;
+ }
+
+ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+ /// the function.
+ virtual void emitPrologue(MachineFunction &MF) const = 0;
+ virtual void emitEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const = 0;
+
+ /// Adjust the prologue to have the function use segmented stacks. This works
+ /// by adding a check even before the "normal" function prologue.
+ virtual void adjustForSegmentedStacks(MachineFunction &MF) const { }
+
+ /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of store instructions via
+ /// storeRegToStackSlot(). Returns false otherwise.
+ virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of load instructions via loadRegToStackSlot().
+ /// Returns false otherwise.
+ virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI,
+ const TargetRegisterInfo *TRI) const {
+ return false;
+ }
+
+ /// hasFP - Return true if the specified function should have a dedicated
+ /// frame pointer register. For most targets this is true only if the function
+ /// has variable sized allocas or if frame pointer elimination is disabled.
+ virtual bool hasFP(const MachineFunction &MF) const = 0;
+
+ /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+ /// not required, we reserve argument space for call sites in the function
+ /// immediately on entry to the current function. This eliminates the need for
+ /// add/sub sp brackets around call sites. Returns true if the call frame is
+ /// included as part of the stack frame.
+ virtual bool hasReservedCallFrame(const MachineFunction &MF) const {
+ return !hasFP(MF);
+ }
+
+ /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
+ /// call frame pseudo ops before doing frame index elimination. This is
+ /// possible only when frame index references between the pseudos won't
+ /// need adjusting for the call frame adjustments. Normally, that's true
+ /// if the function has a reserved call frame or a frame pointer. Some
+ /// targets (Thumb2, for example) may have more complicated criteria,
+ /// however, and can override this behavior.
+ virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const {
+ return hasReservedCallFrame(MF) || hasFP(MF);
+ }
+
+ /// getFrameIndexOffset - Returns the displacement from the frame register to
+ /// the stack frame of the specified index.
+ virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
+
+ /// getFrameIndexReference - This method should return the base register
+ /// and offset used to reference a frame index location. The offset is
+ /// returned directly, and the base register is returned via FrameReg.
+ virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
+ unsigned &FrameReg) const;
+
+ /// processFunctionBeforeCalleeSavedScan - This method is called immediately
+ /// before PrologEpilogInserter scans the physical registers used to determine
+ /// what callee saved registers should be spilled. This method is optional.
+ virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const {
+
+ }
+
+ /// processFunctionBeforeFrameFinalized - This method is called immediately
+ /// before the specified function's frame layout (MF.getFrameInfo()) is
+ /// finalized. Once the frame is finalized, MO_FrameIndex operands are
+ /// replaced with direct constants. This method is optional.
+ ///
+ virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetInstrInfo.h b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h
new file mode 100644
index 000000000000..d1e380c5602a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetInstrInfo.h
@@ -0,0 +1,885 @@
+//===-- llvm/Target/TargetInstrInfo.h - Instruction 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 describes the target machine instruction set to the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETINSTRINFO_H
+#define LLVM_TARGET_TARGETINSTRINFO_H
+
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/CodeGen/DFAPacketizer.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+class InstrItineraryData;
+class LiveVariables;
+class MCAsmInfo;
+class MachineMemOperand;
+class MachineRegisterInfo;
+class MDNode;
+class MCInst;
+class SDNode;
+class ScheduleHazardRecognizer;
+class SelectionDAG;
+class ScheduleDAG;
+class TargetRegisterClass;
+class TargetRegisterInfo;
+class BranchProbability;
+
+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
+public:
+ TargetInstrInfo(int CFSetupOpcode = -1, int CFDestroyOpcode = -1)
+ : CallFrameSetupOpcode(CFSetupOpcode),
+ CallFrameDestroyOpcode(CFDestroyOpcode) {
+ }
+
+ virtual ~TargetInstrInfo();
+
+ /// getRegClass - Givem a machine instruction descriptor, returns the register
+ /// class constraint for OpNum, or NULL.
+ const TargetRegisterClass *getRegClass(const MCInstrDesc &TID,
+ unsigned OpNum,
+ const TargetRegisterInfo *TRI) const;
+
+ /// isTriviallyReMaterializable - Return true if the instruction is trivially
+ /// rematerializable, meaning it has no side effects and requires no operands
+ /// that aren't always available.
+ bool isTriviallyReMaterializable(const MachineInstr *MI,
+ AliasAnalysis *AA = 0) const {
+ return MI->getOpcode() == TargetOpcode::IMPLICIT_DEF ||
+ (MI->getDesc().isRematerializable() &&
+ (isReallyTriviallyReMaterializable(MI, AA) ||
+ isReallyTriviallyReMaterializableGeneric(MI, AA)));
+ }
+
+protected:
+ /// isReallyTriviallyReMaterializable - For instructions with opcodes for
+ /// which the M_REMATERIALIZABLE flag is set, this hook lets the target
+ /// specify whether the instruction is actually trivially rematerializable,
+ /// taking into consideration its operands. This predicate must return false
+ /// if the instruction has any side effects other than producing a value, or
+ /// if it requres any address registers that are not always available.
+ virtual bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
+ AliasAnalysis *AA) const {
+ return false;
+ }
+
+private:
+ /// isReallyTriviallyReMaterializableGeneric - For instructions with opcodes
+ /// for which the M_REMATERIALIZABLE flag is set and the target hook
+ /// isReallyTriviallyReMaterializable returns false, this function does
+ /// target-independent tests to determine if the instruction is really
+ /// trivially rematerializable.
+ bool isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI,
+ AliasAnalysis *AA) const;
+
+public:
+ /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
+ /// frame setup/destroy instructions if they exist (-1 otherwise). Some
+ /// targets use pseudo instructions in order to abstract away the difference
+ /// between operating with a frame pointer and operating without, through the
+ /// use of these two instructions.
+ ///
+ int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
+ int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+
+ /// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
+ /// extension instruction. That is, it's like a copy where it's legal for the
+ /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
+ /// true, then it's expected the pre-extension value is available as a subreg
+ /// of the result register. This also returns the sub-register index in
+ /// SubIdx.
+ virtual bool isCoalescableExtInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SubIdx) const {
+ return false;
+ }
+
+ /// isLoadFromStackSlot - If the specified machine instruction is a direct
+ /// load from a stack slot, return the virtual or physical register number of
+ /// the destination along with the FrameIndex of the loaded stack slot. If
+ /// not, return 0. This predicate must return 0 if the instruction has
+ /// any side effects other than loading from the stack slot.
+ virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination
+ /// stack locations as well. This uses a heuristic so it isn't
+ /// reliable for correctness.
+ virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// hasLoadFromStackSlot - If the specified machine instruction has
+ /// a load from a stack slot, return true along with the FrameIndex
+ /// of the loaded stack slot and the machine mem operand containing
+ /// the reference. If not, return false. Unlike
+ /// isLoadFromStackSlot, this returns true for any instructions that
+ /// loads from the stack. This is just a hint, as some cases may be
+ /// missed.
+ virtual bool hasLoadFromStackSlot(const MachineInstr *MI,
+ const MachineMemOperand *&MMO,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// isStoreToStackSlot - If the specified machine instruction is a direct
+ /// store to a stack slot, return the virtual or physical register number of
+ /// the source reg along with the FrameIndex of the loaded stack slot. If
+ /// not, return 0. This predicate must return 0 if the instruction has
+ /// any side effects other than storing to the stack slot.
+ virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// isStoreToStackSlotPostFE - Check for post-frame ptr elimination
+ /// stack locations as well. This uses a heuristic so it isn't
+ /// reliable for correctness.
+ virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI,
+ int &FrameIndex) const {
+ return 0;
+ }
+
+ /// hasStoreToStackSlot - If the specified machine instruction has a
+ /// store to a stack slot, return true along with the FrameIndex of
+ /// the loaded stack slot and the machine mem operand containing the
+ /// reference. If not, return false. Unlike isStoreToStackSlot,
+ /// this returns true for any instructions that stores to the
+ /// 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;
+ }
+
+ /// reMaterialize - Re-issue the specified 'original' instruction at the
+ /// specific location targeting a new destination register.
+ /// The register in Orig->getOperand(0).getReg() will be substituted by
+ /// DestReg:SubIdx. Any existing subreg index is preserved or composed with
+ /// SubIdx.
+ virtual void reMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg, unsigned SubIdx,
+ const MachineInstr *Orig,
+ const TargetRegisterInfo &TRI) const = 0;
+
+ /// scheduleTwoAddrSource - Schedule the copy / re-mat of the source of the
+ /// two-addrss instruction inserted by two-address pass.
+ virtual void scheduleTwoAddrSource(MachineInstr *SrcMI,
+ MachineInstr *UseMI,
+ const TargetRegisterInfo &TRI) const {
+ // Do nothing.
+ }
+
+ /// duplicate - Create a duplicate of the Orig instruction in MF. This is like
+ /// MachineFunction::CloneMachineInstr(), but the target may update operands
+ /// that are required to be unique.
+ ///
+ /// The instruction must be duplicable as indicated by isNotDuplicable().
+ virtual MachineInstr *duplicate(MachineInstr *Orig,
+ MachineFunction &MF) const = 0;
+
+ /// convertToThreeAddress - This method must be implemented by targets that
+ /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
+ /// may be able to convert a two-address instruction into one or more true
+ /// three-address instructions on demand. This allows the X86 target (for
+ /// example) to convert ADD and SHL instructions into LEA instructions if they
+ /// would require register copies due to two-addressness.
+ ///
+ /// This method returns a null pointer if the transformation cannot be
+ /// performed, otherwise it returns the last new instruction.
+ ///
+ virtual MachineInstr *
+ convertToThreeAddress(MachineFunction::iterator &MFI,
+ MachineBasicBlock::iterator &MBBI, LiveVariables *LV) const {
+ return 0;
+ }
+
+ /// commuteInstruction - If a target has any instructions that are
+ /// commutable but require converting to different instructions or making
+ /// non-trivial changes to commute them, this method can overloaded to do
+ /// that. The default implementation simply swaps the commutable operands.
+ /// If NewMI is false, MI is modified in place and returned; otherwise, a
+ /// new machine instruction is created and returned. Do not call this
+ /// 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;
+
+ /// 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;
+
+ /// produceSameValue - Return true if two machine instructions would produce
+ /// identical values. By default, this is only true when the two instructions
+ /// are deemed identical except for defs. If this function is called when the
+ /// IR is still in SSA form, the caller can pass the MachineRegisterInfo for
+ /// aggressive checks.
+ virtual bool produceSameValue(const MachineInstr *MI0,
+ const MachineInstr *MI1,
+ const MachineRegisterInfo *MRI = 0) const = 0;
+
+ /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
+ /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
+ /// implemented for a target). Upon success, this returns false and returns
+ /// with the following information in various cases:
+ ///
+ /// 1. If this block ends with no branches (it just falls through to its succ)
+ /// just return false, leaving TBB/FBB null.
+ /// 2. If this block ends with only an unconditional branch, it sets TBB to be
+ /// the destination block.
+ /// 3. If this block ends with a conditional branch and it falls through to a
+ /// successor block, it sets TBB to be the branch destination block and a
+ /// list of operands that evaluate the condition. These operands can be
+ /// passed to other TargetInstrInfo methods to create new branches.
+ /// 4. If this block ends with a conditional branch followed by an
+ /// unconditional branch, it returns the 'true' destination in TBB, the
+ /// 'false' destination in FBB, and a list of operands that evaluate the
+ /// condition. These operands can be passed to other TargetInstrInfo
+ /// methods to create new branches.
+ ///
+ /// Note that RemoveBranch and InsertBranch must be implemented to support
+ /// cases where this method returns success.
+ ///
+ /// If AllowModify is true, then this routine is allowed to modify the basic
+ /// block (e.g. delete instructions after the unconditional branch).
+ ///
+ virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ SmallVectorImpl<MachineOperand> &Cond,
+ bool AllowModify = false) const {
+ return true;
+ }
+
+ /// RemoveBranch - Remove the branching code at the end of the specific MBB.
+ /// This is only invoked in cases where AnalyzeBranch returns success. It
+ /// returns the number of instructions that were removed.
+ virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
+ llvm_unreachable("Target didn't implement TargetInstrInfo::RemoveBranch!");
+ }
+
+ /// InsertBranch - Insert branch code into the end of the specified
+ /// MachineBasicBlock. The operands to this method are the same as those
+ /// returned by AnalyzeBranch. This is only invoked in cases where
+ /// AnalyzeBranch returns success. It returns the number of instructions
+ /// inserted.
+ ///
+ /// It is also invoked by tail merging to add unconditional branches in
+ /// cases where AnalyzeBranch doesn't apply because there was no original
+ /// branch to analyze. At least this much must be implemented, else tail
+ /// merging needs to be disabled.
+ virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ const SmallVectorImpl<MachineOperand> &Cond,
+ DebugLoc DL) const {
+ llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!");
+ }
+
+ /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything
+ /// 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;
+
+ /// isLegalToSplitMBBAt - Return true if it's legal to split the given basic
+ /// block at the specified instruction (i.e. instruction would be the start
+ /// of a new basic block).
+ virtual bool isLegalToSplitMBBAt(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI) const {
+ return true;
+ }
+
+ /// isProfitableToIfCvt - Return true if it's profitable to predicate
+ /// instructions with accumulated instruction latency of "NumCycles"
+ /// of the specified basic block, where the probability of the instructions
+ /// being executed is given by Probability, and Confidence is a measure
+ /// of our confidence that it will be properly predicted.
+ virtual
+ bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
+ unsigned ExtraPredCycles,
+ const BranchProbability &Probability) const {
+ return false;
+ }
+
+ /// isProfitableToIfCvt - Second variant of isProfitableToIfCvt, this one
+ /// checks for the case where two basic blocks from true and false path
+ /// of a if-then-else (diamond) are predicated on mutally exclusive
+ /// predicates, where the probability of the true path being taken is given
+ /// by Probability, and Confidence is a measure of our confidence that it
+ /// will be properly predicted.
+ virtual bool
+ isProfitableToIfCvt(MachineBasicBlock &TMBB,
+ unsigned NumTCycles, unsigned ExtraTCycles,
+ MachineBasicBlock &FMBB,
+ unsigned NumFCycles, unsigned ExtraFCycles,
+ const BranchProbability &Probability) const {
+ return false;
+ }
+
+ /// isProfitableToDupForIfCvt - Return true if it's profitable for
+ /// if-converter to duplicate instructions of specified accumulated
+ /// instruction latencies in the specified MBB to enable if-conversion.
+ /// The probability of the instructions being executed is given by
+ /// Probability, and Confidence is a measure of our confidence that it
+ /// will be properly predicted.
+ virtual bool
+ isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCyles,
+ const BranchProbability &Probability) const {
+ return false;
+ }
+
+ /// isProfitableToUnpredicate - Return true if it's profitable to unpredicate
+ /// one side of a 'diamond', i.e. two sides of if-else predicated on mutually
+ /// exclusive predicates.
+ /// e.g.
+ /// subeq r0, r1, #1
+ /// addne r0, r1, #1
+ /// =>
+ /// sub r0, r1, #1
+ /// addne r0, r1, #1
+ ///
+ /// This may be profitable is conditional instructions are always executed.
+ virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
+ MachineBasicBlock &FMBB) const {
+ return false;
+ }
+
+ /// copyPhysReg - Emit instructions to copy a pair of physical registers.
+ virtual void copyPhysReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI, DebugLoc DL,
+ unsigned DestReg, unsigned SrcReg,
+ bool KillSrc) const {
+ llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!");
+ }
+
+ /// storeRegToStackSlot - Store the specified register of the given register
+ /// class to the specified stack frame index. The store instruction is to be
+ /// added to the given machine basic block before the specified machine
+ /// instruction. If isKill is true, the register operand is the last use and
+ /// must be marked kill.
+ virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned SrcReg, bool isKill, int FrameIndex,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::storeRegToStackSlot!");
+ }
+
+ /// loadRegFromStackSlot - Load the specified register of the given register
+ /// class from the specified stack frame index. The load instruction is to be
+ /// added to the given machine basic block before the specified machine
+ /// instruction.
+ virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg, int FrameIndex,
+ const TargetRegisterClass *RC,
+ const TargetRegisterInfo *TRI) const {
+ llvm_unreachable("Target didn't implement "
+ "TargetInstrInfo::loadRegFromStackSlot!");
+ }
+
+ /// expandPostRAPseudo - This function is called for all pseudo instructions
+ /// that remain after register allocation. Many pseudo instructions are
+ /// created to help register allocation. This is the place to convert them
+ /// into real instructions. The target can edit MI in place, or it can insert
+ /// new instructions and erase MI. The function should return true if
+ /// anything was changed.
+ virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
+ return false;
+ }
+
+ /// emitFrameIndexDebugValue - Emit a target-dependent form of
+ /// DBG_VALUE encoding the address of a frame index. Addresses would
+ /// normally be lowered the same way as other addresses on the target,
+ /// e.g. in load instructions. For targets that do not support this
+ /// the debug info is simply lost.
+ /// If you add this for a target you should handle this DBG_VALUE in the
+ /// target-specific AsmPrinter code as well; you will probably get invalid
+ /// assembly output if you don't.
+ virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
+ int FrameIx,
+ uint64_t Offset,
+ const MDNode *MDPtr,
+ DebugLoc dl) const {
+ return 0;
+ }
+
+ /// foldMemoryOperand - Attempt to fold a load or store of the specified stack
+ /// slot into the specified machine instruction for the specified operand(s).
+ /// If this is possible, a new instruction is returned with the specified
+ /// operand folded, otherwise NULL is returned.
+ /// The new instruction is inserted before MI, and the client is responsible
+ /// for removing the old instruction.
+ MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ int FrameIndex) const;
+
+ /// foldMemoryOperand - Same as the previous version except it allows folding
+ /// of any load and store from / to any address, not just from a specific
+ /// stack slot.
+ MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const;
+
+protected:
+ /// foldMemoryOperandImpl - Target-dependent implementation for
+ /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+ /// take care of adding a MachineMemOperand to the newly created instruction.
+ virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ int FrameIndex) const {
+ return 0;
+ }
+
+ /// foldMemoryOperandImpl - Target-dependent implementation for
+ /// foldMemoryOperand. Target-independent code in foldMemoryOperand will
+ /// take care of adding a MachineMemOperand to the newly created instruction.
+ virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr* MI,
+ const SmallVectorImpl<unsigned> &Ops,
+ MachineInstr* LoadMI) const {
+ return 0;
+ }
+
+public:
+ /// canFoldMemoryOperand - Returns true for the specified load / store if
+ /// folding is possible.
+ virtual
+ bool canFoldMemoryOperand(const MachineInstr *MI,
+ const SmallVectorImpl<unsigned> &Ops) const =0;
+
+ /// 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
+ /// possible, returns true as well as the new instructions by reference.
+ virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI,
+ unsigned Reg, bool UnfoldLoad, bool UnfoldStore,
+ SmallVectorImpl<MachineInstr*> &NewMIs) const{
+ return false;
+ }
+
+ virtual bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N,
+ SmallVectorImpl<SDNode*> &NewNodes) const {
+ return false;
+ }
+
+ /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new
+ /// instruction after load / store are unfolded from an instruction of the
+ /// specified opcode. It returns zero if the specified unfolding is not
+ /// possible. If LoadRegIndex is non-null, it is filled in with the operand
+ /// index of the operand which will hold the register holding the loaded
+ /// value.
+ virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
+ bool UnfoldLoad, bool UnfoldStore,
+ unsigned *LoadRegIndex = 0) const {
+ return 0;
+ }
+
+ /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler
+ /// to determine if two loads are loading from the same base address. It
+ /// should only return true if the base pointers are the same and the
+ /// only differences between the two addresses are the offset. It also returns
+ /// the offsets by reference.
+ virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const {
+ return false;
+ }
+
+ /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
+ /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should
+ /// be scheduled togther. On some targets if two loads are loading from
+ /// addresses in the same cache line, it's better if they are scheduled
+ /// together. This function takes two integers that represent the load offsets
+ /// from the common base address. It returns true if it decides it's desirable
+ /// to schedule the two loads together. "NumLoads" is the number of loads that
+ /// have already been scheduled after Load1.
+ virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const {
+ return false;
+ }
+
+ /// ReverseBranchCondition - Reverses the branch condition of the specified
+ /// condition list, returning false on success and true if it cannot be
+ /// reversed.
+ virtual
+ bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
+ return true;
+ }
+
+ /// insertNoop - Insert a noop into the instruction stream at the specified
+ /// point.
+ virtual void insertNoop(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const;
+
+
+ /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+ virtual void getNoopForMachoTarget(MCInst &NopInst) const {
+ // Default to just using 'nop' string.
+ }
+
+
+ /// isPredicated - Returns true if the instruction is already predicated.
+ ///
+ virtual bool isPredicated(const MachineInstr *MI) const {
+ return false;
+ }
+
+ /// isUnpredicatedTerminator - Returns true if the instruction is a
+ /// terminator instruction that has not been predicated.
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const = 0;
+
+ /// 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;
+
+ /// SubsumesPredicate - Returns true if the first specified predicate
+ /// subsumes the second, e.g. GE subsumes GT.
+ virtual
+ bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
+ const SmallVectorImpl<MachineOperand> &Pred2) const {
+ return false;
+ }
+
+ /// DefinesPredicate - If the specified instruction defines any predicate
+ /// or condition code register(s) used for predication, returns true as well
+ /// as the definition predicate(s) by reference.
+ virtual bool DefinesPredicate(MachineInstr *MI,
+ std::vector<MachineOperand> &Pred) const {
+ return false;
+ }
+
+ /// isPredicable - Return true if the specified instruction can be predicated.
+ /// By default, this returns true for every instruction with a
+ /// PredicateOperand.
+ virtual bool isPredicable(MachineInstr *MI) const {
+ return MI->getDesc().isPredicable();
+ }
+
+ /// isSafeToMoveRegClassDefs - Return true if it's safe to move a machine
+ /// instruction that defines the specified register class.
+ virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
+ return true;
+ }
+
+ /// isSchedulingBoundary - Test if the given instruction should be
+ /// considered a scheduling boundary. This primarily includes labels and
+ /// terminators.
+ virtual bool isSchedulingBoundary(const MachineInstr *MI,
+ const MachineBasicBlock *MBB,
+ const MachineFunction &MF) const = 0;
+
+ /// Measure the specified inline asm to determine an approximation of its
+ /// length.
+ virtual unsigned getInlineAsmLength(const char *Str,
+ const MCAsmInfo &MAI) const;
+
+ /// CreateTargetHazardRecognizer - Allocate and return a hazard recognizer to
+ /// use for this target when scheduling the machine instructions before
+ /// register allocation.
+ virtual ScheduleHazardRecognizer*
+ CreateTargetHazardRecognizer(const TargetMachine *TM,
+ const ScheduleDAG *DAG) const = 0;
+
+ /// 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;
+
+ /// AnalyzeCompare - For a comparison instruction, return the source register
+ /// in SrcReg and the value it compares against in CmpValue. Return true if
+ /// the comparison instruction can be analyzed.
+ virtual bool AnalyzeCompare(const MachineInstr *MI,
+ unsigned &SrcReg, int &Mask, int &Value) const {
+ return false;
+ }
+
+ /// OptimizeCompareInstr - See if the comparison instruction can be converted
+ /// into something more efficient. E.g., on ARM most instructions can set the
+ /// flags register, obviating the need for a separate CMP.
+ virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr,
+ unsigned SrcReg, int Mask, int Value,
+ const MachineRegisterInfo *MRI) const {
+ return false;
+ }
+
+ /// FoldImmediate - 'Reg' is known to be defined by a move immediate
+ /// instruction, try to fold the immediate into the use instruction.
+ virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
+ unsigned Reg, MachineRegisterInfo *MRI) const {
+ return false;
+ }
+
+ /// getNumMicroOps - Return the number of u-operations the given machine
+ /// instruction will be decoded to on the target cpu.
+ virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
+ 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
+ /// scheduler should consider free, rather than conservatively handling them
+ /// as instructions with no itinerary.
+ bool isZeroCost(unsigned Opcode) const {
+ return Opcode <= TargetOpcode::COPY;
+ }
+
+ /// getOperandLatency - Compute and return the use operand latency of a given
+ /// pair of def and use.
+ /// In most cases, the static scheduling itinerary was enough to determine the
+ /// operand latency. But it may not be possible for instructions with variable
+ /// number of defs / uses.
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *UseMI, unsigned UseIdx) const;
+
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ SDNode *DefNode, unsigned DefIdx,
+ SDNode *UseNode, unsigned UseIdx) const = 0;
+
+ /// 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 int getInstrLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *MI,
+ unsigned *PredCost = 0) const;
+
+ virtual int getInstrLatency(const InstrItineraryData *ItinData,
+ SDNode *Node) const = 0;
+
+ /// isHighLatencyDef - Return true if this opcode has high latency to its
+ /// result.
+ virtual bool isHighLatencyDef(int opc) const { return false; }
+
+ /// hasHighOperandLatency - Compute operand latency between a def of 'Reg'
+ /// and an use in the current loop, return true if the target considered
+ /// it 'high'. This is used by optimization passes such as machine LICM to
+ /// determine whether it makes sense to hoist an instruction out even in
+ /// high register pressure situation.
+ virtual
+ bool hasHighOperandLatency(const InstrItineraryData *ItinData,
+ const MachineRegisterInfo *MRI,
+ const MachineInstr *DefMI, unsigned DefIdx,
+ const MachineInstr *UseMI, unsigned UseIdx) const {
+ return false;
+ }
+
+ /// hasLowDefLatency - Compute operand latency of a def of 'Reg', return true
+ /// if the target considered it 'low'.
+ virtual
+ bool hasLowDefLatency(const InstrItineraryData *ItinData,
+ const MachineInstr *DefMI, unsigned DefIdx) const;
+
+ /// verifyInstruction - Perform target specific instruction verification.
+ virtual
+ bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const {
+ return true;
+ }
+
+ /// getExecutionDomain - Return the current execution domain and bit mask of
+ /// possible domains for instruction.
+ ///
+ /// Some micro-architectures have multiple execution domains, and multiple
+ /// opcodes that perform the same operation in different domains. For
+ /// example, the x86 architecture provides the por, orps, and orpd
+ /// instructions that all do the same thing. There is a latency penalty if a
+ /// register is written in one domain and read in another.
+ ///
+ /// This function returns a pair (domain, mask) containing the execution
+ /// domain of MI, and a bit mask of possible domains. The setExecutionDomain
+ /// function can be used to change the opcode to one of the domains in the
+ /// bit mask. Instructions whose execution domain can't be changed should
+ /// return a 0 mask.
+ ///
+ /// The execution domain numbers don't have any special meaning except domain
+ /// 0 is used for instructions that are not associated with any interesting
+ /// execution domain.
+ ///
+ virtual std::pair<uint16_t, uint16_t>
+ getExecutionDomain(const MachineInstr *MI) const {
+ return std::make_pair(0, 0);
+ }
+
+ /// setExecutionDomain - Change the opcode of MI to execute in Domain.
+ ///
+ /// The bit (1 << Domain) must be set in the mask returned from
+ /// getExecutionDomain(MI).
+ ///
+ virtual void setExecutionDomain(MachineInstr *MI, unsigned Domain) const {}
+
+
+ /// getPartialRegUpdateClearance - Returns the preferred minimum clearance
+ /// before an instruction with an unwanted partial register update.
+ ///
+ /// Some instructions only write part of a register, and implicitly need to
+ /// read the other parts of the register. This may cause unwanted stalls
+ /// preventing otherwise unrelated instructions from executing in parallel in
+ /// an out-of-order CPU.
+ ///
+ /// For example, the x86 instruction cvtsi2ss writes its result to bits
+ /// [31:0] of the destination xmm register. Bits [127:32] are unaffected, so
+ /// the instruction needs to wait for the old value of the register to become
+ /// available:
+ ///
+ /// addps %xmm1, %xmm0
+ /// movaps %xmm0, (%rax)
+ /// cvtsi2ss %rbx, %xmm0
+ ///
+ /// In the code above, the cvtsi2ss instruction needs to wait for the addps
+ /// instruction before it can issue, even though the high bits of %xmm0
+ /// probably aren't needed.
+ ///
+ /// This hook returns the preferred clearance before MI, measured in
+ /// instructions. Other defs of MI's operand OpNum are avoided in the last N
+ /// instructions before MI. It should only return a positive value for
+ /// unwanted dependencies. If the old bits of the defined register have
+ /// useful values, or if MI is determined to otherwise read the dependency,
+ /// the hook should return 0.
+ ///
+ /// The unwanted dependency may be handled by:
+ ///
+ /// 1. Allocating the same register for an MI def and use. That makes the
+ /// unwanted dependency identical to a required dependency.
+ ///
+ /// 2. Allocating a register for the def that has no defs in the previous N
+ /// instructions.
+ ///
+ /// 3. Calling breakPartialRegDependency() with the same arguments. This
+ /// allows the target to insert a dependency breaking instruction.
+ ///
+ virtual unsigned
+ getPartialRegUpdateClearance(const MachineInstr *MI, unsigned OpNum,
+ const TargetRegisterInfo *TRI) const {
+ // The default implementation returns 0 for no partial register dependency.
+ return 0;
+ }
+
+ /// breakPartialRegDependency - Insert a dependency-breaking instruction
+ /// before MI to eliminate an unwanted dependency on OpNum.
+ ///
+ /// If it wasn't possible to avoid a def in the last N instructions before MI
+ /// (see getPartialRegUpdateClearance), this hook will be called to break the
+ /// unwanted dependency.
+ ///
+ /// On x86, an xorps instruction can be used as a dependency breaker:
+ ///
+ /// addps %xmm1, %xmm0
+ /// movaps %xmm0, (%rax)
+ /// xorps %xmm0, %xmm0
+ /// cvtsi2ss %rbx, %xmm0
+ ///
+ /// An <imp-kill> operand should be added to MI if an instruction was
+ /// inserted. This ties the instructions together in the post-ra scheduler.
+ ///
+ virtual void
+ breakPartialRegDependency(MachineBasicBlock::iterator MI, unsigned OpNum,
+ const TargetRegisterInfo *TRI) const {}
+
+ /// Create machine specific model for scheduling.
+ virtual DFAPacketizer*
+ CreateTargetScheduleState(const TargetMachine*, const ScheduleDAG*) const {
+ return NULL;
+ }
+
+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;
+ using TargetInstrInfo::getOperandLatency;
+ virtual int getOperandLatency(const InstrItineraryData *ItinData,
+ SDNode *DefNode, unsigned DefIdx,
+ SDNode *UseNode, unsigned UseIdx) const;
+ using TargetInstrInfo::getInstrLatency;
+ virtual int getInstrLatency(const InstrItineraryData *ItinData,
+ SDNode *Node) const;
+
+ bool usePreRAHazardRecognizer() const;
+
+ virtual ScheduleHazardRecognizer *
+ CreateTargetHazardRecognizer(const TargetMachine*, const ScheduleDAG*) const;
+
+ virtual ScheduleHazardRecognizer *
+ CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
+ const ScheduleDAG*) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetIntrinsicInfo.h b/contrib/llvm/include/llvm/Target/TargetIntrinsicInfo.h
new file mode 100644
index 000000000000..c44b9230c0d8
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetIntrinsicInfo.h
@@ -0,0 +1,64 @@
+//===-- llvm/Target/TargetIntrinsicInfo.h - Instruction 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 describes the target intrinsic instructions to the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETINTRINSICINFO_H
+#define LLVM_TARGET_TARGETINTRINSICINFO_H
+
+#include <string>
+
+namespace llvm {
+
+class Function;
+class Module;
+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
+public:
+ TargetIntrinsicInfo();
+ virtual ~TargetIntrinsicInfo();
+
+ /// Return the name of a target intrinsic, e.g. "llvm.bfin.ssync".
+ /// The Tys and numTys parameters are for intrinsics with overloaded types
+ /// (e.g., those using iAny or fAny). For a declaration for an overloaded
+ /// intrinsic, Tys should point to an array of numTys pointers to Type,
+ /// and must provide exactly one type for each overloaded type in the
+ /// intrinsic.
+ virtual std::string getName(unsigned IID, Type **Tys = 0,
+ unsigned numTys = 0) const = 0;
+
+ /// Look up target intrinsic by name. Return intrinsic ID or 0 for unknown
+ /// names.
+ virtual unsigned lookupName(const char *Name, unsigned Len) const =0;
+
+ /// Return the target intrinsic ID of a function, or 0.
+ virtual unsigned getIntrinsicID(Function *F) const;
+
+ /// Returns true if the intrinsic can be overloaded.
+ virtual bool isOverloaded(unsigned IID) const = 0;
+
+ /// Create or insert an LLVM Function declaration for an intrinsic,
+ /// and return it. The Tys and numTys are for intrinsics with overloaded
+ /// types. See above for more information.
+ virtual Function *getDeclaration(Module *M, unsigned ID, Type **Tys = 0,
+ unsigned numTys = 0) const = 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetJITInfo.h b/contrib/llvm/include/llvm/Target/TargetJITInfo.h
new file mode 100644
index 000000000000..044afd9b7392
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetJITInfo.h
@@ -0,0 +1,137 @@
+//===- Target/TargetJITInfo.h - Target Information for JIT ------*- 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 abstract interface used by the Just-In-Time code
+// generator to perform target-specific activities, such as emitting stubs. If
+// a TargetMachine supports JIT code generation, it should provide one of these
+// objects through the getJITInfo() method.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETJITINFO_H
+#define LLVM_TARGET_TARGETJITINFO_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+ class Function;
+ class GlobalValue;
+ class JITCodeEmitter;
+ class MachineRelocation;
+
+ /// TargetJITInfo - Target specific information required by the Just-In-Time
+ /// code generator.
+ class TargetJITInfo {
+ virtual void anchor();
+ public:
+ virtual ~TargetJITInfo() {}
+
+ /// replaceMachineCodeForFunction - Make it so that calling the function
+ /// whose machine code is at OLD turns into a call to NEW, perhaps by
+ /// overwriting OLD with a branch to NEW. This is used for self-modifying
+ /// code.
+ ///
+ virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
+
+ /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object
+ /// to emit an indirect symbol which contains the address of the specified
+ /// ptr.
+ virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
+ JITCodeEmitter &JCE) {
+ llvm_unreachable("This target doesn't implement "
+ "emitGlobalValueIndirectSym!");
+ }
+
+ /// Records the required size and alignment for a call stub in bytes.
+ struct StubLayout {
+ size_t Size;
+ size_t Alignment;
+ };
+ /// Returns the maximum size and alignment for a call stub on this target.
+ virtual StubLayout getStubLayout() {
+ llvm_unreachable("This target doesn't implement getStubLayout!");
+ }
+
+ /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
+ /// small native function that simply calls the function at the specified
+ /// address. The JITCodeEmitter must already have storage allocated for the
+ /// stub. Return the address of the resultant function, which may have been
+ /// aligned from the address the JCE was set up to emit at.
+ virtual void *emitFunctionStub(const Function* F, void *Target,
+ JITCodeEmitter &JCE) {
+ llvm_unreachable("This target doesn't implement emitFunctionStub!");
+ }
+
+ /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
+ /// specific basic block.
+ virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) {
+ llvm_unreachable("This target doesn't implement getPICJumpTableEntry!");
+ }
+
+ /// LazyResolverFn - This typedef is used to represent the function that
+ /// unresolved call points should invoke. This is a target specific
+ /// function that knows how to walk the stack and find out which stub the
+ /// call is coming from.
+ typedef void (*LazyResolverFn)();
+
+ /// JITCompilerFn - This typedef is used to represent the JIT function that
+ /// lazily compiles the function corresponding to a stub. The JIT keeps
+ /// track of the mapping between stubs and LLVM Functions, the target
+ /// provides the ability to figure out the address of a stub that is called
+ /// by the LazyResolverFn.
+ typedef void* (*JITCompilerFn)(void *);
+
+ /// getLazyResolverFunction - This method is used to initialize the JIT,
+ /// giving the target the function that should be used to compile a
+ /// function, and giving the JIT the target function used to do the lazy
+ /// resolving.
+ virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) {
+ llvm_unreachable("Not implemented for this target!");
+ }
+
+ /// relocate - Before the JIT can run a block of code that has been emitted,
+ /// it must rewrite the code to contain the actual addresses of any
+ /// referenced global symbols.
+ virtual void relocate(void *Function, MachineRelocation *MR,
+ unsigned NumRelocs, unsigned char* GOTBase) {
+ assert(NumRelocs == 0 && "This target does not have relocations!");
+ }
+
+
+ /// allocateThreadLocalMemory - Each target has its own way of
+ /// handling thread local variables. This method returns a value only
+ /// meaningful to the target.
+ virtual char* allocateThreadLocalMemory(size_t size) {
+ llvm_unreachable("This target does not implement thread local storage!");
+ }
+
+ /// needsGOT - Allows a target to specify that it would like the
+ /// JIT to manage a GOT for it.
+ bool needsGOT() const { return useGOT; }
+
+ /// hasCustomConstantPool - Allows a target to specify that constant
+ /// pool address resolution is handled by the target.
+ virtual bool hasCustomConstantPool() const { return false; }
+
+ /// hasCustomJumpTables - Allows a target to specify that jumptables
+ /// are emitted by the target.
+ virtual bool hasCustomJumpTables() const { return false; }
+
+ /// allocateSeparateGVMemory - If true, globals should be placed in
+ /// separately allocated heap memory rather than in the same
+ /// code memory allocated by JITCodeEmitter.
+ virtual bool allocateSeparateGVMemory() const { return false; }
+ protected:
+ bool useGOT;
+ };
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h b/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h
new file mode 100644
index 000000000000..c8cacf284d0a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetLibraryInfo.h
@@ -0,0 +1,293 @@
+//===-- llvm/Target/TargetLibraryInfo.h - Library information ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLIBRARYINFO_H
+#define LLVM_TARGET_TARGETLIBRARYINFO_H
+
+#include "llvm/Pass.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+ class Triple;
+
+ namespace LibFunc {
+ enum Func {
+ /// double acos(double x);
+ acos,
+ /// long double acosl(long double x);
+ acosl,
+ /// float acosf(float x);
+ acosf,
+ /// double asin(double x);
+ asin,
+ /// long double asinl(long double x);
+ asinl,
+ /// float asinf(float x);
+ asinf,
+ /// double atan(double x);
+ atan,
+ /// long double atanl(long double x);
+ atanl,
+ /// float atanf(float x);
+ atanf,
+ /// double atan2(double y, double x);
+ atan2,
+ /// long double atan2l(long double y, long double x);
+ atan2l,
+ /// float atan2f(float y, float x);
+ atan2f,
+ /// double ceil(double x);
+ ceil,
+ /// long double ceill(long double x);
+ ceill,
+ /// float ceilf(float x);
+ ceilf,
+ /// double copysign(double x, double y);
+ copysign,
+ /// float copysignf(float x, float y);
+ copysignf,
+ /// long double copysignl(long double x, long double y);
+ copysignl,
+ /// double cos(double x);
+ cos,
+ /// long double cosl(long double x);
+ cosl,
+ /// float cosf(float x);
+ cosf,
+ /// double cosh(double x);
+ cosh,
+ /// long double coshl(long double x);
+ coshl,
+ /// float coshf(float x);
+ coshf,
+ /// double exp(double x);
+ exp,
+ /// long double expl(long double x);
+ expl,
+ /// float expf(float x);
+ expf,
+ /// double exp2(double x);
+ exp2,
+ /// long double exp2l(long double x);
+ exp2l,
+ /// float exp2f(float x);
+ exp2f,
+ /// double expm1(double x);
+ expm1,
+ /// long double expm1l(long double x);
+ expm1l,
+ /// float expm1f(float x);
+ expm1f,
+ /// double fabs(double x);
+ fabs,
+ /// long double fabsl(long double x);
+ fabsl,
+ /// float fabsf(float x);
+ fabsf,
+ /// double floor(double x);
+ floor,
+ /// long double floorl(long double x);
+ floorl,
+ /// float floorf(float x);
+ floorf,
+ /// int fiprintf(FILE *stream, const char *format, ...);
+ fiprintf,
+ /// double fmod(double x, double y);
+ fmod,
+ /// long double fmodl(long double x, long double y);
+ fmodl,
+ /// float fmodf(float x, float y);
+ fmodf,
+ /// int fputs(const char *s, FILE *stream);
+ fputs,
+ /// size_t fwrite(const void *ptr, size_t size, size_t nitems,
+ /// FILE *stream);
+ fwrite,
+ /// int iprintf(const char *format, ...);
+ iprintf,
+ /// double log(double x);
+ log,
+ /// long double logl(long double x);
+ logl,
+ /// float logf(float x);
+ logf,
+ /// double log2(double x);
+ log2,
+ /// double long double log2l(long double x);
+ log2l,
+ /// float log2f(float x);
+ log2f,
+ /// double log10(double x);
+ log10,
+ /// long double log10l(long double x);
+ log10l,
+ /// float log10f(float x);
+ log10f,
+ /// double log1p(double x);
+ log1p,
+ /// long double log1pl(long double x);
+ log1pl,
+ /// float log1pf(float x);
+ log1pf,
+ /// void *memcpy(void *s1, const void *s2, size_t n);
+ memcpy,
+ /// void *memmove(void *s1, const void *s2, size_t n);
+ memmove,
+ /// void *memset(void *b, int c, size_t len);
+ memset,
+ /// void memset_pattern16(void *b, const void *pattern16, size_t len);
+ memset_pattern16,
+ /// double nearbyint(double x);
+ nearbyint,
+ /// float nearbyintf(float x);
+ nearbyintf,
+ /// long double nearbyintl(long double x);
+ nearbyintl,
+ /// double pow(double x, double y);
+ pow,
+ /// float powf(float x, float y);
+ powf,
+ /// long double powl(long double x, long double y);
+ powl,
+ /// double rint(double x);
+ rint,
+ /// float rintf(float x);
+ rintf,
+ /// long double rintl(long double x);
+ rintl,
+ /// double round(double x);
+ round,
+ /// float roundf(float x);
+ roundf,
+ /// long double roundl(long double x);
+ roundl,
+ /// double sin(double x);
+ sin,
+ /// long double sinl(long double x);
+ sinl,
+ /// float sinf(float x);
+ sinf,
+ /// double sinh(double x);
+ sinh,
+ /// long double sinhl(long double x);
+ sinhl,
+ /// float sinhf(float x);
+ sinhf,
+ /// int siprintf(char *str, const char *format, ...);
+ siprintf,
+ /// double sqrt(double x);
+ sqrt,
+ /// long double sqrtl(long double x);
+ sqrtl,
+ /// float sqrtf(float x);
+ sqrtf,
+ /// double tan(double x);
+ tan,
+ /// long double tanl(long double x);
+ tanl,
+ /// float tanf(float x);
+ tanf,
+ /// double tanh(double x);
+ tanh,
+ /// long double tanhl(long double x);
+ tanhl,
+ /// float tanhf(float x);
+ tanhf,
+ /// double trunc(double x);
+ trunc,
+ /// float truncf(float x);
+ truncf,
+ /// long double truncl(long double x);
+ truncl,
+ /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
+ cxa_atexit,
+ /// void __cxa_guard_abort(guard_t *guard);
+ /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
+ cxa_guard_abort,
+ /// int __cxa_guard_acquire(guard_t *guard);
+ cxa_guard_acquire,
+ /// void __cxa_guard_release(guard_t *guard);
+ cxa_guard_release,
+
+ NumLibFuncs
+ };
+ }
+
+/// TargetLibraryInfo - This immutable pass captures information about what
+/// library functions are available for the current target, and allows a
+/// frontend to disable optimizations through -fno-builtin etc.
+class TargetLibraryInfo : public ImmutablePass {
+ virtual void anchor();
+ unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
+ llvm::DenseMap<unsigned, std::string> CustomNames;
+ static const char* StandardNames[LibFunc::NumLibFuncs];
+
+ enum AvailabilityState {
+ StandardName = 3, // (memset to all ones)
+ CustomName = 1,
+ Unavailable = 0 // (memset to all zeros)
+ };
+ void setState(LibFunc::Func F, AvailabilityState State) {
+ AvailableArray[F/4] &= ~(3 << 2*(F&3));
+ AvailableArray[F/4] |= State << 2*(F&3);
+ }
+ AvailabilityState getState(LibFunc::Func F) const {
+ return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
+ }
+
+public:
+ static char ID;
+ TargetLibraryInfo();
+ TargetLibraryInfo(const Triple &T);
+ explicit TargetLibraryInfo(const TargetLibraryInfo &TLI);
+
+ /// has - This function is used by optimizations that want to match on or form
+ /// a given library function.
+ bool has(LibFunc::Func F) const {
+ return getState(F) != Unavailable;
+ }
+
+ StringRef getName(LibFunc::Func F) const {
+ AvailabilityState State = getState(F);
+ if (State == Unavailable)
+ return StringRef();
+ if (State == StandardName)
+ return StandardNames[F];
+ assert(State == CustomName);
+ return CustomNames.find(F)->second;
+ }
+
+ /// setUnavailable - this can be used by whatever sets up TargetLibraryInfo to
+ /// ban use of specific library functions.
+ void setUnavailable(LibFunc::Func F) {
+ setState(F, Unavailable);
+ }
+
+ void setAvailable(LibFunc::Func F) {
+ setState(F, StandardName);
+ }
+
+ void setAvailableWithName(LibFunc::Func F, StringRef Name) {
+ if (StandardNames[F] != Name) {
+ setState(F, CustomName);
+ CustomNames[F] = Name;
+ assert(CustomNames.find(F) != CustomNames.end());
+ } else {
+ setState(F, StandardName);
+ }
+ }
+
+ /// disableAllFunctions - This disables all builtins, which is used for
+ /// options like -fno-builtin.
+ void disableAllFunctions();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetLowering.h b/contrib/llvm/include/llvm/Target/TargetLowering.h
new file mode 100644
index 000000000000..720c9df99e2b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetLowering.h
@@ -0,0 +1,2051 @@
+//===-- llvm/Target/TargetLowering.h - Target Lowering 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 describes how to lower LLVM code to machine code. This has two
+// main components:
+//
+// 1. Which ValueTypes are natively supported by the target.
+// 2. Which operations are supported for supported ValueTypes.
+// 3. Cost thresholds for alternative implementations of certain operations.
+//
+// In addition it has a few other components, like information about FP
+// immediates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLOWERING_H
+#define LLVM_TARGET_TARGETLOWERING_H
+
+#include "llvm/CallingConv.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Attributes.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include "llvm/Support/DebugLoc.h"
+#include "llvm/Target/TargetCallingConv.h"
+#include "llvm/Target/TargetMachine.h"
+#include <climits>
+#include <map>
+#include <vector>
+
+namespace llvm {
+ class CallInst;
+ class CCState;
+ class FastISel;
+ class FunctionLoweringInfo;
+ class ImmutableCallSite;
+ class IntrinsicInst;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class MachineJumpTableInfo;
+ class MCContext;
+ class MCExpr;
+ template<typename T> class SmallVectorImpl;
+ class TargetData;
+ class TargetRegisterClass;
+ class TargetLoweringObjectFile;
+ class Value;
+
+ namespace Sched {
+ enum Preference {
+ None, // No preference
+ Source, // Follow source order.
+ RegPressure, // Scheduling for lowest register pressure.
+ Hybrid, // Scheduling for both latency and register pressure.
+ ILP, // Scheduling for ILP in low register pressure mode.
+ VLIW // Scheduling for VLIW targets.
+ };
+ }
+
+
+//===----------------------------------------------------------------------===//
+/// TargetLowering - This class defines information used to lower LLVM code to
+/// legal SelectionDAG operators that the target instruction selector can accept
+/// natively.
+///
+/// This class also defines callbacks that targets must implement to lower
+/// target-specific constructs to SelectionDAG operators.
+///
+class TargetLowering {
+ TargetLowering(const TargetLowering&); // DO NOT IMPLEMENT
+ void operator=(const TargetLowering&); // DO NOT IMPLEMENT
+public:
+ /// LegalizeAction - This enum indicates whether operations are valid for a
+ /// target, and if not, what action should be used to make them valid.
+ enum LegalizeAction {
+ Legal, // The target natively supports this operation.
+ Promote, // This operation should be executed in a larger type.
+ Expand, // Try to expand this to other ops, otherwise use a libcall.
+ Custom // Use the LowerOperation hook to implement custom lowering.
+ };
+
+ /// LegalizeTypeAction - This enum indicates whether a types are legal for a
+ /// target, and if not, what action should be used to make them valid.
+ enum LegalizeTypeAction {
+ TypeLegal, // The target natively supports this type.
+ TypePromoteInteger, // Replace this integer with a larger one.
+ TypeExpandInteger, // Split this integer into two of half the size.
+ TypeSoftenFloat, // Convert this float to a same size integer type.
+ TypeExpandFloat, // Split this float into two of half the size.
+ TypeScalarizeVector, // Replace this one-element vector with its element.
+ TypeSplitVector, // Split this vector into two of half the size.
+ TypeWidenVector // This vector should be widened into a larger vector.
+ };
+
+ 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.
+ ZeroOrNegativeOneBooleanContent // All bits equal to bit 0.
+ };
+
+ static ISD::NodeType getExtendForContent(BooleanContent Content) {
+ switch (Content) {
+ case UndefinedBooleanContent:
+ // Extend by adding rubbish bits.
+ return ISD::ANY_EXTEND;
+ case ZeroOrOneBooleanContent:
+ // Extend by adding zero bits.
+ return ISD::ZERO_EXTEND;
+ case ZeroOrNegativeOneBooleanContent:
+ // Extend by copying the sign bit.
+ return ISD::SIGN_EXTEND;
+ }
+ llvm_unreachable("Invalid content kind");
+ }
+
+ /// NOTE: The constructor takes ownership of TLOF.
+ explicit TargetLowering(const TargetMachine &TM,
+ const TargetLoweringObjectFile *TLOF);
+ virtual ~TargetLowering();
+
+ const TargetMachine &getTargetMachine() const { return TM; }
+ const TargetData *getTargetData() const { return TD; }
+ const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
+
+ bool isBigEndian() const { return !IsLittleEndian; }
+ bool isLittleEndian() const { return IsLittleEndian; }
+ MVT getPointerTy() const { return PointerTy; }
+ virtual MVT getShiftAmountTy(EVT LHSTy) const;
+
+ /// isSelectExpensive - Return true if the select operation is expensive for
+ /// this target.
+ bool isSelectExpensive() const { return SelectIsExpensive; }
+
+ /// 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; }
+
+ /// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of
+ /// srl/add/sra.
+ bool isPow2DivCheap() const { return Pow2DivIsCheap; }
+
+ /// isJumpExpensive() - Return true if Flow Control is an expensive operation
+ /// that should be avoided.
+ bool isJumpExpensive() const { return JumpIsExpensive; }
+
+ /// getSetCCResultType - Return the ValueType of the result of SETCC
+ /// operations. Also used to obtain the target's preferred type for
+ /// the condition operand of SELECT and BRCOND nodes. In the case of
+ /// BRCOND the argument passed is MVT::Other since there are no other
+ /// operands to get a type hint from.
+ virtual EVT getSetCCResultType(EVT VT) const;
+
+ /// getCmpLibcallReturnType - Return the ValueType for comparison
+ /// libcalls. Comparions libcalls include floating point comparion calls,
+ /// and Ordered/Unordered check calls on floating point numbers.
+ virtual
+ MVT::SimpleValueType getCmpLibcallReturnType() const;
+
+ /// getBooleanContents - For targets without i1 registers, this gives the
+ /// nature of the high-bits of boolean values held in types wider than i1.
+ /// "Boolean values" are special true/false values produced by nodes like
+ /// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND.
+ /// Not to be confused with general values promoted from i1.
+ /// Some cpus distinguish between vectors of boolean and scalars; the isVec
+ /// parameter selects between the two kinds. For example on X86 a scalar
+ /// boolean should be zero extended from i1, while the elements of a vector
+ /// of booleans should be sign extended from i1.
+ BooleanContent getBooleanContents(bool isVec) const {
+ return isVec ? BooleanVectorContents : BooleanContents;
+ }
+
+ /// getSchedulingPreference - Return target scheduling preference.
+ Sched::Preference getSchedulingPreference() const {
+ return SchedPreferenceInfo;
+ }
+
+ /// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to
+ /// different scheduling heuristics for different nodes. This function returns
+ /// the preference (or none) for the given node.
+ virtual Sched::Preference getSchedulingPreference(SDNode *) const {
+ return Sched::None;
+ }
+
+ /// 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];
+ assert(RC && "This value type is not natively supported!");
+ return RC;
+ }
+
+ /// getRepRegClassFor - Return the 'representative' register class for the
+ /// specified value type. The 'representative' register class is the largest
+ /// 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];
+ 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];
+ }
+
+ /// isTypeLegal - Return true if the target has native support for the
+ /// specified value type. This means that it has a register that directly
+ /// holds it without promotions or expansions.
+ bool isTypeLegal(EVT VT) const {
+ assert(!VT.isSimple() ||
+ (unsigned)VT.getSimpleVT().SimpleTy < array_lengthof(RegClassForVT));
+ return VT.isSimple() && RegClassForVT[VT.getSimpleVT().SimpleTy] != 0;
+ }
+
+ class ValueTypeActionImpl {
+ /// ValueTypeActions - For each value type, keep a LegalizeTypeAction enum
+ /// that indicates how instruction selection should deal with the type.
+ uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
+
+ public:
+ ValueTypeActionImpl() {
+ std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
+ }
+
+ LegalizeTypeAction getTypeAction(MVT VT) const {
+ return (LegalizeTypeAction)ValueTypeActions[VT.SimpleTy];
+ }
+
+ void setTypeAction(EVT VT, LegalizeTypeAction Action) {
+ unsigned I = VT.getSimpleVT().SimpleTy;
+ ValueTypeActions[I] = Action;
+ }
+ };
+
+ const ValueTypeActionImpl &getValueTypeActions() const {
+ return ValueTypeActions;
+ }
+
+ /// getTypeAction - Return how we should legalize values of this type, either
+ /// it is already legal (return 'Legal') or we need to promote it to a larger
+ /// type (return 'Promote'), or we need to expand it into multiple registers
+ /// of smaller integer type (return 'Expand'). 'Custom' is not an option.
+ LegalizeTypeAction getTypeAction(LLVMContext &Context, EVT VT) const {
+ return getTypeConversion(Context, VT).first;
+ }
+ LegalizeTypeAction getTypeAction(MVT VT) const {
+ return ValueTypeActions.getTypeAction(VT);
+ }
+
+ /// getTypeToTransformTo - For types supported by the target, this is an
+ /// identity function. For types that must be promoted to larger types, this
+ /// returns the larger type to promote to. For integer types that are larger
+ /// than the largest integer register, this contains one step in the expansion
+ /// to get to the smaller register. For illegal floating point types, this
+ /// returns the integer type to transform to.
+ EVT getTypeToTransformTo(LLVMContext &Context, EVT VT) const {
+ return getTypeConversion(Context, VT).second;
+ }
+
+ /// getTypeToExpandTo - For types supported by the target, this is an
+ /// identity function. For types that must be expanded (i.e. integer types
+ /// that are larger than the largest integer register or illegal floating
+ /// point types), this returns the largest legal type it will be expanded to.
+ EVT getTypeToExpandTo(LLVMContext &Context, EVT VT) const {
+ assert(!VT.isVector());
+ while (true) {
+ switch (getTypeAction(Context, VT)) {
+ case TypeLegal:
+ return VT;
+ case TypeExpandInteger:
+ VT = getTypeToTransformTo(Context, VT);
+ break;
+ default:
+ llvm_unreachable("Type is not legal nor is it to be expanded!");
+ }
+ }
+ }
+
+ /// getVectorTypeBreakdown - Vector types are broken down into some number of
+ /// legal first class types. For example, EVT::v8f32 maps to 2 EVT::v4f32
+ /// with Altivec or SSE1, or 8 promoted EVT::f64 values with the X86 FP stack.
+ /// Similarly, EVT::v2i64 turns into 4 EVT::i32 values with both PPC and X86.
+ ///
+ /// This method returns the number of registers needed, and the VT for each
+ /// register. It also returns the VT and quantity of the intermediate values
+ /// before they are promoted/expanded.
+ ///
+ unsigned getVectorTypeBreakdown(LLVMContext &Context, EVT VT,
+ EVT &IntermediateVT,
+ unsigned &NumIntermediates,
+ EVT &RegisterVT) const;
+
+ /// getTgtMemIntrinsic: Given an intrinsic, checks if on the target the
+ /// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
+ /// this is the case, it returns true and store the intrinsic
+ /// information into the IntrinsicInfo that was passed to the function.
+ struct IntrinsicInfo {
+ unsigned opc; // target opcode
+ EVT memVT; // memory VT
+ const Value* ptrVal; // value representing memory location
+ int offset; // offset off of ptrVal
+ unsigned align; // alignment
+ bool vol; // is volatile?
+ bool readMem; // reads memory?
+ bool writeMem; // writes memory?
+ };
+
+ virtual bool getTgtMemIntrinsic(IntrinsicInfo &, const CallInst &,
+ unsigned /*Intrinsic*/) const {
+ return false;
+ }
+
+ /// isFPImmLegal - Returns true if the target can instruction select the
+ /// specified FP immediate natively. If false, the legalizer will materialize
+ /// the FP immediate as a load from a constant pool.
+ virtual bool isFPImmLegal(const APFloat &/*Imm*/, EVT /*VT*/) const {
+ return false;
+ }
+
+ /// isShuffleMaskLegal - Targets can use this to indicate that they only
+ /// support *some* VECTOR_SHUFFLE operations, those with specific masks.
+ /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
+ /// are assumed to be legal.
+ virtual bool isShuffleMaskLegal(const SmallVectorImpl<int> &/*Mask*/,
+ EVT /*VT*/) const {
+ return true;
+ }
+
+ /// canOpTrap - Returns true if the operation can trap for the value type.
+ /// VT must be a legal type. By default, we optimistically assume most
+ /// operations don't trap except for divide and remainder.
+ virtual bool canOpTrap(unsigned Op, EVT VT) const;
+
+ /// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is
+ /// used by Targets can use this to indicate if there is a suitable
+ /// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
+ /// pool entry.
+ virtual bool isVectorClearMaskLegal(const SmallVectorImpl<int> &/*Mask*/,
+ EVT /*VT*/) const {
+ return false;
+ }
+
+ /// getOperationAction - Return how this operation 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 getOperationAction(unsigned Op, EVT VT) const {
+ if (VT.isExtended()) return Expand;
+ assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+ unsigned I = (unsigned) VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)OpActions[I][Op];
+ }
+
+ /// isOperationLegalOrCustom - Return true if the specified operation is
+ /// legal on this target or can be made legal with custom lowering. This
+ /// is used to help guide high-level lowering decisions.
+ bool isOperationLegalOrCustom(unsigned Op, EVT VT) const {
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ (getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom);
+ }
+
+ /// isOperationLegal - Return true if the specified operation is legal on this
+ /// target.
+ bool isOperationLegal(unsigned Op, EVT VT) const {
+ return (VT == MVT::Other || isTypeLegal(VT)) &&
+ getOperationAction(Op, VT) == Legal;
+ }
+
+ /// getLoadExtAction - Return how this load with extension 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 getLoadExtAction(unsigned ExtType, EVT VT) const {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE &&
+ VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ "Table isn't big enough!");
+ return (LegalizeAction)LoadExtActions[VT.getSimpleVT().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;
+ }
+
+ /// 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 &&
+ "Table isn't big enough!");
+ return (LegalizeAction)TruncStoreActions[ValVT.getSimpleVT().SimpleTy]
+ [MemVT.getSimpleVT().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;
+ }
+
+ /// getIndexedLoadAction - Return how the indexed load 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
+ getIndexedLoadAction(unsigned IdxMode, EVT VT) const {
+ assert(IdxMode < ISD::LAST_INDEXED_MODE &&
+ VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ "Table isn't big enough!");
+ unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)((IndexedModeActions[Ty][IdxMode] & 0xf0) >> 4);
+ }
+
+ /// isIndexedLoadLegal - Return true if the specified indexed load is legal
+ /// on this target.
+ bool isIndexedLoadLegal(unsigned IdxMode, EVT VT) const {
+ return VT.isSimple() &&
+ (getIndexedLoadAction(IdxMode, VT) == Legal ||
+ getIndexedLoadAction(IdxMode, VT) == Custom);
+ }
+
+ /// getIndexedStoreAction - Return how the indexed store 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
+ getIndexedStoreAction(unsigned IdxMode, EVT VT) const {
+ assert(IdxMode < ISD::LAST_INDEXED_MODE &&
+ VT.getSimpleVT() < MVT::LAST_VALUETYPE &&
+ "Table isn't big enough!");
+ unsigned Ty = (unsigned)VT.getSimpleVT().SimpleTy;
+ return (LegalizeAction)(IndexedModeActions[Ty][IdxMode] & 0x0f);
+ }
+
+ /// isIndexedStoreLegal - Return true if the specified indexed load is legal
+ /// on this target.
+ bool isIndexedStoreLegal(unsigned IdxMode, EVT VT) const {
+ return VT.isSimple() &&
+ (getIndexedStoreAction(IdxMode, VT) == Legal ||
+ getIndexedStoreAction(IdxMode, VT) == 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 {
+ assert((unsigned)CC < array_lengthof(CondCodeActions) &&
+ (unsigned)VT.getSimpleVT().SimpleTy < sizeof(CondCodeActions[0])*4 &&
+ "Table isn't big enough!");
+ LegalizeAction Action = (LegalizeAction)
+ ((CondCodeActions[CC] >> (2*VT.getSimpleVT().SimpleTy)) & 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;
+ }
+
+
+ /// 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 {
+ 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));
+ if (PTTI != PromoteToType.end()) return PTTI->second;
+
+ assert((VT.isInteger() || VT.isFloatingPoint()) &&
+ "Cannot autopromote this type, add it with AddPromotedToType.");
+
+ EVT NVT = VT;
+ do {
+ NVT = (MVT::SimpleValueType)(NVT.getSimpleVT().SimpleTy+1);
+ assert(NVT.isInteger() == VT.isInteger() && NVT != MVT::isVoid &&
+ "Didn't find type to promote to!");
+ } while (!isTypeLegal(NVT) ||
+ getOperationAction(Op, NVT) == Promote);
+ return NVT;
+ }
+
+ /// getValueType - Return the EVT corresponding to this LLVM type.
+ /// This is fixed by the LLVM operations except for the pointer size. If
+ /// AllowUnknown is true, this will return MVT::Other for types with no EVT
+ /// counterpart (e.g. structs), otherwise it will assert.
+ EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
+ // Lower scalar pointers to native pointer types.
+ if (Ty->isPointerTy()) return PointerTy;
+
+ if (Ty->isVectorTy()) {
+ VectorType *VTy = cast<VectorType>(Ty);
+ Type *Elm = VTy->getElementType();
+ // Lower vectors of pointers to native pointer types.
+ if (Elm->isPointerTy())
+ Elm = EVT(PointerTy).getTypeForEVT(Ty->getContext());
+ return EVT::getVectorVT(Ty->getContext(), EVT::getEVT(Elm, false),
+ VTy->getNumElements());
+ }
+ return EVT::getEVT(Ty, AllowUnknown);
+ }
+
+ /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
+ /// function arguments in the caller parameter area. This is the actual
+ /// alignment, not its logarithm.
+ virtual unsigned getByValTypeAlignment(Type *Ty) const;
+
+ /// getRegisterType - Return the type of registers that this ValueType will
+ /// eventually require.
+ EVT 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 {
+ if (VT.isSimple()) {
+ assert((unsigned)VT.getSimpleVT().SimpleTy <
+ array_lengthof(RegisterTypeForVT));
+ return RegisterTypeForVT[VT.getSimpleVT().SimpleTy];
+ }
+ if (VT.isVector()) {
+ EVT VT1, RegisterVT;
+ unsigned NumIntermediates;
+ (void)getVectorTypeBreakdown(Context, VT, VT1,
+ NumIntermediates, RegisterVT);
+ return RegisterVT;
+ }
+ if (VT.isInteger()) {
+ return getRegisterType(Context, getTypeToTransformTo(Context, VT));
+ }
+ llvm_unreachable("Unsupported extended type!");
+ }
+
+ /// getNumRegisters - Return the number of registers that this ValueType will
+ /// eventually require. This is one for any types promoted to live in larger
+ /// registers, but may be more than one for types (like i64) that are split
+ /// into pieces. For types like i140, which are first promoted then expanded,
+ /// it is the number of registers needed to hold all the bits of the original
+ /// type. For an i140 on a 32 bit machine this means 5 registers.
+ unsigned getNumRegisters(LLVMContext &Context, EVT VT) const {
+ if (VT.isSimple()) {
+ assert((unsigned)VT.getSimpleVT().SimpleTy <
+ array_lengthof(NumRegistersForVT));
+ return NumRegistersForVT[VT.getSimpleVT().SimpleTy];
+ }
+ if (VT.isVector()) {
+ EVT VT1, VT2;
+ unsigned NumIntermediates;
+ return getVectorTypeBreakdown(Context, VT, VT1, NumIntermediates, VT2);
+ }
+ if (VT.isInteger()) {
+ unsigned BitWidth = VT.getSizeInBits();
+ unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits();
+ return (BitWidth + RegWidth - 1) / RegWidth;
+ }
+ llvm_unreachable("Unsupported extended type!");
+ }
+
+ /// ShouldShrinkFPConstant - If true, then instruction selection should
+ /// seek to shrink the FP constant of the specified type to a smaller type
+ /// in order to save space and / or reduce runtime.
+ virtual bool ShouldShrinkFPConstant(EVT) const { return true; }
+
+ /// hasTargetDAGCombine - If true, the target has custom DAG combine
+ /// transformations that it can perform for the specified node.
+ bool hasTargetDAGCombine(ISD::NodeType NT) const {
+ assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
+ return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7));
+ }
+
+ /// This function returns the maximum number of store operations permitted
+ /// to replace a call to llvm.memset. The value is set by the target at the
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
+ /// @brief Get maximum # of store operations permitted for llvm.memset
+ unsigned getMaxStoresPerMemset(bool OptSize) const {
+ return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset;
+ }
+
+ /// This function returns the maximum number of store operations permitted
+ /// to replace a call to llvm.memcpy. The value is set by the target at the
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
+ /// @brief Get maximum # of store operations permitted for llvm.memcpy
+ unsigned getMaxStoresPerMemcpy(bool OptSize) const {
+ return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy;
+ }
+
+ /// This function returns the maximum number of store operations permitted
+ /// to replace a call to llvm.memmove. The value is set by the target at the
+ /// performance threshold for such a replacement. If OptSize is true,
+ /// return the limit for functions that have OptSize attribute.
+ /// @brief Get maximum # of store operations permitted for llvm.memmove
+ unsigned getMaxStoresPerMemmove(bool OptSize) const {
+ return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove;
+ }
+
+ /// 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.
+ /// @brief Determine if the target supports unaligned memory accesses.
+ virtual bool allowsUnalignedMemoryAccesses(EVT) const {
+ return false;
+ }
+
+ /// This function returns true if the target would benefit from code placement
+ /// optimization.
+ /// @brief Determine if the target should perform code placement optimization.
+ bool shouldOptimizeCodePlacement() const {
+ return benefitFromCodePlacementOpt;
+ }
+
+ /// getOptimalMemOpType - Returns the target specific optimal type for load
+ /// and store operations as a result of memset, memcpy, and memmove
+ /// 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.
+ /// 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 /*MemcpyStrSrc*/,
+ MachineFunction &/*MF*/) const {
+ return MVT::Other;
+ }
+
+ /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
+ /// to implement llvm.setjmp.
+ bool usesUnderscoreSetJmp() const {
+ return UseUnderscoreSetJmp;
+ }
+
+ /// usesUnderscoreLongJmp - Determine if we should use _longjmp or longjmp
+ /// to implement llvm.longjmp.
+ bool usesUnderscoreLongJmp() const {
+ return UseUnderscoreLongJmp;
+ }
+
+ /// getStackPointerRegisterToSaveRestore - If a physical register, this
+ /// specifies the register that llvm.savestack/llvm.restorestack should save
+ /// and restore.
+ unsigned getStackPointerRegisterToSaveRestore() const {
+ return StackPointerRegisterToSaveRestore;
+ }
+
+ /// getExceptionPointerRegister - If a physical register, this returns
+ /// the register that receives the exception address on entry to a landing
+ /// pad.
+ unsigned getExceptionPointerRegister() const {
+ return ExceptionPointerRegister;
+ }
+
+ /// getExceptionSelectorRegister - If a physical register, this returns
+ /// the register that receives the exception typeid on entry to a landing
+ /// pad.
+ unsigned getExceptionSelectorRegister() const {
+ return ExceptionSelectorRegister;
+ }
+
+ /// getJumpBufSize - returns the target's jmp_buf size in bytes (if never
+ /// set, the default is 200)
+ unsigned getJumpBufSize() const {
+ return JumpBufSize;
+ }
+
+ /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
+ /// (if never set, the default is 0)
+ unsigned getJumpBufAlignment() const {
+ return JumpBufAlignment;
+ }
+
+ /// getMinStackArgumentAlignment - return the minimum stack alignment of an
+ /// argument.
+ unsigned getMinStackArgumentAlignment() const {
+ return MinStackArgumentAlignment;
+ }
+
+ /// getMinFunctionAlignment - return the minimum function alignment.
+ ///
+ unsigned getMinFunctionAlignment() const {
+ return MinFunctionAlignment;
+ }
+
+ /// getPrefFunctionAlignment - return the preferred function alignment.
+ ///
+ unsigned getPrefFunctionAlignment() const {
+ return PrefFunctionAlignment;
+ }
+
+ /// getPrefLoopAlignment - return the preferred loop alignment.
+ ///
+ unsigned getPrefLoopAlignment() const {
+ return PrefLoopAlignment;
+ }
+
+ /// getShouldFoldAtomicFences - return whether the combiner should fold
+ /// fence MEMBARRIER instructions into the atomic intrinsic instructions.
+ ///
+ bool getShouldFoldAtomicFences() const {
+ return ShouldFoldAtomicFences;
+ }
+
+ /// getInsertFencesFor - return whether the DAG builder should automatically
+ /// insert fences and reduce ordering for atomics.
+ ///
+ bool getInsertFencesForAtomic() const {
+ return InsertFencesForAtomic;
+ }
+
+ /// getPreIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if the node's address
+ /// can be legally represented as pre-indexed load / store address.
+ virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
+ SDValue &/*Offset*/,
+ ISD::MemIndexedMode &/*AM*/,
+ SelectionDAG &/*DAG*/) const {
+ return false;
+ }
+
+ /// getPostIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if this node can be
+ /// combined with a load / store to form a post-indexed load / store.
+ virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
+ SDValue &/*Base*/, SDValue &/*Offset*/,
+ ISD::MemIndexedMode &/*AM*/,
+ SelectionDAG &/*DAG*/) const {
+ return false;
+ }
+
+ /// getJumpTableEncoding - Return the entry encoding for a jump table in the
+ /// current function. The returned value is a member of the
+ /// MachineJumpTableInfo::JTEntryKind enum.
+ virtual unsigned getJumpTableEncoding() const;
+
+ virtual const MCExpr *
+ LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
+ const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
+ MCContext &/*Ctx*/) const {
+ llvm_unreachable("Need to implement this hook if target has custom JTIs");
+ }
+
+ /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
+ /// jumptable.
+ virtual SDValue getPICJumpTableRelocBase(SDValue Table,
+ SelectionDAG &DAG) const;
+
+ /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+ /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+ /// MCExpr.
+ virtual const MCExpr *
+ getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI, MCContext &Ctx) const;
+
+ /// isOffsetFoldingLegal - Return true if folding a constant offset
+ /// with the given GlobalAddress is legal. It is frequently not legal in
+ /// PIC relocation models.
+ virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
+ /// getStackCookieLocation - Return true if the target stores stack
+ /// protector cookies at a fixed offset in some non-standard address
+ /// space, and populates the address space and offset as
+ /// appropriate.
+ virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/,
+ unsigned &/*Offset*/) const {
+ return false;
+ }
+
+ /// getMaximalGlobalOffset - Returns the maximal possible offset which can be
+ /// used for loads / stores from the global.
+ virtual unsigned getMaximalGlobalOffset() const {
+ return 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Optimization Methods
+ //
+
+ /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
+ /// SDValues for returning information from TargetLowering to its clients
+ /// that want to combine
+ struct TargetLoweringOpt {
+ SelectionDAG &DAG;
+ bool LegalTys;
+ bool LegalOps;
+ SDValue Old;
+ SDValue New;
+
+ explicit TargetLoweringOpt(SelectionDAG &InDAG,
+ bool LT, bool LO) :
+ DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
+
+ bool LegalTypes() const { return LegalTys; }
+ bool LegalOperations() const { return LegalOps; }
+
+ bool CombineTo(SDValue O, SDValue N) {
+ Old = O;
+ New = N;
+ return true;
+ }
+
+ /// ShrinkDemandedConstant - Check to see if the specified operand of the
+ /// specified instruction is a constant integer. If so, check to see if
+ /// there are any bits set in the constant that are not demanded. If so,
+ /// shrink the constant and return true.
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
+
+ /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
+ /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
+ /// cast, but it could be generalized for targets with other types of
+ /// implicit widening casts.
+ bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+ DebugLoc dl);
+ };
+
+ /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
+ /// DemandedMask bits of the result of Op are ever used downstream. If we can
+ /// use this information to simplify Op, create a new simplified DAG node and
+ /// return true, returning the original and new nodes in Old and New.
+ /// Otherwise, analyze the expression and return a mask of KnownOne and
+ /// KnownZero bits for the expression (used to simplify the caller).
+ /// The KnownZero/One bits may only be accurate for those bits in the
+ /// DemandedMask.
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
+ APInt &KnownZero, APInt &KnownOne,
+ TargetLoweringOpt &TLO, unsigned Depth = 0) const;
+
+ /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
+ /// Mask are known to be either zero or one and return them in the
+ /// KnownZero/KnownOne bitsets.
+ virtual void computeMaskedBitsForTargetNode(const SDValue Op,
+ APInt &KnownZero,
+ APInt &KnownOne,
+ const SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
+ /// ComputeNumSignBitsForTargetNode - This method can be implemented by
+ /// targets that want to expose additional information about sign bits to the
+ /// DAG Combiner.
+ virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
+ unsigned Depth = 0) const;
+
+ struct DAGCombinerInfo {
+ void *DC; // The DAG Combiner object.
+ bool BeforeLegalize;
+ bool BeforeLegalizeOps;
+ 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) {}
+
+ bool isBeforeLegalize() const { return BeforeLegalize; }
+ bool isBeforeLegalizeOps() const { return BeforeLegalizeOps; }
+ bool isCalledByLegalizer() const { return CalledByLegalizer; }
+
+ void AddToWorklist(SDNode *N);
+ void RemoveFromWorklist(SDNode *N);
+ SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
+ bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
+
+ void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
+ };
+
+ /// SimplifySetCC - Try to simplify a setcc built with the specified operands
+ /// and cc. If it is unable to simplify it, return a null SDValue.
+ SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
+ ISD::CondCode Cond, bool foldBooleans,
+ DAGCombinerInfo &DCI, DebugLoc dl) const;
+
+ /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
+ /// node is a GlobalAddress + offset.
+ virtual bool
+ isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
+
+ /// PerformDAGCombine - This method will be invoked for all target nodes and
+ /// for any target-independent nodes that the target has registered with
+ /// invoke it for.
+ ///
+ /// The semantics are as follows:
+ /// Return Value:
+ /// SDValue.Val == 0 - No change was made
+ /// SDValue.Val == N - N was replaced, is dead, and is already handled.
+ /// otherwise - N should be replaced by the returned Operand.
+ ///
+ /// In addition, methods provided by DAGCombinerInfo may be used to perform
+ /// more complex transformations.
+ ///
+ virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+
+ /// isTypeDesirableForOp - Return true if the target has native support for
+ /// the specified value type and it is 'desirable' to use the type for the
+ /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
+ /// instruction encodings are longer and some i16 instructions are slow.
+ virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
+ // By default, assume all legal types are desirable.
+ return isTypeLegal(VT);
+ }
+
+ /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner
+ /// to transform a floating point op of specified opcode to a equivalent op of
+ /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM.
+ virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/,
+ EVT /*VT*/) const {
+ return false;
+ }
+
+ /// IsDesirableToPromoteOp - This method query the target whether it is
+ /// beneficial for dag combiner to promote the specified node. If true, it
+ /// should return the desired promotion type by reference.
+ virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
+ return false;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Configuration Methods - These methods should be invoked by
+ // the derived class constructor to configure this object for the target.
+ //
+
+protected:
+ /// setBooleanContents - Specify how the target extends the result of a
+ /// boolean value from i1 to a wider type. See getBooleanContents.
+ void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; }
+ /// setBooleanVectorContents - Specify how the target extends the result
+ /// of a vector boolean value from a vector of i1 to a wider type. See
+ /// getBooleanContents.
+ void setBooleanVectorContents(BooleanContent Ty) {
+ BooleanVectorContents = Ty;
+ }
+
+ /// setSchedulingPreference - Specify the target scheduling preference.
+ void setSchedulingPreference(Sched::Preference Pref) {
+ SchedPreferenceInfo = Pref;
+ }
+
+ /// setUseUnderscoreSetJmp - Indicate whether this target prefers to
+ /// use _setjmp to implement llvm.setjmp or the non _ version.
+ /// Defaults to false.
+ void setUseUnderscoreSetJmp(bool Val) {
+ UseUnderscoreSetJmp = Val;
+ }
+
+ /// setUseUnderscoreLongJmp - Indicate whether this target prefers to
+ /// use _longjmp to implement llvm.longjmp or the non _ version.
+ /// Defaults to false.
+ void setUseUnderscoreLongJmp(bool Val) {
+ UseUnderscoreLongJmp = Val;
+ }
+
+ /// setStackPointerRegisterToSaveRestore - If set to a physical register, this
+ /// specifies the register that llvm.savestack/llvm.restorestack should save
+ /// and restore.
+ void setStackPointerRegisterToSaveRestore(unsigned R) {
+ StackPointerRegisterToSaveRestore = R;
+ }
+
+ /// setExceptionPointerRegister - If set to a physical register, this sets
+ /// the register that receives the exception address on entry to a landing
+ /// pad.
+ void setExceptionPointerRegister(unsigned R) {
+ ExceptionPointerRegister = R;
+ }
+
+ /// setExceptionSelectorRegister - If set to a physical register, this sets
+ /// the register that receives the exception typeid on entry to a landing
+ /// pad.
+ void setExceptionSelectorRegister(unsigned R) {
+ ExceptionSelectorRegister = R;
+ }
+
+ /// SelectIsExpensive - Tells the code generator not to expand operations
+ /// into sequences that use the select operations if possible.
+ void setSelectIsExpensive(bool isExpensive = true) {
+ SelectIsExpensive = isExpensive;
+ }
+
+ /// JumpIsExpensive - Tells the code generator not to expand sequence of
+ /// operations into a separate sequences that increases the amount of
+ /// flow control.
+ void setJumpIsExpensive(bool isExpensive = true) {
+ JumpIsExpensive = isExpensive;
+ }
+
+ /// setIntDivIsCheap - Tells the code generator that integer divide is
+ /// expensive, and if possible, should be replaced by an alternate sequence
+ /// of instructions not containing an integer divide.
+ void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
+
+ /// setPow2DivIsCheap - 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
+ /// it.
+ void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }
+
+ /// 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));
+ AvailableRegClasses.push_back(std::make_pair(VT, RC));
+ RegClassForVT[VT.getSimpleVT().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;
+
+ /// computeRegisterProperties - Once all of the register classes are added,
+ /// this allows us to compute derived properties we expose.
+ void computeRegisterProperties();
+
+ /// setOperationAction - Indicate that the specified operation does not work
+ /// with the specified type and indicate what to do about it.
+ void setOperationAction(unsigned Op, MVT VT,
+ LegalizeAction Action) {
+ assert(Op < array_lengthof(OpActions[0]) && "Table isn't big enough!");
+ OpActions[(unsigned)VT.SimpleTy][Op] = (uint8_t)Action;
+ }
+
+ /// setLoadExtAction - Indicate that the specified load with extension does
+ /// not work with the specified type and indicate what to do about it.
+ void setLoadExtAction(unsigned ExtType, MVT VT,
+ LegalizeAction Action) {
+ assert(ExtType < ISD::LAST_LOADEXT_TYPE && VT < MVT::LAST_VALUETYPE &&
+ "Table isn't big enough!");
+ LoadExtActions[VT.SimpleTy][ExtType] = (uint8_t)Action;
+ }
+
+ /// setTruncStoreAction - Indicate that the specified truncating store does
+ /// not work with the specified type and indicate what to do about it.
+ void setTruncStoreAction(MVT ValVT, MVT MemVT,
+ LegalizeAction Action) {
+ assert(ValVT < MVT::LAST_VALUETYPE && MemVT < MVT::LAST_VALUETYPE &&
+ "Table isn't big enough!");
+ TruncStoreActions[ValVT.SimpleTy][MemVT.SimpleTy] = (uint8_t)Action;
+ }
+
+ /// setIndexedLoadAction - Indicate that the specified indexed load does or
+ /// does not work with the specified type and indicate what to do abort
+ /// it. NOTE: All indexed mode loads are initialized to Expand in
+ /// TargetLowering.cpp
+ void setIndexedLoadAction(unsigned IdxMode, MVT VT,
+ LegalizeAction Action) {
+ assert(VT < MVT::LAST_VALUETYPE && IdxMode < ISD::LAST_INDEXED_MODE &&
+ (unsigned)Action < 0xf && "Table isn't big enough!");
+ // Load action are kept in the upper half.
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0xf0;
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action) <<4;
+ }
+
+ /// setIndexedStoreAction - Indicate that the specified indexed store does or
+ /// does not work with the specified type and indicate what to do about
+ /// it. NOTE: All indexed mode stores are initialized to Expand in
+ /// TargetLowering.cpp
+ void setIndexedStoreAction(unsigned IdxMode, MVT VT,
+ LegalizeAction Action) {
+ assert(VT < MVT::LAST_VALUETYPE && IdxMode < ISD::LAST_INDEXED_MODE &&
+ (unsigned)Action < 0xf && "Table isn't big enough!");
+ // Store action are kept in the lower half.
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] &= ~0x0f;
+ IndexedModeActions[(unsigned)VT.SimpleTy][IdxMode] |= ((uint8_t)Action);
+ }
+
+ /// setCondCodeAction - Indicate that the specified condition code is or isn't
+ /// supported on the target and indicate what to do about it.
+ void setCondCodeAction(ISD::CondCode CC, MVT VT,
+ LegalizeAction Action) {
+ 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;
+ }
+
+ /// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
+ /// promotion code defaults to trying a larger integer/fp until it can find
+ /// one that works. If that default is insufficient, this method can be used
+ /// by the target to override the default.
+ void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT) {
+ PromoteToType[std::make_pair(Opc, OrigVT.SimpleTy)] = DestVT.SimpleTy;
+ }
+
+ /// setTargetDAGCombine - Targets should invoke this method for each target
+ /// independent node that they want to provide a custom DAG combiner for by
+ /// implementing the PerformDAGCombine virtual method.
+ void setTargetDAGCombine(ISD::NodeType NT) {
+ assert(unsigned(NT >> 3) < array_lengthof(TargetDAGCombineArray));
+ TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7);
+ }
+
+ /// setJumpBufSize - Set the target's required jmp_buf buffer size (in
+ /// bytes); default is 200
+ void setJumpBufSize(unsigned Size) {
+ JumpBufSize = Size;
+ }
+
+ /// setJumpBufAlignment - Set the target's required jmp_buf buffer
+ /// alignment (in bytes); default is 0
+ void setJumpBufAlignment(unsigned Align) {
+ JumpBufAlignment = Align;
+ }
+
+ /// setMinFunctionAlignment - Set the target's minimum function alignment (in
+ /// log2(bytes))
+ void setMinFunctionAlignment(unsigned Align) {
+ MinFunctionAlignment = Align;
+ }
+
+ /// setPrefFunctionAlignment - Set the target's preferred function alignment.
+ /// This should be set if there is a performance benefit to
+ /// higher-than-minimum alignment (in log2(bytes))
+ void setPrefFunctionAlignment(unsigned Align) {
+ PrefFunctionAlignment = Align;
+ }
+
+ /// setPrefLoopAlignment - Set the target's preferred loop alignment. Default
+ /// alignment is zero, it means the target does not care about loop alignment.
+ /// The alignment is specified in log2(bytes).
+ void setPrefLoopAlignment(unsigned Align) {
+ PrefLoopAlignment = Align;
+ }
+
+ /// setMinStackArgumentAlignment - Set the minimum stack alignment of an
+ /// argument (in log2(bytes)).
+ void setMinStackArgumentAlignment(unsigned Align) {
+ MinStackArgumentAlignment = Align;
+ }
+
+ /// setShouldFoldAtomicFences - Set if the target's implementation of the
+ /// atomic operation intrinsics includes locking. Default is false.
+ void setShouldFoldAtomicFences(bool fold) {
+ ShouldFoldAtomicFences = fold;
+ }
+
+ /// setInsertFencesForAtomic - Set if the the DAG builder should
+ /// automatically insert fences and reduce the order of atomic memory
+ /// operations to Monotonic.
+ void setInsertFencesForAtomic(bool fence) {
+ InsertFencesForAtomic = fence;
+ }
+
+public:
+ //===--------------------------------------------------------------------===//
+ // Lowering methods - These methods must be implemented by targets so that
+ // the SelectionDAGLowering code knows how to lower these.
+ //
+
+ /// LowerFormalArguments - This hook must be implemented to lower the
+ /// incoming (formal) arguments, described by the Ins array, into the
+ /// specified DAG. The implementation should fill in the InVals array
+ /// with legal-type argument values, and return the resulting token
+ /// chain value.
+ ///
+ virtual SDValue
+ LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
+ SmallVectorImpl<SDValue> &/*InVals*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// LowerCallTo - This function lowers an abstract call to a function into an
+ /// actual call. This returns a pair of operands. The first element is the
+ /// return value for the function (if RetTy is not VoidTy). The second
+ /// element is the outgoing token chain. It calls LowerCall to do the actual
+ /// lowering.
+ struct ArgListEntry {
+ SDValue Node;
+ Type* Ty;
+ bool isSExt : 1;
+ bool isZExt : 1;
+ bool isInReg : 1;
+ bool isSRet : 1;
+ bool isNest : 1;
+ bool isByVal : 1;
+ uint16_t Alignment;
+
+ ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
+ isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
+ };
+ typedef std::vector<ArgListEntry> ArgListTy;
+ std::pair<SDValue, SDValue>
+ LowerCallTo(SDValue Chain, Type *RetTy, bool RetSExt, bool RetZExt,
+ bool isVarArg, bool isInreg, unsigned NumFixedArgs,
+ CallingConv::ID CallConv, bool isTailCall,
+ bool doesNotRet, bool isReturnValueUsed,
+ SDValue Callee, ArgListTy &Args,
+ SelectionDAG &DAG, DebugLoc dl) const;
+
+ /// LowerCall - This hook must be implemented to lower calls into the
+ /// the specified DAG. The outgoing arguments to the call are described
+ /// by the Outs array, and the values to be returned by the call are
+ /// described by the Ins array. The implementation should fill in the
+ /// InVals array with legal-type return values from the call, and return
+ /// the resulting token chain value.
+ virtual SDValue
+ LowerCall(SDValue /*Chain*/, SDValue /*Callee*/,
+ CallingConv::ID /*CallConv*/, bool /*isVarArg*/,
+ bool /*doesNotRet*/, bool &/*isTailCall*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ const SmallVectorImpl<SDValue> &/*OutVals*/,
+ const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
+ SmallVectorImpl<SDValue> &/*InVals*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
+ virtual void HandleByVal(CCState *, unsigned &) const {}
+
+ /// CanLowerReturn - This hook should be implemented to check whether the
+ /// return values described by the Outs array can fit into the return
+ /// registers. If false is returned, an sret-demotion is performed.
+ ///
+ virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
+ MachineFunction &/*MF*/, bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ LLVMContext &/*Context*/) const
+ {
+ // Return true by default to get preexisting behavior.
+ return true;
+ }
+
+ /// LowerReturn - This hook must be implemented to lower outgoing
+ /// return values, described by the Outs array, into the specified
+ /// DAG. The implementation should return the resulting token chain
+ /// value.
+ ///
+ virtual SDValue
+ LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ const SmallVectorImpl<SDValue> &/*OutVals*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// isUsedByReturnOnly - Return true if result of the specified node is used
+ /// by a return node only. It also compute and return the input chain for the
+ /// tail call.
+ /// This is used to determine whether it is possible
+ /// to codegen a libcall as tail call at legalization time.
+ virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const {
+ return false;
+ }
+
+ /// mayBeEmittedAsTailCall - Return true if the target may be able emit the
+ /// call instruction as a tail call. This is used by optimization passes to
+ /// determine if it's profitable to duplicate return instructions to enable
+ /// tailcall optimization.
+ virtual bool mayBeEmittedAsTailCall(CallInst *) const {
+ return false;
+ }
+
+ /// getTypeForExtArgOrReturn - Return the type that should be used to zero or
+ /// sign extend a zeroext/signext integer argument or return value.
+ /// FIXME: Most C calling convention requires the return type to be promoted,
+ /// 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,
+ ISD::NodeType /*ExtendKind*/) const {
+ EVT MinVT = getRegisterType(Context, MVT::i32);
+ return VT.bitsLT(MinVT) ? MinVT : VT;
+ }
+
+ /// LowerOperationWrapper - This callback is invoked by the type legalizer
+ /// to legalize nodes with an illegal operand type but legal result types.
+ /// It replaces the LowerOperation callback in the type Legalizer.
+ /// The reason we can not do away with LowerOperation entirely is that
+ /// LegalizeDAG isn't yet ready to use this callback.
+ /// TODO: Consider merging with ReplaceNodeResults.
+
+ /// The target places new result values for the node in Results (their number
+ /// and types must exactly match those of the original return values of
+ /// the node), or leaves Results empty, which indicates that the node is not
+ /// to be custom lowered after all.
+ /// The default implementation calls LowerOperation.
+ virtual void LowerOperationWrapper(SDNode *N,
+ SmallVectorImpl<SDValue> &Results,
+ SelectionDAG &DAG) const;
+
+ /// LowerOperation - This callback is invoked for operations that are
+ /// unsupported by the target, which are registered to use 'custom' lowering,
+ /// and whose defined values are all legal.
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation of this aborts.
+ virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
+
+ /// ReplaceNodeResults - This callback is invoked when a node result type is
+ /// illegal for the target, and the operation was registered to use 'custom'
+ /// lowering for that result type. The target places new result values for
+ /// the node in Results (their number and types must exactly match those of
+ /// the original return values of the node), or leaves Results empty, which
+ /// indicates that the node is not to be custom lowered after all.
+ ///
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation aborts.
+ virtual void ReplaceNodeResults(SDNode * /*N*/,
+ SmallVectorImpl<SDValue> &/*Results*/,
+ SelectionDAG &/*DAG*/) const {
+ llvm_unreachable("ReplaceNodeResults not implemented for this target!");
+ }
+
+ /// getTargetNodeName() - This method returns the name of a target specific
+ /// DAG node.
+ virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+ /// createFastISel - This method returns a target specific FastISel object,
+ /// or null if the target does not support "fast" ISel.
+ virtual FastISel *createFastISel(FunctionLoweringInfo &) const {
+ return 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inline Asm Support hooks
+ //
+
+ /// ExpandInlineAsm - This hook allows the target to expand an inline asm
+ /// call to be explicit llvm code if it wants to. This is useful for
+ /// turning simple inline asms into LLVM intrinsics, which gives the
+ /// compiler more information about the behavior of the code.
+ virtual bool ExpandInlineAsm(CallInst *) const {
+ return false;
+ }
+
+ enum ConstraintType {
+ C_Register, // Constraint represents specific register(s).
+ C_RegisterClass, // Constraint represents any of register(s) in class.
+ C_Memory, // Memory constraint.
+ C_Other, // Something else.
+ C_Unknown // Unsupported constraint.
+ };
+
+ enum ConstraintWeight {
+ // Generic weights.
+ CW_Invalid = -1, // No match.
+ CW_Okay = 0, // Acceptable.
+ CW_Good = 1, // Good weight.
+ CW_Better = 2, // Better weight.
+ CW_Best = 3, // Best weight.
+
+ // Well-known weights.
+ CW_SpecificReg = CW_Okay, // Specific register operands.
+ CW_Register = CW_Good, // Register operands.
+ CW_Memory = CW_Better, // Memory operands.
+ CW_Constant = CW_Best, // Constant operand.
+ CW_Default = CW_Okay // Default or don't know type.
+ };
+
+ /// AsmOperandInfo - This contains information for each constraint that we are
+ /// lowering.
+ struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
+ /// ConstraintCode - This contains the actual string for the code, like "m".
+ /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
+ /// most closely matches the operand.
+ std::string ConstraintCode;
+
+ /// ConstraintType - Information about the constraint code, e.g. Register,
+ /// RegisterClass, Memory, Other, Unknown.
+ TargetLowering::ConstraintType ConstraintType;
+
+ /// CallOperandval - If this is the result output operand or a
+ /// clobber, this is null, otherwise it is the incoming operand to the
+ /// CallInst. This gets modified as the asm is processed.
+ Value *CallOperandVal;
+
+ /// ConstraintVT - The ValueType for the operand value.
+ EVT ConstraintVT;
+
+ /// isMatchingInputConstraint - Return true of this is an input operand that
+ /// is a matching constraint like "4".
+ bool isMatchingInputConstraint() const;
+
+ /// getMatchedOperand - If this is an input matching constraint, this method
+ /// returns the output operand it matches.
+ unsigned getMatchedOperand() const;
+
+ /// Copy constructor for copying from an AsmOperandInfo.
+ AsmOperandInfo(const AsmOperandInfo &info)
+ : InlineAsm::ConstraintInfo(info),
+ ConstraintCode(info.ConstraintCode),
+ ConstraintType(info.ConstraintType),
+ CallOperandVal(info.CallOperandVal),
+ ConstraintVT(info.ConstraintVT) {
+ }
+
+ /// Copy constructor for copying from a ConstraintInfo.
+ AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
+ : InlineAsm::ConstraintInfo(info),
+ ConstraintType(TargetLowering::C_Unknown),
+ CallOperandVal(0), ConstraintVT(MVT::Other) {
+ }
+ };
+
+ typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
+
+ /// ParseConstraints - Split up the constraint string from the inline
+ /// assembly value into the specific constraints and their prefixes,
+ /// and also tie in the associated operand values.
+ /// If this returns an empty vector, and if the constraint string itself
+ /// isn't empty, there was an error parsing.
+ virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
+
+ /// Examine constraint type and operand type and determine a weight value.
+ /// The operand object must already have been set up with the operand type.
+ virtual ConstraintWeight getMultipleConstraintMatchWeight(
+ AsmOperandInfo &info, int maIndex) const;
+
+ /// Examine constraint string and operand type and determine a weight value.
+ /// The operand object must already have been set up with the operand type.
+ virtual ConstraintWeight getSingleConstraintMatchWeight(
+ AsmOperandInfo &info, const char *constraint) const;
+
+ /// ComputeConstraintToUse - Determines the constraint code and constraint
+ /// type to use for the specific AsmOperandInfo, setting
+ /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
+ /// being passed in is available, it can be passed in as Op, otherwise an
+ /// empty SDValue can be passed.
+ virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
+ SDValue Op,
+ SelectionDAG *DAG = 0) const;
+
+ /// getConstraintType - Given a constraint, return the type of constraint it
+ /// is for this target.
+ virtual ConstraintType getConstraintType(const std::string &Constraint) const;
+
+ /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
+ /// {edx}), return the register number and the register class for the
+ /// register.
+ ///
+ /// Given a register class constraint, like 'r', if this corresponds directly
+ /// to an LLVM register class, return a register of 0 and the register class
+ /// pointer.
+ ///
+ /// This should only be used for C_Register constraints. On error,
+ /// this returns a register number of 0 and a null register class pointer..
+ virtual std::pair<unsigned, const TargetRegisterClass*>
+ getRegForInlineAsmConstraint(const std::string &Constraint,
+ EVT VT) const;
+
+ /// LowerXConstraint - try to replace an X constraint, which matches anything,
+ /// with another that has more specific requirements based on the type of the
+ /// corresponding operand. This returns null if there is no replacement to
+ /// make.
+ virtual const char *LowerXConstraint(EVT ConstraintVT) const;
+
+ /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
+ /// vector. If it is invalid, don't add anything to Ops.
+ virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
+ std::vector<SDValue> &Ops,
+ SelectionDAG &DAG) const;
+
+ //===--------------------------------------------------------------------===//
+ // Instruction Emitting Hooks
+ //
+
+ // EmitInstrWithCustomInserter - This method should be implemented by targets
+ // that mark instructions with the 'usesCustomInserter' flag. These
+ // instructions are special in various ways, which require special support to
+ // insert. The specified MachineInstr is created but not inserted into any
+ // basic blocks, and this method is called to expand it into a sequence of
+ // instructions, potentially also creating new basic blocks and control flow.
+ virtual MachineBasicBlock *
+ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
+
+ /// AdjustInstrPostInstrSelection - This method should be implemented by
+ /// targets that mark instructions with the 'hasPostISelHook' flag. These
+ /// instructions must be adjusted after instruction selection by target hooks.
+ /// e.g. To fill in optional defs for ARM 's' setting instructions.
+ virtual void
+ AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
+
+ //===--------------------------------------------------------------------===//
+ // Addressing mode description hooks (used by LSR etc).
+ //
+
+ /// AddrMode - This represents an addressing mode of:
+ /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
+ /// If BaseGV is null, there is no BaseGV.
+ /// If BaseOffs is zero, there is no base offset.
+ /// If HasBaseReg is false, there is no base register.
+ /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
+ /// no scale.
+ ///
+ struct AddrMode {
+ GlobalValue *BaseGV;
+ int64_t BaseOffs;
+ bool HasBaseReg;
+ int64_t Scale;
+ AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
+ };
+
+ /// GetAddrModeArguments - CodeGenPrepare sinks address calculations into the
+ /// same BB as Load/Store instructions reading the address. This allows as
+ /// much computation as possible to be done in the address mode for that
+ /// 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
+ /// mode is legal for a load/store of any legal type.
+ /// TODO: Handle pre/postinc as well.
+ virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) 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) const {
+ return true;
+ }
+
+ /// 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) const {
+ return true;
+ }
+
+ /// 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 {
+ return false;
+ }
+
+ virtual bool isTruncateFree(EVT /*VT1*/, EVT /*VT2*/) const {
+ return false;
+ }
+
+ /// isZExtFree - Return true if any actual instruction that defines a
+ /// value of type Ty1 implicitly zero-extends the value to Ty2 in the result
+ /// register. This does not necessarily include registers defined in
+ /// unknown ways, such as incoming arguments, or copies from unknown
+ /// virtual registers. Also, if isTruncateFree(Ty2, Ty1) is true, this
+ /// does not necessarily apply to truncate instructions. e.g. on x86-64,
+ /// all instructions that define 32-bit values implicit zero-extend the
+ /// result out to 64 bits.
+ virtual bool isZExtFree(Type * /*Ty1*/, Type * /*Ty2*/) const {
+ return false;
+ }
+
+ virtual bool isZExtFree(EVT /*VT1*/, EVT /*VT2*/) const {
+ return false;
+ }
+
+ /// 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 {
+ return false;
+ }
+
+ /// isFAbsFree - 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 isFAbsFree(EVT) const {
+ return false;
+ }
+
+ /// isNarrowingProfitable - Return true if it's profitable to narrow
+ /// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow
+ /// from i32 to i8 but not from i32 to i16.
+ virtual bool isNarrowingProfitable(EVT /*VT1*/, EVT /*VT2*/) const {
+ return false;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Div utility functions
+ //
+ SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
+ SelectionDAG &DAG) const;
+ SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
+ std::vector<SDNode*>* Created) const;
+ SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
+ std::vector<SDNode*>* Created) const;
+
+
+ //===--------------------------------------------------------------------===//
+ // Runtime Library hooks
+ //
+
+ /// setLibcallName - Rename the default libcall routine name for the specified
+ /// libcall.
+ void setLibcallName(RTLIB::Libcall Call, const char *Name) {
+ LibcallRoutineNames[Call] = Name;
+ }
+
+ /// getLibcallName - Get the libcall routine name for the specified libcall.
+ ///
+ const char *getLibcallName(RTLIB::Libcall Call) const {
+ return LibcallRoutineNames[Call];
+ }
+
+ /// setCmpLibcallCC - Override the default CondCode to be used to test the
+ /// result of the comparison libcall against zero.
+ void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC) {
+ CmpLibcallCCs[Call] = CC;
+ }
+
+ /// getCmpLibcallCC - Get the CondCode that's to be used to test the result of
+ /// the comparison libcall against zero.
+ ISD::CondCode getCmpLibcallCC(RTLIB::Libcall Call) const {
+ return CmpLibcallCCs[Call];
+ }
+
+ /// setLibcallCallingConv - Set the CallingConv that should be used for the
+ /// specified libcall.
+ void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) {
+ LibcallCallingConvs[Call] = CC;
+ }
+
+ /// getLibcallCallingConv - Get the CallingConv that should be used for the
+ /// specified libcall.
+ CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const {
+ return LibcallCallingConvs[Call];
+ }
+
+private:
+ const TargetMachine &TM;
+ const TargetData *TD;
+ const TargetLoweringObjectFile &TLOF;
+
+ /// We are in the process of implementing a new TypeLegalization action
+ /// which is the promotion of vector elements. This feature is under
+ /// development. Until this feature is complete, it is only enabled using a
+ /// flag. We pass this flag using a member because of circular dep issues.
+ /// This member will be removed with the flag once we complete the transition.
+ bool mayPromoteElements;
+
+ /// PointerTy - The type to use for pointers, usually i32 or i64.
+ ///
+ MVT PointerTy;
+
+ /// IsLittleEndian - True if this is a little endian target.
+ ///
+ bool IsLittleEndian;
+
+ /// SelectIsExpensive - Tells the code generator not to expand operations
+ /// into sequences that use the select operations if possible.
+ bool SelectIsExpensive;
+
+ /// IntDivIsCheap - Tells the code generator not to expand integer divides by
+ /// constants into a sequence of muls, adds, and shifts. This is a hack until
+ /// a real cost model is in place. If we ever optimize for size, this will be
+ /// set to true unconditionally.
+ bool IntDivIsCheap;
+
+ /// 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
+ /// it.
+ bool Pow2DivIsCheap;
+
+ /// JumpIsExpensive - Tells the code generator that it shouldn't generate
+ /// extra flow control instructions and should attempt to combine flow
+ /// control instructions via predication.
+ bool JumpIsExpensive;
+
+ /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
+ /// llvm.setjmp. Defaults to false.
+ bool UseUnderscoreSetJmp;
+
+ /// UseUnderscoreLongJmp - This target prefers to use _longjmp to implement
+ /// llvm.longjmp. Defaults to false.
+ bool UseUnderscoreLongJmp;
+
+ /// BooleanContents - Information about the contents of the high-bits in
+ /// boolean values held in a type wider than i1. See getBooleanContents.
+ BooleanContent BooleanContents;
+ /// BooleanVectorContents - Information about the contents of the high-bits
+ /// in boolean vector values when the element type is wider than i1. See
+ /// getBooleanContents.
+ BooleanContent BooleanVectorContents;
+
+ /// SchedPreferenceInfo - The target scheduling preference: shortest possible
+ /// total cycles or lowest register usage.
+ Sched::Preference SchedPreferenceInfo;
+
+ /// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
+ unsigned JumpBufSize;
+
+ /// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf
+ /// buffers
+ unsigned JumpBufAlignment;
+
+ /// MinStackArgumentAlignment - The minimum alignment that any argument
+ /// on the stack needs to have.
+ ///
+ unsigned MinStackArgumentAlignment;
+
+ /// MinFunctionAlignment - The minimum function alignment (used when
+ /// optimizing for size, and to prevent explicitly provided alignment
+ /// from leading to incorrect code).
+ ///
+ unsigned MinFunctionAlignment;
+
+ /// PrefFunctionAlignment - The preferred function alignment (used when
+ /// alignment unspecified and optimizing for speed).
+ ///
+ unsigned PrefFunctionAlignment;
+
+ /// PrefLoopAlignment - The preferred loop alignment.
+ ///
+ unsigned PrefLoopAlignment;
+
+ /// ShouldFoldAtomicFences - Whether fencing MEMBARRIER instructions should
+ /// be folded into the enclosed atomic intrinsic instruction by the
+ /// combiner.
+ bool ShouldFoldAtomicFences;
+
+ /// InsertFencesForAtomic - Whether the DAG builder should automatically
+ /// insert fences and reduce ordering for atomics. (This will be set for
+ /// for most architectures with weak memory ordering.)
+ bool InsertFencesForAtomic;
+
+ /// StackPointerRegisterToSaveRestore - If set to a physical register, this
+ /// specifies the register that llvm.savestack/llvm.restorestack should save
+ /// and restore.
+ unsigned StackPointerRegisterToSaveRestore;
+
+ /// ExceptionPointerRegister - If set to a physical register, this specifies
+ /// the register that receives the exception address on entry to a landing
+ /// pad.
+ unsigned ExceptionPointerRegister;
+
+ /// ExceptionSelectorRegister - If set to a physical register, this specifies
+ /// the register that receives the exception typeid on entry to a landing
+ /// pad.
+ unsigned ExceptionSelectorRegister;
+
+ /// RegClassForVT - This indicates the default register class to use for
+ /// each ValueType the target supports natively.
+ const TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
+ unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
+ EVT RegisterTypeForVT[MVT::LAST_VALUETYPE];
+
+ /// RepRegClassForVT - This indicates the "representative" register class to
+ /// use for each ValueType the target supports natively. This information is
+ /// used by the scheduler to track register pressure. By default, the
+ /// representative register class is the largest legal super-reg register
+ /// class of the register class of the specified type. e.g. On x86, i8, i16,
+ /// and i32's representative class would be GR32.
+ const TargetRegisterClass *RepRegClassForVT[MVT::LAST_VALUETYPE];
+
+ /// RepRegClassCostForVT - This indicates the "cost" of the "representative"
+ /// register class for each ValueType. The cost is used by the scheduler to
+ /// approximate register pressure.
+ uint8_t RepRegClassCostForVT[MVT::LAST_VALUETYPE];
+
+ /// TransformToType - For any value types we are promoting or expanding, this
+ /// contains the value type that we are changing to. For Expanded types, this
+ /// 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];
+
+ /// OpActions - For each operation and each value type, keep a LegalizeAction
+ /// that indicates how instruction selection should deal with the operation.
+ /// Most operations are Legal (aka, supported natively by the target), but
+ /// operations that are not should be described. Note that operations on
+ /// non-legal value types are not described here.
+ uint8_t OpActions[MVT::LAST_VALUETYPE][ISD::BUILTIN_OP_END];
+
+ /// LoadExtActions - For each load extension type and each value type,
+ /// keep a LegalizeAction that indicates how instruction selection should deal
+ /// with a load of a specific value type and extension type.
+ uint8_t LoadExtActions[MVT::LAST_VALUETYPE][ISD::LAST_LOADEXT_TYPE];
+
+ /// TruncStoreActions - For each value type pair keep a LegalizeAction that
+ /// indicates whether a truncating store of a specific value type and
+ /// truncating type is legal.
+ uint8_t TruncStoreActions[MVT::LAST_VALUETYPE][MVT::LAST_VALUETYPE];
+
+ /// IndexedModeActions - For each indexed mode and each value type,
+ /// keep a pair of LegalizeAction that indicates how instruction
+ /// selection should deal with the load / store. The first dimension is the
+ /// value_type for the reference. The second dimension represents the various
+ /// modes for load store.
+ uint8_t IndexedModeActions[MVT::LAST_VALUETYPE][ISD::LAST_INDEXED_MODE];
+
+ /// 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];
+
+ ValueTypeActionImpl ValueTypeActions;
+
+ typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind;
+
+ 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());
+
+ assert(
+ (!(NVT.isSimple() && LA != TypeLegal) ||
+ ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger)
+ && "Promote may not follow Expand or Promote");
+
+ return LegalizeKind(LA, NVT);
+ }
+
+ // Handle Extended Scalar Types.
+ if (!VT.isVector()) {
+ assert(VT.isInteger() && "Float types must be simple");
+ unsigned BitSize = VT.getSizeInBits();
+ // First promote to a power-of-two size, then expand if necessary.
+ if (BitSize < 8 || !isPowerOf2_32(BitSize)) {
+ EVT NVT = VT.getRoundIntegerType(Context);
+ assert(NVT != VT && "Unable to round integer VT");
+ LegalizeKind NextStep = getTypeConversion(Context, NVT);
+ // Avoid multi-step promotion.
+ if (NextStep.first == TypePromoteInteger) return NextStep;
+ // Return rounded integer type.
+ return LegalizeKind(TypePromoteInteger, NVT);
+ }
+
+ return LegalizeKind(TypeExpandInteger,
+ EVT::getIntegerVT(Context, VT.getSizeInBits()/2));
+ }
+
+ // Handle vector types.
+ unsigned NumElts = VT.getVectorNumElements();
+ EVT EltVT = VT.getVectorElementType();
+
+ // Vectors with only one element are always scalarized.
+ if (NumElts == 1)
+ return LegalizeKind(TypeScalarizeVector, EltVT);
+
+ // If we allow the promotion of vector elements using a flag,
+ // then try to widen vector elements until a legal type is found.
+ if (mayPromoteElements && EltVT.isInteger()) {
+ // Vectors with a number of elements that is not a power of two are always
+ // widened, for example <3 x float> -> <4 x float>.
+ if (!VT.isPow2VectorType()) {
+ NumElts = (unsigned)NextPowerOf2(NumElts);
+ EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts);
+ return LegalizeKind(TypeWidenVector, NVT);
+ }
+
+ // Examine the element type.
+ LegalizeKind LK = getTypeConversion(Context, EltVT);
+
+ // If type is to be expanded, split the vector.
+ // <4 x i140> -> <2 x i140>
+ if (LK.first == TypeExpandInteger)
+ return LegalizeKind(TypeSplitVector,
+ EVT::getVectorVT(Context, EltVT, NumElts / 2));
+
+ // Promote the integer element types until a legal vector type is found
+ // or until the element integer type is too big. If a legal type was not
+ // found, fallback to the usual mechanism of widening/splitting the
+ // vector.
+ while (1) {
+ // Increase the bitwidth of the element to the next pow-of-two
+ // (which is greater than 8 bits).
+ EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits()
+ ).getRoundIntegerType(Context);
+
+ // Stop trying when getting a non-simple element type.
+ // Note that vector elements may be greater than legal vector element
+ // types. Example: X86 XMM registers hold 64bit element on 32bit systems.
+ if (!EltVT.isSimple()) break;
+
+ // Build a new vector type and check if it is legal.
+ MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts);
+ // Found a legal promoted vector type.
+ if (NVT != MVT() && ValueTypeActions.getTypeAction(NVT) == TypeLegal)
+ return LegalizeKind(TypePromoteInteger,
+ EVT::getVectorVT(Context, EltVT, NumElts));
+ }
+ }
+
+ // Try to widen the vector until a legal type is found.
+ // If there is no wider legal type, split the vector.
+ while (1) {
+ // Round up to the next power of 2.
+ NumElts = (unsigned)NextPowerOf2(NumElts);
+
+ // If there is no simple vector type with this many elements then there
+ // cannot be a larger legal vector type. Note that this assumes that
+ // there are no skipped intermediate vector types in the simple types.
+ if (!EltVT.isSimple()) break;
+ MVT LargerVector = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts);
+ if (LargerVector == MVT()) break;
+
+ // If this type is legal then widen the vector.
+ if (ValueTypeActions.getTypeAction(LargerVector) == TypeLegal)
+ return LegalizeKind(TypeWidenVector, LargerVector);
+ }
+
+ // Widen odd vectors to next power of two.
+ if (!VT.isPow2VectorType()) {
+ EVT NVT = VT.getPow2VectorType(Context);
+ return LegalizeKind(TypeWidenVector, NVT);
+ }
+
+ // Vectors with illegal element types are expanded.
+ EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2);
+ return LegalizeKind(TypeSplitVector, NVT);
+ }
+
+ std::vector<std::pair<EVT, const TargetRegisterClass*> > AvailableRegClasses;
+
+ /// TargetDAGCombineArray - Targets can specify ISD nodes that they would
+ /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
+ /// which sets a bit in this array.
+ unsigned char
+ TargetDAGCombineArray[(ISD::BUILTIN_OP_END+CHAR_BIT-1)/CHAR_BIT];
+
+ /// PromoteToType - For operations that must be promoted to a specific type,
+ /// this holds the destination type. This map should be sparse, so don't hold
+ /// it as an array.
+ ///
+ /// Targets add entries to this map with AddPromotedToType(..), clients access
+ /// this with getTypeToPromoteTo(..).
+ std::map<std::pair<unsigned, MVT::SimpleValueType>, MVT::SimpleValueType>
+ PromoteToType;
+
+ /// LibcallRoutineNames - Stores the name each libcall.
+ ///
+ const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL];
+
+ /// CmpLibcallCCs - The ISD::CondCode that should be used to test the result
+ /// of each of the comparison libcall against zero.
+ ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
+
+ /// LibcallCallingConvs - Stores the CallingConv that should be used for each
+ /// libcall.
+ CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
+
+protected:
+ /// When lowering \@llvm.memset this field specifies the maximum number of
+ /// store operations that may be substituted for the call to memset. Targets
+ /// must set this value based on the cost threshold for that target. Targets
+ /// should assume that the memset will be done using as many of the largest
+ /// store operations first, followed by smaller ones, if necessary, per
+ /// alignment restrictions. For example, storing 9 bytes on a 32-bit machine
+ /// with 16-bit alignment would result in four 2-byte stores and one 1-byte
+ /// store. This only applies to setting a constant array of a constant size.
+ /// @brief Specify maximum number of store instructions per memset call.
+ unsigned maxStoresPerMemset;
+
+ /// Maximum number of stores operations that may be substituted for the call
+ /// to memset, used for functions with OptSize attribute.
+ unsigned maxStoresPerMemsetOptSize;
+
+ /// When lowering \@llvm.memcpy this field specifies the maximum number of
+ /// store operations that may be substituted for a call to memcpy. Targets
+ /// must set this value based on the cost threshold for that target. Targets
+ /// should assume that the memcpy will be done using as many of the largest
+ /// store operations first, followed by smaller ones, if necessary, per
+ /// alignment restrictions. For example, storing 7 bytes on a 32-bit machine
+ /// with 32-bit alignment would result in one 4-byte store, a one 2-byte store
+ /// and one 1-byte store. This only applies to copying a constant array of
+ /// constant size.
+ /// @brief Specify maximum bytes of store instructions per memcpy call.
+ unsigned maxStoresPerMemcpy;
+
+ /// Maximum number of store operations that may be substituted for a call
+ /// to memcpy, used for functions with OptSize attribute.
+ unsigned maxStoresPerMemcpyOptSize;
+
+ /// When lowering \@llvm.memmove this field specifies the maximum number of
+ /// store instructions that may be substituted for a call to memmove. Targets
+ /// must set this value based on the cost threshold for that target. Targets
+ /// should assume that the memmove will be done using as many of the largest
+ /// store operations first, followed by smaller ones, if necessary, per
+ /// alignment restrictions. For example, moving 9 bytes on a 32-bit machine
+ /// with 8-bit alignment would result in nine 1-byte stores. This only
+ /// applies to copying a constant array of constant size.
+ /// @brief Specify maximum bytes of store instructions per memmove call.
+ unsigned maxStoresPerMemmove;
+
+ /// Maximum number of store instructions that may be substituted for a call
+ /// to memmove, used for functions with OpSize attribute.
+ unsigned maxStoresPerMemmoveOptSize;
+
+ /// This field specifies whether the target can benefit from code placement
+ /// optimization.
+ bool benefitFromCodePlacementOpt;
+
+private:
+ /// isLegalRC - Return true if the value types that can be represented by the
+ /// specified register class are all legal.
+ bool isLegalRC(const TargetRegisterClass *RC) const;
+
+ /// hasLegalSuperRegRegClasses - Return true if the specified register class
+ /// has one or more super-reg register classes that are legal.
+ bool hasLegalSuperRegRegClasses(const TargetRegisterClass *RC) const;
+};
+
+/// 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,
+ SmallVectorImpl<ISD::OutputArg> &Outs,
+ const TargetLowering &TLI,
+ SmallVectorImpl<uint64_t> *Offsets = 0);
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h
new file mode 100644
index 000000000000..d631f58aab74
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -0,0 +1,147 @@
+//===-- llvm/Target/TargetLoweringObjectFile.h - Object Info ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements classes used to handle lowerings specific to common
+// object file formats.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
+#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
+
+#include "llvm/Module.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace llvm {
+ class MachineModuleInfo;
+ class Mangler;
+ class MCContext;
+ class MCExpr;
+ class MCSection;
+ class MCSymbol;
+ 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
+
+public:
+ MCContext &getContext() const { return *Ctx; }
+
+ TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(0) {}
+
+ virtual ~TargetLoweringObjectFile();
+
+ /// Initialize - this method must be called before any actual lowering is
+ /// done. This specifies the current context for codegen, and gives the
+ /// lowering implementations a chance to set up their default sections.
+ virtual void Initialize(MCContext &ctx, const TargetMachine &TM);
+
+ virtual void emitPersonalityValue(MCStreamer &Streamer,
+ const TargetMachine &TM,
+ const MCSymbol *Sym) const;
+
+ /// emitModuleFlags - Emit the module flags that the platform cares about.
+ virtual void emitModuleFlags(MCStreamer &,
+ ArrayRef<Module::ModuleFlagEntry>,
+ Mangler *, const TargetMachine &) const {
+ }
+
+ /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
+ /// decide not to emit the UsedDirective for some symbols in llvm.used.
+ /// FIXME: REMOVE this (rdar://7071300)
+ virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
+ Mangler *) const {
+ return GV != 0;
+ }
+
+ /// getSectionForConstant - Given a constant with the SectionKind, return a
+ /// section that it should be placed in.
+ virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+
+ /// getKindForGlobal - Classify the specified global variable into a set of
+ /// target independent categories embodied in SectionKind.
+ static SectionKind getKindForGlobal(const GlobalValue *GV,
+ const TargetMachine &TM);
+
+ /// SectionForGlobal - This method computes the appropriate section to emit
+ /// the specified global variable or function definition. This should not
+ /// be passed external (or available externally) globals.
+ const MCSection *SectionForGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler *Mang,
+ const TargetMachine &TM) const;
+
+ /// SectionForGlobal - This method computes the appropriate section to emit
+ /// the specified global variable or function definition. This should not
+ /// be passed external (or available externally) globals.
+ const MCSection *SectionForGlobal(const GlobalValue *GV,
+ Mangler *Mang,
+ const TargetMachine &TM) const {
+ return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
+ }
+
+ /// getExplicitSectionGlobal - Targets should implement this method to assign
+ /// a section to globals with an explicit section specfied. The
+ /// implementation of this method can assume that GV->hasSection() is true.
+ virtual const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const = 0;
+
+ /// getSpecialCasedSectionGlobals - Allow the target to completely override
+ /// section assignment of a global.
+ virtual const MCSection *
+ getSpecialCasedSectionGlobals(const GlobalValue *GV, Mangler *Mang,
+ SectionKind Kind) const {
+ return 0;
+ }
+
+ /// getExprForDwarfGlobalReference - 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;
+
+ // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
+ virtual MCSymbol *
+ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI) const;
+
+ ///
+ const MCExpr *
+ getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
+ MCStreamer &Streamer) const;
+
+ virtual const MCSection *
+ getStaticCtorSection(unsigned Priority = 65535) const {
+ (void)Priority;
+ return StaticCtorSection;
+ }
+ virtual const MCSection *
+ getStaticDtorSection(unsigned Priority = 65535) const {
+ (void)Priority;
+ return StaticDtorSection;
+ }
+
+protected:
+ virtual const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler *Mang, const TargetMachine &TM) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetMachine.h b/contrib/llvm/include/llvm/Target/TargetMachine.h
new file mode 100644
index 000000000000..1a0560478a41
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetMachine.h
@@ -0,0 +1,333 @@
+//===-- llvm/Target/TargetMachine.h - Target Information --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetMachine and LLVMTargetMachine classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETMACHINE_H
+#define LLVM_TARGET_TARGETMACHINE_H
+
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+
+class InstrItineraryData;
+class JITCodeEmitter;
+class GlobalValue;
+class MCAsmInfo;
+class MCCodeGenInfo;
+class MCContext;
+class PassManagerBase;
+class Target;
+class TargetData;
+class TargetELFWriterInfo;
+class TargetFrameLowering;
+class TargetInstrInfo;
+class TargetIntrinsicInfo;
+class TargetJITInfo;
+class TargetLowering;
+class TargetPassConfig;
+class TargetRegisterInfo;
+class TargetSelectionDAGInfo;
+class TargetSubtargetInfo;
+class formatted_raw_ostream;
+class raw_ostream;
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetMachine - Primary interface to the complete machine description for
+/// the target machine. All target-specific information should be accessible
+/// through this interface.
+///
+class TargetMachine {
+ TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
+ void operator=(const TargetMachine &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ TargetMachine(const Target &T, StringRef TargetTriple,
+ StringRef CPU, StringRef FS, const TargetOptions &Options);
+
+ /// getSubtargetImpl - virtual method implemented by subclasses that returns
+ /// a reference to that target's TargetSubtargetInfo-derived member variable.
+ virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; }
+
+ /// TheTarget - The Target that this machine was created for.
+ const Target &TheTarget;
+
+ /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target
+ /// feature strings the TargetMachine instance is created with.
+ std::string TargetTriple;
+ std::string TargetCPU;
+ std::string TargetFS;
+
+ /// CodeGenInfo - Low level target information such as relocation model.
+ const MCCodeGenInfo *CodeGenInfo;
+
+ /// AsmInfo - Contains target specific asm information.
+ ///
+ const MCAsmInfo *AsmInfo;
+
+ unsigned MCRelaxAll : 1;
+ unsigned MCNoExecStack : 1;
+ unsigned MCSaveTempLabels : 1;
+ unsigned MCUseLoc : 1;
+ unsigned MCUseCFI : 1;
+ unsigned MCUseDwarfDirectory : 1;
+
+public:
+ virtual ~TargetMachine();
+
+ const Target &getTarget() const { return TheTarget; }
+
+ const StringRef getTargetTriple() const { return TargetTriple; }
+ const StringRef getTargetCPU() const { return TargetCPU; }
+ const StringRef getTargetFeatureString() const { return TargetFS; }
+
+ TargetOptions Options;
+
+ // Interfaces to the major aspects of target machine information:
+ // -- Instruction opcode and operand information
+ // -- Pipelines and scheduling information
+ // -- Stack frame information
+ // -- Selection DAG lowering information
+ //
+ virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
+ 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; }
+
+ /// getMCAsmInfo - Return target specific asm information.
+ ///
+ const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; }
+
+ /// getSubtarget - This method returns a pointer to the specified type of
+ /// TargetSubtargetInfo. In debug builds, it verifies that the object being
+ /// returned is of the correct type.
+ template<typename STC> const STC &getSubtarget() const {
+ return *static_cast<const STC*>(getSubtargetImpl());
+ }
+
+ /// getRegisterInfo - If register information is available, return it. If
+ /// not, return null. This is kept separate from RegInfo until RegInfo has
+ /// details of graph coloring register allocation removed from it.
+ ///
+ virtual const TargetRegisterInfo *getRegisterInfo() const { return 0; }
+
+ /// getIntrinsicInfo - If intrinsic information is available, return it. If
+ /// not, return null.
+ ///
+ virtual const TargetIntrinsicInfo *getIntrinsicInfo() const { return 0; }
+
+ /// getJITInfo - If this target supports a JIT, return information for it,
+ /// otherwise return null.
+ ///
+ virtual TargetJITInfo *getJITInfo() { return 0; }
+
+ /// getInstrItineraryData - Returns instruction itinerary data for the target
+ /// or specific subtarget.
+ ///
+ virtual const InstrItineraryData *getInstrItineraryData() const {
+ 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; }
+
+ /// setMCRelaxAll - Set whether all machine code instructions should be
+ /// relaxed.
+ void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
+
+ /// hasMCSaveTempLabels - Check whether temporary labels will be preserved
+ /// (i.e., not treated as temporary).
+ bool hasMCSaveTempLabels() const { return MCSaveTempLabels; }
+
+ /// setMCSaveTempLabels - Set whether temporary labels will be preserved
+ /// (i.e., not treated as temporary).
+ void setMCSaveTempLabels(bool Value) { MCSaveTempLabels = Value; }
+
+ /// hasMCNoExecStack - Check whether an executable stack is not needed.
+ bool hasMCNoExecStack() const { return MCNoExecStack; }
+
+ /// setMCNoExecStack - Set whether an executabel stack is not needed.
+ void setMCNoExecStack(bool Value) { MCNoExecStack = Value; }
+
+ /// hasMCUseLoc - Check whether we should use dwarf's .loc directive.
+ bool hasMCUseLoc() const { return MCUseLoc; }
+
+ /// setMCUseLoc - Set whether all we should use dwarf's .loc directive.
+ void setMCUseLoc(bool Value) { MCUseLoc = Value; }
+
+ /// hasMCUseCFI - Check whether we should use dwarf's .cfi_* directives.
+ bool hasMCUseCFI() const { return MCUseCFI; }
+
+ /// setMCUseCFI - Set whether all we should use dwarf's .cfi_* directives.
+ void setMCUseCFI(bool Value) { MCUseCFI = Value; }
+
+ /// hasMCUseDwarfDirectory - Check whether we should use .file directives with
+ /// explicit directories.
+ bool hasMCUseDwarfDirectory() const { return MCUseDwarfDirectory; }
+
+ /// setMCUseDwarfDirectory - Set whether all we should use .file directives
+ /// with explicit directories.
+ void setMCUseDwarfDirectory(bool Value) { MCUseDwarfDirectory = Value; }
+
+ /// getRelocationModel - Returns the code generation relocation model. The
+ /// choices are static, PIC, and dynamic-no-pic, and target default.
+ Reloc::Model getRelocationModel() const;
+
+ /// getCodeModel - Returns the code model. The choices are small, kernel,
+ /// medium, large, and target default.
+ CodeModel::Model getCodeModel() const;
+
+ /// getTLSModel - Returns the TLS model which should be used for the given
+ /// global variable.
+ TLSModel::Model getTLSModel(const GlobalValue *GV) const;
+
+ /// getOptLevel - Returns the optimization level: None, Less,
+ /// Default, or Aggressive.
+ CodeGenOpt::Level getOptLevel() const;
+
+ void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
+
+ bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
+
+ /// getAsmVerbosityDefault - Returns the default value of asm verbosity.
+ ///
+ static bool getAsmVerbosityDefault();
+
+ /// setAsmVerbosityDefault - Set the default value of asm verbosity. Default
+ /// is false.
+ static void setAsmVerbosityDefault(bool);
+
+ /// getDataSections - Return true if data objects should be emitted into their
+ /// own section, corresponds to -fdata-sections.
+ static bool getDataSections();
+
+ /// getFunctionSections - Return true if functions should be emitted into
+ /// their own section, corresponding to -ffunction-sections.
+ static bool getFunctionSections();
+
+ /// setDataSections - Set if the data are emit into separate sections.
+ static void setDataSections(bool);
+
+ /// setFunctionSections - Set if the functions are emit into separate
+ /// sections.
+ static void setFunctionSections(bool);
+
+ /// 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.
+ enum CodeGenFileType {
+ CGFT_AssemblyFile,
+ CGFT_ObjectFile,
+ CGFT_Null // Do not emit any output.
+ };
+
+ /// addPassesToEmitFile - Add passes to the specified pass manager to get the
+ /// specified file emitted. Typically this will involve several steps of code
+ /// generation. This method should return true if emission of this file type
+ /// is not supported, or false on success.
+ virtual bool addPassesToEmitFile(PassManagerBase &,
+ formatted_raw_ostream &,
+ CodeGenFileType,
+ bool /*DisableVerify*/ = true) {
+ return true;
+ }
+
+ /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+ /// get machine code emitted. This uses a JITCodeEmitter object to handle
+ /// actually outputting the machine code and resolving things like the address
+ /// of functions. This method returns true if machine code emission is
+ /// not supported.
+ ///
+ virtual bool addPassesToEmitMachineCode(PassManagerBase &,
+ JITCodeEmitter &,
+ bool /*DisableVerify*/ = true) {
+ return true;
+ }
+
+ /// addPassesToEmitMC - Add passes to the specified pass manager to get
+ /// machine code emitted with the MCJIT. This method returns true if machine
+ /// code is not supported. It fills the MCContext Ctx pointer which can be
+ /// used to build custom MCStreamer.
+ ///
+ virtual bool addPassesToEmitMC(PassManagerBase &,
+ MCContext *&,
+ raw_ostream &,
+ bool /*DisableVerify*/ = true) {
+ return true;
+ }
+};
+
+/// LLVMTargetMachine - This class describes a target machine that is
+/// implemented with the LLVM target-independent code generator.
+///
+class LLVMTargetMachine : public TargetMachine {
+protected: // Can only create subclasses.
+ LLVMTargetMachine(const Target &T, StringRef TargetTriple,
+ StringRef CPU, StringRef FS, TargetOptions Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL);
+
+public:
+ /// createPassConfig - Create a pass configuration object to be used by
+ /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
+ virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
+
+ /// addPassesToEmitFile - Add passes to the specified pass manager to get the
+ /// specified file emitted. Typically this will involve several steps of code
+ /// generation.
+ virtual bool addPassesToEmitFile(PassManagerBase &PM,
+ formatted_raw_ostream &Out,
+ CodeGenFileType FileType,
+ bool DisableVerify = true);
+
+ /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+ /// get machine code emitted. This uses a JITCodeEmitter object to handle
+ /// actually outputting the machine code and resolving things like the address
+ /// of functions. This method returns true if machine code emission is
+ /// not supported.
+ ///
+ virtual bool addPassesToEmitMachineCode(PassManagerBase &PM,
+ JITCodeEmitter &MCE,
+ bool DisableVerify = true);
+
+ /// addPassesToEmitMC - Add passes to the specified pass manager to get
+ /// machine code emitted with the MCJIT. This method returns true if machine
+ /// code is not supported. It fills the MCContext Ctx pointer which can be
+ /// used to build custom MCStreamer.
+ ///
+ virtual bool addPassesToEmitMC(PassManagerBase &PM,
+ MCContext *&Ctx,
+ raw_ostream &OS,
+ bool DisableVerify = true);
+
+ /// addCodeEmitter - This pass should be overridden by the target to add a
+ /// code emitter, if supported. If this is not supported, 'true' should be
+ /// returned.
+ virtual bool addCodeEmitter(PassManagerBase &,
+ JITCodeEmitter &) {
+ return true;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetOpcodes.h b/contrib/llvm/include/llvm/Target/TargetOpcodes.h
new file mode 100644
index 000000000000..f0b181e345b7
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetOpcodes.h
@@ -0,0 +1,95 @@
+//===-- llvm/Target/TargetOpcodes.h - Target Indep Opcodes ------*- 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 target independent instruction opcodes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETOPCODES_H
+#define LLVM_TARGET_TARGETOPCODES_H
+
+namespace llvm {
+
+/// Invariant opcodes: All instruction sets have these as their low opcodes.
+///
+/// Every instruction defined here must also appear in Target.td and the order
+/// must be the same as in CodeGenTarget.cpp.
+///
+namespace TargetOpcode {
+ enum {
+ PHI = 0,
+ INLINEASM = 1,
+ PROLOG_LABEL = 2,
+ EH_LABEL = 3,
+ GC_LABEL = 4,
+
+ /// KILL - This instruction is a noop that is used only to adjust the
+ /// liveness of registers. This can be useful when dealing with
+ /// sub-registers.
+ KILL = 5,
+
+ /// EXTRACT_SUBREG - This instruction takes two operands: a register
+ /// that has subregisters, and a subregister index. It returns the
+ /// extracted subregister value. This is commonly used to implement
+ /// truncation operations on target architectures which support it.
+ EXTRACT_SUBREG = 6,
+
+ /// INSERT_SUBREG - This instruction takes three operands: a register that
+ /// has subregisters, a register providing an insert value, and a
+ /// subregister index. It returns the value of the first register with the
+ /// value of the second register inserted. The first register is often
+ /// defined by an IMPLICIT_DEF, because it is commonly used to implement
+ /// anyext operations on target architectures which support it.
+ INSERT_SUBREG = 7,
+
+ /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
+ IMPLICIT_DEF = 8,
+
+ /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that
+ /// the first operand is an immediate integer constant. This constant is
+ /// often zero, because it is commonly used to assert that the instruction
+ /// defining the register implicitly clears the high bits.
+ SUBREG_TO_REG = 9,
+
+ /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
+ /// register-to-register copy into a specific register class. This is only
+ /// used between instruction selection and MachineInstr creation, before
+ /// virtual registers have been created for all the instructions, and it's
+ /// only needed in cases where the register classes implied by the
+ /// instructions are insufficient. It is emitted as a COPY MachineInstr.
+ COPY_TO_REGCLASS = 10,
+
+ /// DBG_VALUE - a mapping of the llvm.dbg.value intrinsic
+ DBG_VALUE = 11,
+
+ /// REG_SEQUENCE - This variadic instruction is used to form a register that
+ /// represent a consecutive sequence of sub-registers. It's used as register
+ /// coalescing / allocation aid and must be eliminated before code emission.
+ // In SDNode form, the first operand encodes the register class created by
+ // the REG_SEQUENCE, while each subsequent pair names a vreg + subreg index
+ // pair. Once it has been lowered to a MachineInstr, the regclass operand
+ // is no longer present.
+ /// e.g. v1027 = REG_SEQUENCE v1024, 3, v1025, 4, v1026, 5
+ /// After register coalescing references of v1024 should be replace with
+ /// v1027:3, v1025 with v1027:4, etc.
+ REG_SEQUENCE = 12,
+
+ /// COPY - Target-independent register copy. This instruction can also be
+ /// used to copy between subregisters of virtual registers.
+ COPY = 13,
+
+ /// BUNDLE - This instruction represents an instruction bundle. Instructions
+ /// which immediately follow a BUNDLE instruction which are marked with
+ /// 'InsideBundle' flag are inside the bundle.
+ BUNDLE
+ };
+} // end namespace TargetOpcode
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetOptions.h b/contrib/llvm/include/llvm/Target/TargetOptions.h
new file mode 100644
index 000000000000..12a275731536
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetOptions.h
@@ -0,0 +1,191 @@
+//===-- llvm/Target/TargetOptions.h - Target Options ------------*- 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 command line option flags that are shared across various
+// targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETOPTIONS_H
+#define LLVM_TARGET_TARGETOPTIONS_H
+
+#include <string>
+
+namespace llvm {
+ class MachineFunction;
+ class StringRef;
+
+ // 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).
+ Soft, // Soft float.
+ Hard // Hard float.
+ };
+ }
+
+ class TargetOptions {
+ public:
+ TargetOptions()
+ : PrintMachineCode(false), NoFramePointerElim(false),
+ NoFramePointerElimNonLeaf(false), LessPreciseFPMADOption(false),
+ NoExcessFPPrecision(false), UnsafeFPMath(false), NoInfsFPMath(false),
+ NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false),
+ UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false),
+ JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
+ GuaranteedTailCallOpt(false), DisableTailCalls(false),
+ StackAlignmentOverride(0), RealignStack(true),
+ DisableJumpTables(false), EnableFastISel(false),
+ PositionIndependentExecutable(false), EnableSegmentedStacks(false),
+ TrapFuncName(""), FloatABIType(FloatABI::Default)
+ {}
+
+ /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
+ /// option is specified on the command line, and should enable debugging
+ /// output from the code generator.
+ unsigned PrintMachineCode : 1;
+
+ /// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is
+ /// specified on the command line. If the target supports the frame pointer
+ /// elimination optimization, this option should disable it.
+ unsigned NoFramePointerElim : 1;
+
+ /// NoFramePointerElimNonLeaf - This flag is enabled when the
+ /// -disable-non-leaf-fp-elim is specified on the command line. If the
+ /// target supports the frame pointer elimination optimization, this option
+ /// should disable it for non-leaf functions.
+ unsigned NoFramePointerElimNonLeaf : 1;
+
+ /// DisableFramePointerElim - This returns true if frame pointer elimination
+ /// optimization should be disabled for the given machine function.
+ bool DisableFramePointerElim(const MachineFunction &MF) const;
+
+ /// LessPreciseFPMAD - This flag is enabled when the
+ /// -enable-fp-mad is specified on the command line. When this flag is off
+ /// (the default), the code generator is not allowed to generate mad
+ /// (multiply add) if the result is "less precise" than doing those
+ /// operations individually.
+ unsigned LessPreciseFPMADOption : 1;
+ bool LessPreciseFPMAD() const;
+
+ /// NoExcessFPPrecision - This flag is enabled when the
+ /// -disable-excess-fp-precision flag is specified on the command line.
+ /// When this flag is off (the default), the code generator is allowed to
+ /// produce results that are "more precise" than IEEE allows. This includes
+ /// use of FMA-like operations and use of the X86 FP registers without
+ /// rounding all over the place.
+ unsigned NoExcessFPPrecision : 1;
+
+ /// UnsafeFPMath - This flag is enabled when the
+ /// -enable-unsafe-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// produce results that are "less precise" than IEEE allows. This includes
+ /// use of X86 instructions like FSIN and FCOS instead of libcalls.
+ /// UnsafeFPMath implies LessPreciseFPMAD.
+ unsigned UnsafeFPMath : 1;
+
+ /// NoInfsFPMath - This flag is enabled when the
+ /// -enable-no-infs-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// assume the FP arithmetic arguments and results are never +-Infs.
+ unsigned NoInfsFPMath : 1;
+
+ /// NoNaNsFPMath - This flag is enabled when the
+ /// -enable-no-nans-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// assume the FP arithmetic arguments and results are never NaNs.
+ unsigned NoNaNsFPMath : 1;
+
+ /// HonorSignDependentRoundingFPMath - This returns true when the
+ /// -enable-sign-dependent-rounding-fp-math is specified. If this returns
+ /// false (the default), the code generator is allowed to assume that the
+ /// rounding behavior is the default (round-to-zero for all floating point
+ /// to integer conversions, and round-to-nearest for all other arithmetic
+ /// truncations). If this is enabled (set to true), the code generator must
+ /// assume that the rounding mode may dynamically change.
+ unsigned HonorSignDependentRoundingFPMathOption : 1;
+ bool HonorSignDependentRoundingFPMath() const;
+
+ /// UseSoftFloat - This flag is enabled when the -soft-float flag is
+ /// specified on the command line. When this flag is on, the code generator
+ /// will generate libcalls to the software floating point library instead of
+ /// target FP instructions.
+ unsigned UseSoftFloat : 1;
+
+ /// NoZerosInBSS - By default some codegens place zero-initialized data to
+ /// .bss section. This flag disables such behaviour (necessary, e.g. for
+ /// crt*.o compiling).
+ unsigned NoZerosInBSS : 1;
+
+ /// JITExceptionHandling - This flag indicates that the JIT should emit
+ /// exception handling information.
+ unsigned JITExceptionHandling : 1;
+
+ /// JITEmitDebugInfo - This flag indicates that the JIT should try to emit
+ /// debug information and notify a debugger about it.
+ unsigned JITEmitDebugInfo : 1;
+
+ /// JITEmitDebugInfoToDisk - This flag indicates that the JIT should write
+ /// the object files generated by the JITEmitDebugInfo flag to disk. This
+ /// flag is hidden and is only for debugging the debug info.
+ unsigned JITEmitDebugInfoToDisk : 1;
+
+ /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is
+ /// specified on the commandline. When the flag is on, participating targets
+ /// will perform tail call optimization on all calls which use the fastcc
+ /// calling convention and which satisfy certain target-independent
+ /// criteria (being at the end of a function, having the same return type
+ /// as their parent function, etc.), using an alternate ABI if necessary.
+ unsigned GuaranteedTailCallOpt : 1;
+
+ /// DisableTailCalls - This flag controls whether we will use tail calls.
+ /// Disabling them may be useful to maintain a correct call stack.
+ unsigned DisableTailCalls : 1;
+
+ /// StackAlignmentOverride - Override default stack alignment for target.
+ unsigned StackAlignmentOverride;
+
+ /// RealignStack - This flag indicates whether the stack should be
+ /// automatically realigned, if needed.
+ unsigned RealignStack : 1;
+
+ /// DisableJumpTables - This flag indicates jump tables should not be
+ /// generated.
+ unsigned DisableJumpTables : 1;
+
+ /// EnableFastISel - This flag enables fast-path instruction selection
+ /// which trades away generated code quality in favor of reducing
+ /// compile time.
+ unsigned EnableFastISel : 1;
+
+ /// PositionIndependentExecutable - This flag indicates whether the code
+ /// will eventually be linked into a single executable, despite the PIC
+ /// relocation model being in use. It's value is undefined (and irrelevant)
+ /// if the relocation model is anything other than PIC.
+ unsigned PositionIndependentExecutable : 1;
+
+ unsigned EnableSegmentedStacks : 1;
+
+ /// getTrapFunctionName - If this returns a non-empty string, this means
+ /// isel should lower Intrinsic::trap to a call to the specified function
+ /// name instead of an ISD::TRAP node.
+ std::string TrapFuncName;
+ StringRef getTrapFunctionName() const;
+
+ /// FloatABIType - This setting is set by -float-abi=xxx option is specfied
+ /// on the command line. This setting may either be Default, Soft, or Hard.
+ /// Default selects the target's default behavior. Soft selects the ABI for
+ /// UseSoftFloat, but does not indicate that FP hardware may not be used.
+ /// Such a combination is unfortunately popular (e.g. arm-apple-darwin).
+ /// Hard presumes that the normal FP ABI is used.
+ FloatABI::ABIType FloatABIType;
+ };
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h
new file mode 100644
index 000000000000..6ddd36451b5c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetRegisterInfo.h
@@ -0,0 +1,747 @@
+//=== Target/TargetRegisterInfo.h - Target Register Information -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file. This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETREGISTERINFO_H
+#define LLVM_TARGET_TARGETREGISTERINFO_H
+
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/CallingConv.h"
+#include <cassert>
+#include <functional>
+
+namespace llvm {
+
+class BitVector;
+class MachineFunction;
+class RegScavenger;
+template<class T> class SmallVectorImpl;
+class raw_ostream;
+
+class TargetRegisterClass {
+public:
+ typedef const uint16_t* iterator;
+ typedef const uint16_t* const_iterator;
+ typedef const MVT::SimpleValueType* vt_iterator;
+ typedef const TargetRegisterClass* const * sc_iterator;
+
+ // Instance variables filled by tablegen, do not use!
+ const MCRegisterClass *MC;
+ const vt_iterator VTs;
+ const unsigned *SubClassMask;
+ const sc_iterator SuperClasses;
+ const sc_iterator SuperRegClasses;
+ ArrayRef<uint16_t> (*OrderFunc)(const MachineFunction&);
+
+ /// getID() - Return the register class ID number.
+ ///
+ unsigned getID() const { return MC->getID(); }
+
+ /// getName() - Return the register class name for debugging.
+ ///
+ const char *getName() const { return MC->getName(); }
+
+ /// begin/end - Return all of the registers in this class.
+ ///
+ iterator begin() const { return MC->begin(); }
+ iterator end() const { return MC->end(); }
+
+ /// getNumRegs - Return the number of registers in this class.
+ ///
+ unsigned getNumRegs() const { return MC->getNumRegs(); }
+
+ /// getRegister - Return the specified register in the class.
+ ///
+ unsigned getRegister(unsigned i) const {
+ return MC->getRegister(i);
+ }
+
+ /// contains - Return true if the specified register is included in this
+ /// register class. This does not include virtual registers.
+ bool contains(unsigned Reg) const {
+ return MC->contains(Reg);
+ }
+
+ /// contains - Return true if both registers are in this class.
+ bool contains(unsigned Reg1, unsigned Reg2) const {
+ return MC->contains(Reg1, Reg2);
+ }
+
+ /// getSize - Return the size of the register in bytes, which is also the size
+ /// of a stack slot allocated to hold a spilled copy of this register.
+ unsigned getSize() const { return MC->getSize(); }
+
+ /// getAlignment - Return the minimum required alignment for a register of
+ /// this class.
+ unsigned getAlignment() const { return MC->getAlignment(); }
+
+ /// getCopyCost - Return the cost of copying a value between two registers in
+ /// this class. A negative number means the register class is very expensive
+ /// to copy e.g. status flag register classes.
+ int getCopyCost() const { return MC->getCopyCost(); }
+
+ /// isAllocatable - Return true if this register class may be used to create
+ /// virtual registers.
+ bool isAllocatable() const { return MC->isAllocatable(); }
+
+ /// hasType - return true if this TargetRegisterClass has the ValueType vt.
+ ///
+ bool hasType(EVT vt) const {
+ for(int i = 0; VTs[i] != MVT::Other; ++i)
+ if (EVT(VTs[i]) == vt)
+ return true;
+ return false;
+ }
+
+ /// vt_begin / vt_end - Loop over all of the value types that can be
+ /// represented by values in this register class.
+ vt_iterator vt_begin() const {
+ return VTs;
+ }
+
+ vt_iterator vt_end() const {
+ vt_iterator I = VTs;
+ while (*I != MVT::Other) ++I;
+ return I;
+ }
+
+ /// superregclasses_begin / superregclasses_end - Loop over all of
+ /// the superreg register classes of this register class.
+ sc_iterator superregclasses_begin() const {
+ return SuperRegClasses;
+ }
+
+ sc_iterator superregclasses_end() const {
+ sc_iterator I = SuperRegClasses;
+ while (*I != NULL) ++I;
+ return I;
+ }
+
+ /// hasSubClass - return true if the specified TargetRegisterClass
+ /// is a proper sub-class of this TargetRegisterClass.
+ bool hasSubClass(const TargetRegisterClass *RC) const {
+ return RC != this && hasSubClassEq(RC);
+ }
+
+ /// hasSubClassEq - Returns true if RC is a sub-class of or equal to this
+ /// class.
+ bool hasSubClassEq(const TargetRegisterClass *RC) const {
+ unsigned ID = RC->getID();
+ return (SubClassMask[ID / 32] >> (ID % 32)) & 1;
+ }
+
+ /// hasSuperClass - return true if the specified TargetRegisterClass is a
+ /// proper super-class of this TargetRegisterClass.
+ bool hasSuperClass(const TargetRegisterClass *RC) const {
+ return RC->hasSubClass(this);
+ }
+
+ /// hasSuperClassEq - Returns true if RC is a super-class of or equal to this
+ /// class.
+ bool hasSuperClassEq(const TargetRegisterClass *RC) const {
+ return RC->hasSubClassEq(this);
+ }
+
+ /// getSubClassMask - Returns a bit vector of subclasses, including this one.
+ /// The vector is indexed by class IDs, see hasSubClassEq() above for how to
+ /// use it.
+ const uint32_t *getSubClassMask() const {
+ return SubClassMask;
+ }
+
+ /// getSuperClasses - Returns a NULL terminated list of super-classes. The
+ /// classes are ordered by ID which is also a topological ordering from large
+ /// to small classes. The list does NOT include the current class.
+ sc_iterator getSuperClasses() const {
+ return SuperClasses;
+ }
+
+ /// isASubClass - return true if this TargetRegisterClass is a subset
+ /// class of at least one other TargetRegisterClass.
+ bool isASubClass() const {
+ return SuperClasses[0] != 0;
+ }
+
+ /// getRawAllocationOrder - Returns the preferred order for allocating
+ /// registers from this register class in MF. The raw order comes directly
+ /// from the .td file and may include reserved registers that are not
+ /// allocatable. Register allocators should also make sure to allocate
+ /// callee-saved registers only after all the volatiles are used. The
+ /// RegisterClassInfo class provides filtered allocation orders with
+ /// callee-saved registers moved to the end.
+ ///
+ /// The MachineFunction argument can be used to tune the allocatable
+ /// registers based on the characteristics of the function, subtarget, or
+ /// other criteria.
+ ///
+ /// By default, this method returns all registers in the class.
+ ///
+ ArrayRef<uint16_t> getRawAllocationOrder(const MachineFunction &MF) const {
+ return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs());
+ }
+};
+
+/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about
+/// registers. These are used by codegen, not by MC.
+struct TargetRegisterInfoDesc {
+ unsigned CostPerUse; // Extra cost of instructions using register.
+ bool inAllocatableClass; // Register belongs to an allocatable regclass.
+};
+
+/// Each TargetRegisterClass has a per register weight, and weight
+/// limit which must be less than the limits of its pressure sets.
+struct RegClassWeight {
+ unsigned RegWeight;
+ unsigned WeightLimit;
+};
+
+/// TargetRegisterInfo base class - We assume that the target defines a static
+/// array of TargetRegisterDesc objects that represent all of the machine
+/// registers that the target has. As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+class TargetRegisterInfo : public MCRegisterInfo {
+public:
+ typedef const TargetRegisterClass * const * regclass_iterator;
+private:
+ const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
+ const char *const *SubRegIndexNames; // Names of subreg indexes.
+ regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
+
+protected:
+ TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
+ regclass_iterator RegClassBegin,
+ regclass_iterator RegClassEnd,
+ const char *const *subregindexnames);
+ virtual ~TargetRegisterInfo();
+public:
+
+ // Register numbers can represent physical registers, virtual registers, and
+ // sometimes stack slots. The unsigned values are divided into these ranges:
+ //
+ // 0 Not a register, can be used as a sentinel.
+ // [1;2^30) Physical registers assigned by TableGen.
+ // [2^30;2^31) Stack slots. (Rarely used.)
+ // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo.
+ //
+ // Further sentinels can be allocated from the small negative integers.
+ // DenseMapInfo<unsigned> uses -1u and -2u.
+
+ /// isStackSlot - Sometimes it is useful the be able to store a non-negative
+ /// frame index in a variable that normally holds a register. isStackSlot()
+ /// returns true if Reg is in the range used for stack slots.
+ ///
+ /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack
+ /// slots, so if a variable may contains a stack slot, always check
+ /// isStackSlot() first.
+ ///
+ static bool isStackSlot(unsigned Reg) {
+ return int(Reg) >= (1 << 30);
+ }
+
+ /// stackSlot2Index - Compute the frame index from a register value
+ /// representing a stack slot.
+ static int stackSlot2Index(unsigned Reg) {
+ assert(isStackSlot(Reg) && "Not a stack slot");
+ return int(Reg - (1u << 30));
+ }
+
+ /// index2StackSlot - Convert a non-negative frame index to a stack slot
+ /// register value.
+ static unsigned index2StackSlot(int FI) {
+ assert(FI >= 0 && "Cannot hold a negative frame index.");
+ return FI + (1u << 30);
+ }
+
+ /// isPhysicalRegister - Return true if the specified register number is in
+ /// the physical register namespace.
+ static bool isPhysicalRegister(unsigned Reg) {
+ assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+ return int(Reg) > 0;
+ }
+
+ /// isVirtualRegister - Return true if the specified register number is in
+ /// the virtual register namespace.
+ static bool isVirtualRegister(unsigned Reg) {
+ assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
+ return int(Reg) < 0;
+ }
+
+ /// virtReg2Index - Convert a virtual register number to a 0-based index.
+ /// The first virtual register in a function will get the index 0.
+ static unsigned virtReg2Index(unsigned Reg) {
+ assert(isVirtualRegister(Reg) && "Not a virtual register");
+ return Reg & ~(1u << 31);
+ }
+
+ /// index2VirtReg - Convert a 0-based index to a virtual register number.
+ /// This is the inverse operation of VirtReg2IndexFunctor below.
+ static unsigned index2VirtReg(unsigned Index) {
+ return Index | (1u << 31);
+ }
+
+ /// getMinimalPhysRegClass - Returns the Register Class of a physical
+ /// register of the given type, picking the most sub register class of
+ /// the right type that contains this physreg.
+ const TargetRegisterClass *
+ getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const;
+
+ /// getAllocatableSet - Returns a bitset indexed by register number
+ /// indicating if a register is allocatable or not. If a register class is
+ /// specified, returns the subset for the class.
+ BitVector getAllocatableSet(const MachineFunction &MF,
+ const TargetRegisterClass *RC = NULL) const;
+
+ /// getCostPerUse - Return the additional cost of using this register instead
+ /// of other registers in its class.
+ unsigned getCostPerUse(unsigned RegNo) const {
+ return InfoDesc[RegNo].CostPerUse;
+ }
+
+ /// isInAllocatableClass - Return true if the register is in the allocation
+ /// of any register class.
+ bool isInAllocatableClass(unsigned RegNo) const {
+ return InfoDesc[RegNo].inAllocatableClass;
+ }
+
+ /// 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");
+ return SubRegIndexNames[SubIdx-1];
+ }
+
+ /// 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 {
+ if (regA == regB) return true;
+ if (isVirtualRegister(regA) || isVirtualRegister(regB))
+ return false;
+ for (const uint16_t *regList = getOverlaps(regA)+1; *regList; ++regList) {
+ if (*regList == regB) return true;
+ }
+ 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 (const uint16_t *regList = getSuperRegisters(regA); *regList;++regList){
+ if (*regList == 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)
+ const = 0;
+
+ /// getCallPreservedMask - Return a mask of call-preserved registers for the
+ /// given calling convention on the current sub-target. The mask should
+ /// include all call-preserved aliases. This is used by the register
+ /// allocator to determine which registers can be live across a call.
+ ///
+ /// The mask is an array containing (TRI::getNumRegs()+31)/32 entries.
+ /// A set bit indicates that all bits of the corresponding register are
+ /// preserved across the function call. The bit mask is expected to be
+ /// sub-register complete, i.e. if A is preserved, so are all its
+ /// sub-registers.
+ ///
+ /// Bits are numbered from the LSB, so the bit for physical register Reg can
+ /// be found as (Mask[Reg / 32] >> Reg % 32) & 1.
+ ///
+ /// A NULL pointer means that no register mask will be used, and call
+ /// instructions should use implicit-def operands to indicate call clobbered
+ /// registers.
+ ///
+ virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const {
+ // The default mask clobbers everything. All targets should override.
+ return 0;
+ }
+
+ /// getReservedRegs - Returns a bitset indexed by physical register number
+ /// indicating if a register is a special register that has particular uses
+ /// and should be considered unavailable at all times, e.g. SP, RA. This is
+ /// used by register scavenger to determine what registers are free.
+ virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+
+ /// getMatchingSuperReg - 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 TargetRegisterClass *RC) const {
+ 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.
+ ///
+ /// TableGen will synthesize missing A sub-classes.
+ virtual const TargetRegisterClass *
+ getMatchingSuperRegClass(const TargetRegisterClass *A,
+ const TargetRegisterClass *B, unsigned Idx) const =0;
+
+ /// getSubClassWithSubReg - Returns the largest legal sub-class of RC that
+ /// supports the sub-register index Idx.
+ /// If no such sub-class exists, return NULL.
+ /// If all registers in RC already have an Idx sub-register, return RC.
+ ///
+ /// TableGen generates a version of this function that is good enough in most
+ /// cases. Targets can override if they have constraints that TableGen
+ /// doesn't understand. For example, the x86 sub_8bit sub-register index is
+ /// supported by the full GR32 register class in 64-bit mode, but only by the
+ /// GR32_ABCD regiister class in 32-bit mode.
+ ///
+ /// TableGen will synthesize missing RC sub-classes.
+ virtual const TargetRegisterClass *
+ getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const =0;
+
+ /// composeSubRegIndices - Return the subregister index you get from composing
+ /// two subregister indices.
+ ///
+ /// 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
+ /// b, composeSubRegIndices doesn't tell you.
+ ///
+ /// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has
+ /// 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;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Register Class Information
+ //
+
+ /// Register class iterators
+ ///
+ regclass_iterator regclass_begin() const { return RegClassBegin; }
+ regclass_iterator regclass_end() const { return RegClassEnd; }
+
+ unsigned getNumRegClasses() const {
+ return (unsigned)(regclass_end()-regclass_begin());
+ }
+
+ /// getRegClass - Returns the register class associated with the enumeration
+ /// value. See class MCOperandInfo.
+ const TargetRegisterClass *getRegClass(unsigned i) const {
+ assert(i < getNumRegClasses() && "Register Class ID out of range");
+ return RegClassBegin[i];
+ }
+
+ /// getCommonSubClass - find the largest common subclass of A and B. Return
+ /// NULL if there is no common subclass.
+ const TargetRegisterClass *
+ getCommonSubClass(const TargetRegisterClass *A,
+ const TargetRegisterClass *B) const;
+
+ /// getPointerRegClass - Returns a TargetRegisterClass used for pointer
+ /// values. If a target supports multiple different pointer register classes,
+ /// kind specifies which one is indicated.
+ virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const {
+ llvm_unreachable("Target didn't implement getPointerRegClass!");
+ }
+
+ /// getCrossCopyRegClass - Returns a legal register class to copy a register
+ /// in the specified class to or from. If it is possible to copy the register
+ /// directly without using a cross register class copy, return the specified
+ /// RC. Returns NULL if it is not possible to copy between a two registers of
+ /// the specified class.
+ virtual const TargetRegisterClass *
+ getCrossCopyRegClass(const TargetRegisterClass *RC) const {
+ return RC;
+ }
+
+ /// getLargestLegalSuperClass - Returns the largest super class of RC that is
+ /// legal to use in the current sub-target and has the same spill size.
+ /// The returned register class can be used to create virtual registers which
+ /// means that all its registers can be copied and spilled.
+ virtual const TargetRegisterClass*
+ getLargestLegalSuperClass(const TargetRegisterClass *RC) const {
+ /// The default implementation is very conservative and doesn't allow the
+ /// register allocator to inflate register classes.
+ return RC;
+ }
+
+ /// getRegPressureLimit - Return the register pressure "high water mark" for
+ /// the specific register class. The scheduler is in high register pressure
+ /// mode (for the specific register class) if it goes over the limit.
+ ///
+ /// Note: this is the old register pressure model that relies on a manually
+ /// specified representative register class per value type.
+ virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC,
+ MachineFunction &MF) const {
+ return 0;
+ }
+
+ /// Get the weight in units of pressure for this register class.
+ virtual const RegClassWeight &getRegClassWeight(
+ const TargetRegisterClass *RC) const = 0;
+
+ /// Get the number of dimensions of register pressure.
+ virtual unsigned getNumRegPressureSets() const = 0;
+
+ /// Get the register unit pressure limit for this dimension.
+ /// This limit must be adjusted dynamically for reserved registers.
+ virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0;
+
+ /// Get the dimensions of register pressure impacted by this register class.
+ /// Returns a -1 terminated array of pressure set IDs.
+ 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;
+ }
+
+ /// avoidWriteAfterWrite - Return true if the register allocator should avoid
+ /// writing a register from RC in two consecutive instructions.
+ /// This can avoid pipeline stalls on certain architectures.
+ /// It does cause increased register pressure, though.
+ virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
+ return false;
+ }
+
+ /// UpdateRegAllocHint - A callback to allow target a chance to update
+ /// register allocation hints when a register is "changed" (e.g. coalesced)
+ /// to another register. e.g. On ARM, some virtual registers should target
+ /// register pairs, if one of pair is coalesced to another register, the
+ /// allocation hint of the other half of the pair should be changed to point
+ /// to the new register.
+ virtual void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
+ MachineFunction &MF) const {
+ // Do nothing.
+ }
+
+ /// requiresRegisterScavenging - returns true if the target requires (and can
+ /// make use of) the register scavenger.
+ virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
+ return false;
+ }
+
+ /// useFPForScavengingIndex - returns true if the target wants to use
+ /// frame pointer based accesses to spill to the scavenger emergency spill
+ /// slot.
+ virtual bool useFPForScavengingIndex(const MachineFunction &MF) const {
+ return true;
+ }
+
+ /// requiresFrameIndexScavenging - returns true if the target requires post
+ /// PEI scavenging of registers for materializing frame index constants.
+ virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const {
+ return false;
+ }
+
+ /// requiresVirtualBaseRegisters - Returns true if the target wants the
+ /// LocalStackAllocation pass to be run and virtual base registers
+ /// used for more efficient stack access.
+ virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const {
+ return false;
+ }
+
+ /// hasReservedSpillSlot - Return true if target has reserved a spill slot in
+ /// the stack frame of the given function for the specified register. e.g. On
+ /// x86, if the frame register is required, the first fixed stack object is
+ /// reserved as its spill slot. This tells PEI not to create a new stack frame
+ /// object for the given register. It should be called only after
+ /// processFunctionBeforeCalleeSavedScan().
+ virtual bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
+ int &FrameIdx) const {
+ return false;
+ }
+
+ /// needsStackRealignment - true if storage within the function requires the
+ /// stack pointer to be aligned more than the normal calling convention calls
+ /// for.
+ virtual bool needsStackRealignment(const MachineFunction &MF) const {
+ return false;
+ }
+
+ /// getFrameIndexInstrOffset - Get the offset from the referenced frame
+ /// index in the instruction, if there is one.
+ virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
+ int Idx) const {
+ return 0;
+ }
+
+ /// needsFrameBaseReg - Returns true if the instruction's frame index
+ /// reference would be better served by a base register other than FP
+ /// or SP. Used by LocalStackFrameAllocation to determine which frame index
+ /// references it should create new base registers for.
+ virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
+ return false;
+ }
+
+ /// materializeFrameBaseRegister - Insert defining instruction(s) for
+ /// BaseReg to be a pointer to FrameIdx before insertion point I.
+ virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB,
+ unsigned BaseReg, int FrameIdx,
+ int64_t Offset) const {
+ llvm_unreachable("materializeFrameBaseRegister does not exist on this "
+ "target");
+ }
+
+ /// resolveFrameIndex - Resolve a frame index operand of an instruction
+ /// to reference the indicated base register plus offset instead.
+ virtual void resolveFrameIndex(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int64_t Offset) const {
+ llvm_unreachable("resolveFrameIndex does not exist on this target");
+ }
+
+ /// isFrameOffsetLegal - Determine whether a given offset immediate is
+ /// encodable to resolve a frame index.
+ virtual bool isFrameOffsetLegal(const MachineInstr *MI,
+ int64_t Offset) const {
+ llvm_unreachable("isFrameOffsetLegal does not exist on this target");
+ }
+
+ /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
+ /// code insertion to eliminate call frame setup and destroy pseudo
+ /// instructions (but only if the Target is using them). It is responsible
+ /// for eliminating these instructions, replacing them with concrete
+ /// instructions. This method need only be implemented if using call frame
+ /// setup/destroy pseudo instructions.
+ ///
+ virtual void
+ eliminateCallFramePseudoInstr(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const {
+ llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
+ "target!");
+ }
+
+
+ /// saveScavengerRegister - Spill the register so it can be used by the
+ /// register scavenger. Return true if the register was spilled, false
+ /// otherwise. If this function does not spill the register, the scavenger
+ /// will instead spill it to the emergency spill slot.
+ ///
+ virtual bool saveScavengerRegister(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ MachineBasicBlock::iterator &UseMI,
+ const TargetRegisterClass *RC,
+ unsigned Reg) const {
+ return false;
+ }
+
+ /// eliminateFrameIndex - This method must be overriden to eliminate abstract
+ /// frame indices from instructions which may use them. The instruction
+ /// referenced by the iterator contains an MO_FrameIndex operand which must be
+ /// eliminated by this method. This method may modify or replace the
+ /// specified instruction, as long as it keeps the iterator pointing at the
+ /// finished product. SPAdj is the SP adjustment due to call frame setup
+ /// instruction.
+ virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
+ int SPAdj, RegScavenger *RS=NULL) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ /// Debug information queries.
+
+ /// getFrameRegister - This method should return the register used as a base
+ /// for values allocated in the current stack frame.
+ virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
+
+ /// getCompactUnwindRegNum - This function maps the register to the number for
+ /// compact unwind encoding. Return -1 if the register isn't valid.
+ virtual int getCompactUnwindRegNum(unsigned, bool) const {
+ return -1;
+ }
+};
+
+
+// This is useful when building IndexedMaps keyed on virtual registers
+struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
+ unsigned operator()(unsigned Reg) const {
+ return TargetRegisterInfo::virtReg2Index(Reg);
+ }
+};
+
+/// PrintReg - Helper class for printing registers on a raw_ostream.
+/// Prints virtual and physical registers with or without a TRI instance.
+///
+/// The format is:
+/// %noreg - NoRegister
+/// %vreg5 - a virtual register.
+/// %vreg5:sub_8bit - a virtual register with sub-register index (with TRI).
+/// %EAX - a physical register
+/// %physreg17 - a physical register when no TRI instance given.
+///
+/// Usage: OS << PrintReg(Reg, TRI) << '\n';
+///
+class PrintReg {
+ const TargetRegisterInfo *TRI;
+ unsigned Reg;
+ unsigned SubIdx;
+public:
+ PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, unsigned subidx = 0)
+ : TRI(tri), Reg(reg), SubIdx(subidx) {}
+ void print(raw_ostream&) const;
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) {
+ PR.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetSchedule.td b/contrib/llvm/include/llvm/Target/TargetSchedule.td
new file mode 100644
index 000000000000..97ea82ab9e3d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetSchedule.td
@@ -0,0 +1,130 @@
+//===- TargetSchedule.td - Target Independent Scheduling ---*- 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 the target-independent scheduling interfaces which should
+// be implemented by each target which is using TableGen based scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Processor functional unit - These values represent the function units
+// available across all chip sets for the target. Eg., IntUnit, FPUnit, ...
+// These may be independent values for each chip set or may be shared across
+// all chip sets of the target. Each functional unit is treated as a resource
+// during scheduling and has an affect instruction order based on availability
+// during a time interval.
+//
+class FuncUnit;
+
+//===----------------------------------------------------------------------===//
+// Pipeline bypass / forwarding - These values specifies the symbolic names of
+// pipeline bypasses which can be used to forward results of instructions
+// that are forwarded to uses.
+class Bypass;
+def NoBypass : Bypass;
+
+class ReservationKind<bits<1> val> {
+ int Value = val;
+}
+
+def Required : ReservationKind<0>;
+def Reserved : ReservationKind<1>;
+
+//===----------------------------------------------------------------------===//
+// Instruction stage - These values represent a non-pipelined step in
+// the execution of an instruction. Cycles represents the number of
+// discrete time slots needed to complete the stage. Units represent
+// the choice of functional units that can be used to complete the
+// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
+// cycles should elapse from the start of this stage to the start of
+// the next stage in the itinerary. For example:
+//
+// A stage is specified in one of two ways:
+//
+// InstrStage<1, [FU_x, FU_y]> - TimeInc defaults to Cycles
+// InstrStage<1, [FU_x, FU_y], 0> - TimeInc explicit
+//
+
+class InstrStage<int cycles, list<FuncUnit> units,
+ int timeinc = -1,
+ ReservationKind kind = Required> {
+ int Cycles = cycles; // length of stage in machine cycles
+ list<FuncUnit> Units = units; // choice of functional units
+ int TimeInc = timeinc; // cycles till start of next stage
+ int Kind = kind.Value; // kind of FU reservation
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary - An itinerary represents a sequential series of steps
+// required to complete an instruction. Itineraries are represented as lists of
+// instruction stages.
+//
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary classes - These values represent 'named' instruction
+// itinerary. Using named itineraries simplifies managing groups of
+// instructions across chip sets. An instruction uses the same itinerary class
+// across all chip sets. Thus a new chip set can be added without modifying
+// instruction information.
+//
+// NumMicroOps represents the number of micro-operations that each instruction
+// in the class are decoded to. If the number is zero, then it means the
+// instruction can decode into variable number of micro-ops and it must be
+// determined dynamically.
+//
+class InstrItinClass<int ops = 1> {
+ int NumMicroOps = ops;
+}
+def NoItinerary : InstrItinClass;
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary data - These values provide a runtime map of an
+// instruction itinerary class (name) to its itinerary data.
+//
+// OperandCycles are optional "cycle counts". They specify the cycle after
+// instruction issue the values which correspond to specific operand indices
+// are defined or read. Bypasses are optional "pipeline forwarding pathes", if
+// a def by an instruction is available on a specific bypass and the use can
+// read from the same bypass, then the operand use latency is reduced by one.
+//
+// InstrItinData<IIC_iLoad_i , [InstrStage<1, [A9_Pipe1]>,
+// InstrStage<1, [A9_AGU]>],
+// [3, 1], [A9_LdBypass]>,
+// InstrItinData<IIC_iMVNr , [InstrStage<1, [A9_Pipe0, A9_Pipe1]>],
+// [1, 1], [NoBypass, A9_LdBypass]>,
+//
+// In this example, the instruction of IIC_iLoadi reads its input on cycle 1
+// (after issue) and the result of the load is available on cycle 3. The result
+// is available via forwarding path A9_LdBypass. If it's used by the first
+// source operand of instructions of IIC_iMVNr class, then the operand latency
+// is reduced by 1.
+class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
+ list<int> operandcycles = [],
+ list<Bypass> bypasses = []> {
+ InstrItinClass TheClass = Class;
+ list<InstrStage> Stages = stages;
+ list<int> OperandCycles = operandcycles;
+ list<Bypass> Bypasses = bypasses;
+}
+
+//===----------------------------------------------------------------------===//
+// Processor itineraries - These values represent the set of all itinerary
+// classes for a given chip set.
+//
+class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
+ list<InstrItinData> iid> {
+ list<FuncUnit> FU = fu;
+ list<Bypass> BP = bp;
+ list<InstrItinData> IID = iid;
+}
+
+// NoItineraries - A marker that can be used by processors without schedule
+// info.
+def NoItineraries : ProcessorItineraries<[], [], []>;
+
diff --git a/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td b/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td
new file mode 100644
index 000000000000..f55cf0e6306c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -0,0 +1,1018 @@
+//===- TargetSelectionDAG.td - Common code for DAG isels ---*- 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 the target-independent interfaces used by SelectionDAG
+// instruction selection generators.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Type Constraint definitions.
+//
+// Note that the semantics of these constraints are hard coded into tblgen. To
+// modify or add constraints, you have to hack tblgen.
+//
+
+class SDTypeConstraint<int opnum> {
+ int OperandNum = opnum;
+}
+
+// SDTCisVT - The specified operand has exactly this VT.
+class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
+ ValueType VT = vt;
+}
+
+class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisInt - The specified operand has integer type.
+class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisFP - The specified operand has floating-point type.
+class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisVec - The specified operand has a vector type.
+class SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>;
+
+// SDTCisSameAs - The two specified operands have identical types.
+class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
+ int OtherOperandNum = OtherOp;
+}
+
+// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is
+// smaller than the 'Other' operand.
+class SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
+ int OtherOperandNum = OtherOp;
+}
+
+class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{
+ int BigOperandNum = BigOp;
+}
+
+/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same
+/// type as the element type of OtherOp, which is a vector type.
+class SDTCisEltOfVec<int ThisOp, int OtherOp>
+ : SDTypeConstraint<ThisOp> {
+ int OtherOpNum = OtherOp;
+}
+
+/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type
+/// with length less that of OtherOp, which is a vector type.
+class SDTCisSubVecOfVec<int ThisOp, int OtherOp>
+ : SDTypeConstraint<ThisOp> {
+ int OtherOpNum = OtherOp;
+}
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Type Profile definitions.
+//
+// These use the constraints defined above to describe the type requirements of
+// the various nodes. These are not hard coded into tblgen, allowing targets to
+// add their own if needed.
+//
+
+// SDTypeProfile - This profile describes the type requirements of a Selection
+// DAG node.
+class SDTypeProfile<int numresults, int numoperands,
+ list<SDTypeConstraint> constraints> {
+ int NumResults = numresults;
+ int NumOperands = numoperands;
+ list<SDTypeConstraint> Constraints = constraints;
+}
+
+// Builtin profiles.
+def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'.
+def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'.
+def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'.
+def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'.
+def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'.
+def SDTUnaryOp : SDTypeProfile<1, 1, []>; // for bitconvert.
+
+def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc.
+ SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>
+]>;
+def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl
+ SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>
+]>;
+def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem
+ SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0>
+]>;
+
+def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc.
+ SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0>
+]>;
+def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign.
+ SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2>
+]>;
+def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc.
+ SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0>
+]>;
+def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz
+ SDTCisSameAs<0, 1>, SDTCisInt<0>
+]>;
+def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>
+]>;
+def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>
+]>;
+def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc
+ SDTCisSameAs<0, 1>, SDTCisFP<0>
+]>;
+def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fround
+ SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>
+]>;
+def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend
+ SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
+]>;
+def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
+ SDTCisFP<0>, SDTCisInt<1>
+]>;
+def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
+ SDTCisInt<0>, SDTCisFP<1>
+]>;
+def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
+ SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
+ SDTCisVTSmallerThanOp<2, 1>
+]>;
+
+def SDTSetCC : SDTypeProfile<1, 3, [ // setcc
+ SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
+]>;
+
+def SDTSelect : SDTypeProfile<1, 3, [ // select
+ SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
+]>;
+
+def SDTVSelect : SDTypeProfile<1, 3, [ // vselect
+ SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
+]>;
+
+def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc
+ SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>,
+ SDTCisVT<5, OtherVT>
+]>;
+
+def SDTBr : SDTypeProfile<0, 1, [ // br
+ SDTCisVT<0, OtherVT>
+]>;
+
+def SDTBrcond : SDTypeProfile<0, 2, [ // brcond
+ SDTCisInt<0>, SDTCisVT<1, OtherVT>
+]>;
+
+def SDTBrind : SDTypeProfile<0, 1, [ // brind
+ SDTCisPtrTy<0>
+]>;
+
+def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
+
+def SDTLoad : SDTypeProfile<1, 1, [ // load
+ SDTCisPtrTy<1>
+]>;
+
+def SDTStore : SDTypeProfile<0, 2, [ // store
+ SDTCisPtrTy<1>
+]>;
+
+def SDTIStore : SDTypeProfile<1, 3, [ // indexed store
+ SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3>
+]>;
+
+def SDTVecShuffle : SDTypeProfile<1, 2, [
+ SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
+]>;
+def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract
+ SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2>
+]>;
+def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert
+ SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3>
+]>;
+
+def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract
+ SDTCisSubVecOfVec<0,1>, SDTCisInt<2>
+]>;
+def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert
+ SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3>
+]>;
+
+def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch
+ SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1>
+]>;
+
+def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barier
+ SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>,
+ SDTCisInt<0>
+]>;
+def SDTAtomicFence : SDTypeProfile<0, 2, [
+ SDTCisSameAs<0,1>, SDTCisPtrTy<0>
+]>;
+def SDTAtomic3 : SDTypeProfile<1, 3, [
+ SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+def SDTAtomic2 : SDTypeProfile<1, 2, [
+ SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+def SDTAtomicStore : SDTypeProfile<0, 2, [
+ SDTCisPtrTy<0>, SDTCisInt<1>
+]>;
+def SDTAtomicLoad : SDTypeProfile<1, 1, [
+ SDTCisInt<0>, SDTCisPtrTy<1>
+]>;
+
+def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su
+ SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>
+]>;
+
+class SDCallSeqStart<list<SDTypeConstraint> constraints> :
+ SDTypeProfile<0, 1, constraints>;
+class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
+ SDTypeProfile<0, 2, constraints>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Node Properties.
+//
+// Note: These are hard coded into tblgen.
+//
+class SDNodeProperty;
+def SDNPCommutative : SDNodeProperty; // X op Y == Y op X
+def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z)
+def SDNPHasChain : SDNodeProperty; // R/W chain operand and result
+def SDNPOutGlue : SDNodeProperty; // Write a flag result
+def SDNPInGlue : SDNodeProperty; // Read a flag operand
+def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand
+def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'.
+def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
+def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
+def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
+def SDNPVariadic : SDNodeProperty; // Node has variable arguments.
+def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match
+def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Pattern Operations
+class SDPatternOperator;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Node definitions.
+//
+class SDNode<string opcode, SDTypeProfile typeprof,
+ list<SDNodeProperty> props = [], string sdclass = "SDNode">
+ : SDPatternOperator {
+ string Opcode = opcode;
+ string SDClass = sdclass;
+ list<SDNodeProperty> Properties = props;
+ SDTypeProfile TypeProfile = typeprof;
+}
+
+// Special TableGen-recognized dag nodes
+def set;
+def implicit;
+def node;
+def srcvalue;
+
+def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">;
+def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">;
+def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">;
+def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">;
+def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">;
+def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">;
+def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>;
+def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [],
+ "GlobalAddressSDNode">;
+def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [],
+ "GlobalAddressSDNode">;
+def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [],
+ "GlobalAddressSDNode">;
+def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [],
+ "GlobalAddressSDNode">;
+def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [],
+ "ConstantPoolSDNode">;
+def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [],
+ "ConstantPoolSDNode">;
+def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [],
+ "JumpTableSDNode">;
+def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [],
+ "JumpTableSDNode">;
+def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [],
+ "FrameIndexSDNode">;
+def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [],
+ "FrameIndexSDNode">;
+def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [],
+ "ExternalSymbolSDNode">;
+def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [],
+ "ExternalSymbolSDNode">;
+def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [],
+ "BlockAddressSDNode">;
+def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [],
+ "BlockAddressSDNode">;
+
+def add : SDNode<"ISD::ADD" , SDTIntBinOp ,
+ [SDNPCommutative, SDNPAssociative]>;
+def sub : SDNode<"ISD::SUB" , SDTIntBinOp>;
+def mul : SDNode<"ISD::MUL" , SDTIntBinOp,
+ [SDNPCommutative, SDNPAssociative]>;
+def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>;
+def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>;
+def smullohi : SDNode<"ISD::SMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>;
+def umullohi : SDNode<"ISD::UMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>;
+def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>;
+def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>;
+def srem : SDNode<"ISD::SREM" , SDTIntBinOp>;
+def urem : SDNode<"ISD::UREM" , SDTIntBinOp>;
+def sdivrem : SDNode<"ISD::SDIVREM" , SDTIntBinHiLoOp>;
+def udivrem : SDNode<"ISD::UDIVREM" , SDTIntBinHiLoOp>;
+def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>;
+def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>;
+def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>;
+def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>;
+def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>;
+def and : SDNode<"ISD::AND" , SDTIntBinOp,
+ [SDNPCommutative, SDNPAssociative]>;
+def or : SDNode<"ISD::OR" , SDTIntBinOp,
+ [SDNPCommutative, SDNPAssociative]>;
+def xor : SDNode<"ISD::XOR" , SDTIntBinOp,
+ [SDNPCommutative, SDNPAssociative]>;
+def addc : SDNode<"ISD::ADDC" , SDTIntBinOp,
+ [SDNPCommutative, SDNPOutGlue]>;
+def adde : SDNode<"ISD::ADDE" , SDTIntBinOp,
+ [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>;
+def subc : SDNode<"ISD::SUBC" , SDTIntBinOp,
+ [SDNPOutGlue]>;
+def sube : SDNode<"ISD::SUBE" , SDTIntBinOp,
+ [SDNPOutGlue, SDNPInGlue]>;
+
+def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
+def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
+def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
+def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>;
+def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>;
+def ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntUnaryOp>;
+def cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntUnaryOp>;
+def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>;
+def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>;
+def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>;
+def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>;
+def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>;
+def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>;
+def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>;
+
+
+def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>;
+def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>;
+def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>;
+def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>;
+def frem : SDNode<"ISD::FREM" , SDTFPBinOp>;
+def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp>;
+def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>;
+def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>;
+def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>;
+def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>;
+def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>;
+def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>;
+def fexp2 : SDNode<"ISD::FEXP2" , SDTFPUnaryOp>;
+def flog2 : SDNode<"ISD::FLOG2" , SDTFPUnaryOp>;
+def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>;
+def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>;
+def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>;
+def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>;
+def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>;
+
+def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>;
+def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>;
+def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>;
+
+def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>;
+def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>;
+def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>;
+def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
+def f16_to_f32 : SDNode<"ISD::FP16_TO_FP32", SDTIntToFPOp>;
+def f32_to_f16 : SDNode<"ISD::FP32_TO_FP16", SDTFPToIntOp>;
+
+def setcc : SDNode<"ISD::SETCC" , SDTSetCC>;
+def select : SDNode<"ISD::SELECT" , SDTSelect>;
+def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>;
+def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>;
+
+def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>;
+def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
+def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
+def trap : SDNode<"ISD::TRAP" , SDTNone,
+ [SDNPHasChain, SDNPSideEffect]>;
+
+def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch,
+ [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
+ SDNPMemOperand]>;
+
+def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier,
+ [SDNPHasChain, SDNPSideEffect]>;
+
+def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence,
+ [SDNPHasChain, SDNPSideEffect]>;
+
+def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or : SDNode<"ISD::ATOMIC_LOAD_OR" , SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+
+// Do not use ld, st directly. Use load, extload, sextload, zextload, store,
+// and truncst (see below).
+def ld : SDNode<"ISD::LOAD" , SDTLoad,
+ [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+def st : SDNode<"ISD::STORE" , SDTStore,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def ist : SDNode<"ISD::STORE" , SDTIStore,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+
+def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>;
+def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>;
+def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
+ []>;
+def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
+ SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>;
+def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
+ SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
+
+// This operator does not do subvector type checking. The ARM
+// backend, at least, needs it.
+def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR",
+ SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>,
+ []>;
+
+// This operator does subvector type checking.
+def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>;
+def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>;
+
+// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use
+// these internally. Don't reference these directly.
+def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID",
+ SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>,
+ [SDNPHasChain]>;
+def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
+ SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>,
+ [SDNPHasChain]>;
+def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
+ SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
+
+// Do not use cvt directly. Use cvt forms below
+def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Condition Codes
+
+class CondCode; // ISD::CondCode enums
+def SETOEQ : CondCode; def SETOGT : CondCode;
+def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode;
+def SETONE : CondCode; def SETO : CondCode; def SETUO : CondCode;
+def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode;
+def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode;
+
+def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode;
+def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode;
+
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Node Transformation Functions.
+//
+// This mechanism allows targets to manipulate nodes in the output DAG once a
+// match has been formed. This is typically used to manipulate immediate
+// values.
+//
+class SDNodeXForm<SDNode opc, code xformFunction> {
+ SDNode Opcode = opc;
+ code XFormFunction = xformFunction;
+}
+
+def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
+
+//===----------------------------------------------------------------------===//
+// PatPred Subclasses.
+//
+// These allow specifying different sorts of predicates that control whether a
+// node is matched.
+//
+class PatPred;
+
+class CodePatPred<code predicate> : PatPred {
+ code PredicateCode = predicate;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Pattern Fragments.
+//
+// Pattern fragments are reusable chunks of dags that match specific things.
+// They can take arguments and have C++ predicates that control whether they
+// match. They are intended to make the patterns for common instructions more
+// compact and readable.
+//
+
+/// PatFrag - Represents a pattern fragment. This can match something on the
+/// DAG, from a single node to multiple nested other fragments.
+///
+class PatFrag<dag ops, dag frag, code pred = [{}],
+ SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
+ dag Operands = ops;
+ dag Fragment = frag;
+ code PredicateCode = pred;
+ code ImmediateCode = [{}];
+ SDNodeXForm OperandTransform = xform;
+}
+
+// PatLeaf's are pattern fragments that have no operands. This is just a helper
+// to define immediates and other common things concisely.
+class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
+ : PatFrag<(ops), frag, pred, xform>;
+
+
+// ImmLeaf is a pattern fragment with a constraint on the immediate. The
+// constraint is a function that is run on the immediate (always with the value
+// sign extended out to an int64_t) as Imm. For example:
+//
+// def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>;
+//
+// this is a more convenient form to match 'imm' nodes in than PatLeaf and also
+// is preferred over using PatLeaf because it allows the code generator to
+// reason more about the constraint.
+//
+// If FastIsel should ignore all instructions that have an operand of this type,
+// the FastIselShouldIgnore flag can be set. This is an optimization to reduce
+// the code size of the generated fast instruction selector.
+class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
+ : PatFrag<(ops), (vt imm), [{}], xform> {
+ let ImmediateCode = pred;
+ bit FastIselShouldIgnore = 0;
+}
+
+
+// Leaf fragments.
+
+def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>;
+def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>;
+
+def immAllOnesV: PatLeaf<(build_vector), [{
+ return ISD::isBuildVectorAllOnes(N);
+}]>;
+def immAllZerosV: PatLeaf<(build_vector), [{
+ return ISD::isBuildVectorAllZeros(N);
+}]>;
+
+
+
+// Other helper fragments.
+def not : PatFrag<(ops node:$in), (xor node:$in, -1)>;
+def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>;
+def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
+
+// load fragments.
+def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
+ return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
+def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
+}]>;
+
+// extending load fragments.
+def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+}]>;
+def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+}]>;
+def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+}]>;
+
+def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f64;
+}]>;
+
+def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f32;
+}]>;
+def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::f64;
+}]>;
+
+def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+
+def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i1;
+}]>;
+def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i8;
+}]>;
+def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i16;
+}]>;
+def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
+
+// store fragments.
+def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
+ (st node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
+def store : PatFrag<(ops node:$val, node:$ptr),
+ (unindexedstore node:$val, node:$ptr), [{
+ return !cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+
+// truncstore fragments.
+def truncstore : PatFrag<(ops node:$val, node:$ptr),
+ (unindexedstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f64;
+}]>;
+
+// indexed store fragments.
+def istore : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (ist node:$val, node:$base, node:$offset), [{
+ return !cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+
+def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (istore node:$val, node:$base, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
+
+def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (ist node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (itruncstore node:$val, node:$base, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
+def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+
+def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset),
+ (istore node:$val, node:$ptr, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
+
+def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (itruncstore node:$val, node:$base, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
+def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+
+// setcc convenience fragments.
+def setoeq : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOEQ)>;
+def setogt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOGT)>;
+def setoge : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOGE)>;
+def setolt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOLT)>;
+def setole : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOLE)>;
+def setone : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETONE)>;
+def seto : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETO)>;
+def setuo : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUO)>;
+def setueq : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUEQ)>;
+def setugt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUGT)>;
+def setuge : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUGE)>;
+def setult : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETULT)>;
+def setule : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETULE)>;
+def setune : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUNE)>;
+def seteq : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETEQ)>;
+def setgt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETGT)>;
+def setge : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETGE)>;
+def setlt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETLT)>;
+def setle : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETLE)>;
+def setne : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETNE)>;
+
+def atomic_cmp_swap_8 :
+ PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+ (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def atomic_cmp_swap_16 :
+ PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+ (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def atomic_cmp_swap_32 :
+ PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+ (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def atomic_cmp_swap_64 :
+ PatFrag<(ops node:$ptr, node:$cmp, node:$swap),
+ (atomic_cmp_swap node:$ptr, node:$cmp, node:$swap), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
+
+multiclass binary_atomic_op<SDNode atomic_op> {
+ def _8 : PatFrag<(ops node:$ptr, node:$val),
+ (atomic_op node:$ptr, node:$val), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
+ }]>;
+ def _16 : PatFrag<(ops node:$ptr, node:$val),
+ (atomic_op node:$ptr, node:$val), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
+ }]>;
+ def _32 : PatFrag<(ops node:$ptr, node:$val),
+ (atomic_op node:$ptr, node:$val), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
+ }]>;
+ def _64 : PatFrag<(ops node:$ptr, node:$val),
+ (atomic_op node:$ptr, node:$val), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
+ }]>;
+}
+
+defm atomic_load_add : binary_atomic_op<atomic_load_add>;
+defm atomic_swap : binary_atomic_op<atomic_swap>;
+defm atomic_load_sub : binary_atomic_op<atomic_load_sub>;
+defm atomic_load_and : binary_atomic_op<atomic_load_and>;
+defm atomic_load_or : binary_atomic_op<atomic_load_or>;
+defm atomic_load_xor : binary_atomic_op<atomic_load_xor>;
+defm atomic_load_nand : binary_atomic_op<atomic_load_nand>;
+defm atomic_load_min : binary_atomic_op<atomic_load_min>;
+defm atomic_load_max : binary_atomic_op<atomic_load_max>;
+defm atomic_load_umin : binary_atomic_op<atomic_load_umin>;
+defm atomic_load_umax : binary_atomic_op<atomic_load_umax>;
+defm atomic_store : binary_atomic_op<atomic_store>;
+
+def atomic_load_8 :
+ PatFrag<(ops node:$ptr),
+ (atomic_load node:$ptr), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def atomic_load_16 :
+ PatFrag<(ops node:$ptr),
+ (atomic_load node:$ptr), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def atomic_load_32 :
+ PatFrag<(ops node:$ptr),
+ (atomic_load node:$ptr), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def atomic_load_64 :
+ PatFrag<(ops node:$ptr),
+ (atomic_load node:$ptr), [{
+ return cast<AtomicSDNode>(N)->getMemoryVT() == MVT::i64;
+}]>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG CONVERT_RNDSAT patterns
+
+def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FF;
+ }]>;
+
+def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SS;
+ }]>;
+
+def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SU;
+ }]>;
+
+def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_US;
+ }]>;
+
+def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UU;
+ }]>;
+
+def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SF;
+ }]>;
+
+def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UF;
+ }]>;
+
+def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FS;
+ }]>;
+
+def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
+ (cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
+ return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FU;
+ }]>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Pattern Support.
+//
+// Patterns are what are actually matched against by the target-flavored
+// instruction selection DAG. Instructions defined by the target implicitly
+// define patterns in most cases, but patterns can also be explicitly added when
+// an operation is defined by a sequence of instructions (e.g. loading a large
+// immediate value on RISC targets that do not support immediates as large as
+// their GPRs).
+//
+
+class Pattern<dag patternToMatch, list<dag> resultInstrs> {
+ dag PatternToMatch = patternToMatch;
+ list<dag> ResultInstrs = resultInstrs;
+ list<Predicate> Predicates = []; // See class Instruction in Target.td.
+ int AddedComplexity = 0; // See class Instruction in Target.td.
+}
+
+// Pat - A simple (but common) form of a pattern, which produces a simple result
+// not needing a full list.
+class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
+
+//===----------------------------------------------------------------------===//
+// Complex pattern definitions.
+//
+
+// Complex patterns, e.g. X86 addressing mode, requires pattern matching code
+// in C++. NumOperands is the number of operands returned by the select function;
+// SelectFunc is the name of the function used to pattern match the max. pattern;
+// RootNodes are the list of possible root nodes of the sub-dags to match.
+// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
+//
+class ComplexPattern<ValueType ty, int numops, string fn,
+ list<SDNode> roots = [], list<SDNodeProperty> props = []> {
+ ValueType Ty = ty;
+ int NumOperands = numops;
+ string SelectFunc = fn;
+ list<SDNode> RootNodes = roots;
+ list<SDNodeProperty> Properties = props;
+}
diff --git a/contrib/llvm/include/llvm/Target/TargetSelectionDAGInfo.h b/contrib/llvm/include/llvm/Target/TargetSelectionDAGInfo.h
new file mode 100644
index 000000000000..c9ca7223b5f5
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -0,0 +1,101 @@
+//==-- llvm/Target/TargetSelectionDAGInfo.h - SelectionDAG 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 declares the TargetSelectionDAGInfo class, which targets can
+// subclass to parameterize the SelectionDAG lowering and instruction
+// selection process.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSELECTIONDAGINFO_H
+#define LLVM_TARGET_TARGETSELECTIONDAGINFO_H
+
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+namespace llvm {
+
+class TargetData;
+class TargetMachine;
+
+//===----------------------------------------------------------------------===//
+/// TargetSelectionDAGInfo - Targets can subclass this to parameterize the
+/// SelectionDAG lowering and instruction selection process.
+///
+class TargetSelectionDAGInfo {
+ TargetSelectionDAGInfo(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
+ void operator=(const TargetSelectionDAGInfo &); // DO NOT IMPLEMENT
+
+ const TargetData *TD;
+
+protected:
+ const TargetData *getTargetData() const { return TD; }
+
+public:
+ explicit TargetSelectionDAGInfo(const TargetMachine &TM);
+ virtual ~TargetSelectionDAGInfo();
+
+ /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
+ /// memcpy. This can be used by targets to provide code sequences for cases
+ /// that don't fit the target's parameters for simple loads/stores and can be
+ /// more efficient than using a library call. This function can return a null
+ /// SDValue if the target declines to use custom code and a different
+ /// lowering strategy should be used.
+ ///
+ /// If AlwaysInline is true, the size is constant and the target should not
+ /// emit any calls and is strongly encouraged to attempt to emit inline code
+ /// even if it is beyond the usual threshold because this intrinsic is being
+ /// expanded in a place where calls are not feasible (e.g. within the prologue
+ /// for another call). If the target chooses to decline an AlwaysInline
+ /// request here, legalize will resort to using simple loads and stores.
+ virtual SDValue
+ EmitTargetCodeForMemcpy(SelectionDAG &DAG, DebugLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ bool AlwaysInline,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo) const {
+ return SDValue();
+ }
+
+ /// EmitTargetCodeForMemmove - Emit target-specific code that performs a
+ /// memmove. This can be used by targets to provide code sequences for cases
+ /// that don't fit the target's parameters for simple loads/stores and can be
+ /// more efficient than using a library call. This function can return a null
+ /// SDValue if the target declines to use custom code and a different
+ /// lowering strategy should be used.
+ virtual SDValue
+ EmitTargetCodeForMemmove(SelectionDAG &DAG, DebugLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo) const {
+ return SDValue();
+ }
+
+ /// EmitTargetCodeForMemset - Emit target-specific code that performs a
+ /// memset. This can be used by targets to provide code sequences for cases
+ /// that don't fit the target's parameters for simple stores and can be more
+ /// efficient than using a library call. This function can return a null
+ /// SDValue if the target declines to use custom code and a different
+ /// lowering strategy should be used.
+ virtual SDValue
+ EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
+ SDValue Chain,
+ SDValue Op1, SDValue Op2,
+ SDValue Op3, unsigned Align, bool isVolatile,
+ MachinePointerInfo DstPtrInfo) const {
+ return SDValue();
+ }
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h b/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h
new file mode 100644
index 000000000000..fc23b2c6b58d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Target/TargetSubtargetInfo.h
@@ -0,0 +1,68 @@
+//==-- llvm/Target/TargetSubtargetInfo.h - Target Information ----*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSUBTARGETINFO_H
+#define LLVM_TARGET_TARGETSUBTARGETINFO_H
+
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/CodeGen.h"
+
+namespace llvm {
+
+class SDep;
+class SUnit;
+class TargetRegisterClass;
+template <typename T> class SmallVectorImpl;
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetSubtargetInfo - Generic base class for all target subtargets. All
+/// Target-specific options that control code generation and printing should
+/// be exposed through a TargetSubtargetInfo-derived class.
+///
+class TargetSubtargetInfo : public MCSubtargetInfo {
+ TargetSubtargetInfo(const TargetSubtargetInfo&); // DO NOT IMPLEMENT
+ void operator=(const TargetSubtargetInfo&); // DO NOT IMPLEMENT
+protected: // Can only create subclasses...
+ TargetSubtargetInfo();
+public:
+ // AntiDepBreakMode - Type of anti-dependence breaking that should
+ // be performed before post-RA scheduling.
+ typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode;
+ typedef SmallVectorImpl<const TargetRegisterClass*> RegClassVector;
+
+ 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; }
+
+ // 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.
+ 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,
+ SDep& dep) const { }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/IPO.h b/contrib/llvm/include/llvm/Transforms/IPO.h
new file mode 100644
index 000000000000..18176e8fdbb1
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/IPO.h
@@ -0,0 +1,198 @@
+//===- llvm/Transforms/IPO.h - Interprocedural Transformations --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the IPO transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_H
+#define LLVM_TRANSFORMS_IPO_H
+
+#include <vector>
+
+namespace llvm {
+
+class ModulePass;
+class Pass;
+class Function;
+class BasicBlock;
+class GlobalValue;
+
+//===----------------------------------------------------------------------===//
+//
+// These functions removes symbols from functions and modules. If OnlyDebugInfo
+// is true, only debugging information is removed from the module.
+//
+ModulePass *createStripSymbolsPass(bool OnlyDebugInfo = false);
+
+//===----------------------------------------------------------------------===//
+//
+// These functions strips symbols from functions and modules.
+// Only debugging information is not stripped.
+//
+ModulePass *createStripNonDebugSymbolsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// These pass removes llvm.dbg.declare intrinsics.
+ModulePass *createStripDebugDeclarePass();
+
+//===----------------------------------------------------------------------===//
+//
+// These pass removes unused symbols' debug info.
+ModulePass *createStripDeadDebugInfoPass();
+
+//===----------------------------------------------------------------------===//
+/// createConstantMergePass - This function returns a new pass that merges
+/// duplicate global constants together into a single constant that is shared.
+/// This is useful because some passes (ie TraceValues) insert a lot of string
+/// constants into the program, regardless of whether or not they duplicate an
+/// existing string.
+///
+ModulePass *createConstantMergePass();
+
+
+//===----------------------------------------------------------------------===//
+/// createGlobalOptimizerPass - This function returns a new pass that optimizes
+/// non-address taken internal globals.
+///
+ModulePass *createGlobalOptimizerPass();
+
+
+//===----------------------------------------------------------------------===//
+/// createGlobalDCEPass - This transform is designed to eliminate unreachable
+/// internal globals (functions or global variables)
+///
+ModulePass *createGlobalDCEPass();
+
+
+//===----------------------------------------------------------------------===//
+/// createGVExtractionPass - If deleteFn is true, this pass deletes
+/// the specified global values. Otherwise, it deletes as much of the module as
+/// possible, except for the global values specified.
+///
+ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
+ deleteFn = false);
+
+//===----------------------------------------------------------------------===//
+/// createFunctionInliningPass - Return a new pass object that uses a heuristic
+/// to inline direct function calls to small functions.
+///
+/// The -inline-threshold command line option takes precedence over the
+/// threshold given here.
+Pass *createFunctionInliningPass();
+Pass *createFunctionInliningPass(int Threshold);
+
+//===----------------------------------------------------------------------===//
+/// createAlwaysInlinerPass - Return a new pass object that inlines only
+/// functions that are marked as "always_inline".
+Pass *createAlwaysInlinerPass();
+Pass *createAlwaysInlinerPass(bool InsertLifetime);
+
+//===----------------------------------------------------------------------===//
+/// createPruneEHPass - Return a new pass object which transforms invoke
+/// instructions into calls, if the callee can _not_ unwind the stack.
+///
+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);
+
+//===----------------------------------------------------------------------===//
+/// createDeadArgEliminationPass - This pass removes arguments from functions
+/// which are not used by the body of the function.
+///
+ModulePass *createDeadArgEliminationPass();
+
+/// DeadArgHacking pass - Same as DAE, but delete arguments of external
+/// functions as well. This is definitely not safe, and should only be used by
+/// bugpoint.
+ModulePass *createDeadArgHackingPass();
+
+//===----------------------------------------------------------------------===//
+/// createArgumentPromotionPass - This pass promotes "by reference" arguments to
+/// be passed by value if the number of elements passed is smaller or
+/// equal to maxElements (maxElements == 0 means always promote).
+///
+Pass *createArgumentPromotionPass(unsigned maxElements = 3);
+
+//===----------------------------------------------------------------------===//
+/// createIPConstantPropagationPass - This pass propagates constants from call
+/// sites into the bodies of functions.
+///
+ModulePass *createIPConstantPropagationPass();
+
+//===----------------------------------------------------------------------===//
+/// createIPSCCPPass - This pass propagates constants from call sites into the
+/// bodies of functions, and keeps track of whether basic blocks are executable
+/// in the process.
+///
+ModulePass *createIPSCCPPass();
+
+//===----------------------------------------------------------------------===//
+//
+/// createLoopExtractorPass - This pass extracts all natural loops from the
+/// program into a function if it can.
+///
+Pass *createLoopExtractorPass();
+
+/// createSingleLoopExtractorPass - This pass extracts one natural loop from the
+/// program into a function if it can. This is used by bugpoint.
+///
+Pass *createSingleLoopExtractorPass();
+
+/// createBlockExtractorPass - This pass extracts all blocks (except those
+/// specified in the argument list) from the functions in the module.
+///
+ModulePass *createBlockExtractorPass();
+
+/// createStripDeadPrototypesPass - This pass removes any function declarations
+/// (prototypes) that are not used.
+ModulePass *createStripDeadPrototypesPass();
+
+//===----------------------------------------------------------------------===//
+/// createFunctionAttrsPass - This pass discovers functions that do not access
+/// memory, or only read memory, and gives them the readnone/readonly attribute.
+/// It also discovers function arguments that are not captured by the function
+/// and marks them with the nocapture attribute.
+///
+Pass *createFunctionAttrsPass();
+
+//===----------------------------------------------------------------------===//
+/// createMergeFunctionsPass - This pass discovers identical functions and
+/// collapses them.
+///
+ModulePass *createMergeFunctionsPass();
+
+//===----------------------------------------------------------------------===//
+/// createPartialInliningPass - This pass inlines parts of functions.
+///
+ModulePass *createPartialInliningPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h b/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h
new file mode 100644
index 000000000000..7c3cfc870156
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/IPO/InlinerPass.h
@@ -0,0 +1,90 @@
+//===- InlinerPass.h - Code common to all inliners --------------*- 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 simple policy-based bottom-up inliner. This file
+// implements all of the boring mechanics of the bottom-up inlining, while the
+// subclass determines WHAT to inline, which is the much more interesting
+// component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_INLINERPASS_H
+#define LLVM_TRANSFORMS_IPO_INLINERPASS_H
+
+#include "llvm/CallGraphSCCPass.h"
+
+namespace llvm {
+ class CallSite;
+ class TargetData;
+ class InlineCost;
+ template<class PtrType, unsigned SmallSize>
+ class SmallPtrSet;
+
+/// Inliner - This class contains all of the helper code which is used to
+/// perform the inlining operations that do not depend on the policy.
+///
+struct Inliner : public CallGraphSCCPass {
+ explicit Inliner(char &ID);
+ explicit Inliner(char &ID, int Threshold, bool InsertLifetime);
+
+ /// getAnalysisUsage - For this class, we declare that we require and preserve
+ /// the call graph. If the derived class implements this method, it should
+ /// always explicitly call the implementation here.
+ virtual void getAnalysisUsage(AnalysisUsage &Info) const;
+
+ // Main run interface method, this implements the interface required by the
+ // Pass class.
+ virtual bool runOnSCC(CallGraphSCC &SCC);
+
+ // doFinalization - Remove now-dead linkonce functions at the end of
+ // processing to avoid breaking the SCC traversal.
+ virtual bool doFinalization(CallGraph &CG);
+
+ /// This method returns the value specified by the -inline-threshold value,
+ /// specified on the command line. This is typically not directly needed.
+ ///
+ unsigned getInlineThreshold() const { return InlineThreshold; }
+
+ /// Calculate the inline threshold for given Caller. This threshold is lower
+ /// if the caller is marked with OptimizeForSize and -inline-threshold is not
+ /// given on the comand line. It is higher if the callee is marked with the
+ /// inlinehint attribute.
+ ///
+ unsigned getInlineThreshold(CallSite CS) const;
+
+ /// getInlineCost - This method must be implemented by the subclass to
+ /// determine the cost of inlining the specified call site. If the cost
+ /// returned is greater than the current inline threshold, the call site is
+ /// not inlined.
+ ///
+ virtual InlineCost getInlineCost(CallSite CS) = 0;
+
+ /// removeDeadFunctions - Remove dead functions.
+ ///
+ /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag
+ /// which restricts it to deleting functions with an 'AlwaysInline'
+ /// attribute. This is useful for the InlineAlways pass that only wants to
+ /// deal with that subset of the functions.
+ bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false);
+
+private:
+ // InlineThreshold - Cache the value here for easy access.
+ unsigned InlineThreshold;
+
+ // InsertLifetime - Insert @llvm.lifetime intrinsics.
+ bool InsertLifetime;
+
+ /// shouldInline - Return true if the inliner should attempt to
+ /// inline at the given CallSite.
+ bool shouldInline(CallSite CS);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h b/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
new file mode 100644
index 000000000000..47ce90265bd5
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -0,0 +1,149 @@
+// llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- 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 PassManagerBuilder class, which is used to set up a
+// "standard" optimization sequence suitable for languages like C and C++.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H
+#define LLVM_SUPPORT_PASSMANAGERBUILDER_H
+
+#include <vector>
+
+namespace llvm {
+ class TargetLibraryInfo;
+ class PassManagerBase;
+ class Pass;
+ class FunctionPassManager;
+
+/// PassManagerBuilder - This class is used to set up a standard optimization
+/// sequence for languages like C and C++, allowing some APIs to customize the
+/// pass sequence in various ways. A simple example of using it would be:
+///
+/// PassManagerBuilder Builder;
+/// Builder.OptLevel = 2;
+/// Builder.populateFunctionPassManager(FPM);
+/// Builder.populateModulePassManager(MPM);
+///
+/// In addition to setting up the basic passes, PassManagerBuilder allows
+/// frontends to vend a plugin API, where plugins are allowed to add extensions
+/// to the default pass manager. They do this by specifying where in the pass
+/// pipeline they want to be added, along with a callback function that adds
+/// the pass(es). For example, a plugin that wanted to add a loop optimization
+/// could do something like this:
+///
+/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) {
+/// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0)
+/// PM.add(createMyAwesomePass());
+/// }
+/// ...
+/// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd,
+/// addMyLoopPass);
+/// ...
+class PassManagerBuilder {
+public:
+
+ /// Extensions are passed the builder itself (so they can see how it is
+ /// configured) as well as the pass manager to add stuff to.
+ typedef void (*ExtensionFn)(const PassManagerBuilder &Builder,
+ PassManagerBase &PM);
+ enum ExtensionPointTy {
+ /// EP_EarlyAsPossible - This extension point allows adding passes before
+ /// any other transformations, allowing them to see the code as it is coming
+ /// out of the frontend.
+ EP_EarlyAsPossible,
+
+ /// EP_ModuleOptimizerEarly - This extension point allows adding passes
+ /// just before the main module-level optimization passes.
+ EP_ModuleOptimizerEarly,
+
+ /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
+ /// the end of the loop optimizer.
+ EP_LoopOptimizerEnd,
+
+ /// EP_ScalarOptimizerLate - This extension point allows adding optimization
+ /// passes after most of the main optimizations, but before the last
+ /// cleanup-ish optimizations.
+ EP_ScalarOptimizerLate,
+
+ /// EP_OptimizerLast -- This extension point allows adding passes that
+ /// run after everything else.
+ EP_OptimizerLast,
+
+ /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
+ /// should not be disabled by O0 optimization level. The passes will be
+ /// inserted after the inlining pass.
+ EP_EnabledOnOptLevel0
+ };
+
+ /// The Optimization Level - Specify the basic optimization level.
+ /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
+ unsigned OptLevel;
+
+ /// SizeLevel - How much we're optimizing for size.
+ /// 0 = none, 1 = -Os, 2 = -Oz
+ unsigned SizeLevel;
+
+ /// LibraryInfo - Specifies information about the runtime library for the
+ /// optimizer. If this is non-null, it is added to both the function and
+ /// per-module pass pipeline.
+ TargetLibraryInfo *LibraryInfo;
+
+ /// Inliner - Specifies the inliner to use. If this is non-null, it is
+ /// added to the per-module passes.
+ Pass *Inliner;
+
+ bool DisableSimplifyLibCalls;
+ bool DisableUnitAtATime;
+ bool DisableUnrollLoops;
+ bool Vectorize;
+
+private:
+ /// ExtensionList - This is list of all of the extensions that are registered.
+ std::vector<std::pair<ExtensionPointTy, ExtensionFn> > Extensions;
+
+public:
+ PassManagerBuilder();
+ ~PassManagerBuilder();
+ /// Adds an extension that will be used by all PassManagerBuilder instances.
+ /// This is intended to be used by plugins, to register a set of
+ /// optimisations to run automatically.
+ static void addGlobalExtension(ExtensionPointTy Ty, ExtensionFn Fn);
+ void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);
+
+private:
+ void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const;
+ void addInitialAliasAnalysisPasses(PassManagerBase &PM) const;
+public:
+
+ /// populateFunctionPassManager - This fills in the function pass manager,
+ /// which is expected to be run on each function immediately as it is
+ /// generated. The idea is to reduce the size of the IR in memory.
+ void populateFunctionPassManager(FunctionPassManager &FPM);
+
+ /// populateModulePassManager - This sets up the primary pass manager.
+ void populateModulePassManager(PassManagerBase &MPM);
+ void populateLTOPassManager(PassManagerBase &PM, bool Internalize,
+ bool RunInliner, bool DisableGVNLoadPRE = false);
+};
+
+/// Registers a function for adding a standard set of passes. This should be
+/// used by optimizer plugins to allow all front ends to transparently use
+/// them. Create a static instance of this class in your plugin, providing a
+/// private function that the PassManagerBuilder can use to add your passes.
+struct RegisterStandardPasses {
+ RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
+ PassManagerBuilder::ExtensionFn Fn) {
+ PassManagerBuilder::addGlobalExtension(Ty, Fn);
+ }
+};
+
+} // end namespace llvm
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Instrumentation.h b/contrib/llvm/include/llvm/Transforms/Instrumentation.h
new file mode 100644
index 000000000000..bbf3a69d246d
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Instrumentation.h
@@ -0,0 +1,43 @@
+//===- Transforms/Instrumentation.h - Instrumentation passes ----*- 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 constructor functions for instrumentation passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_H
+
+namespace llvm {
+
+class ModulePass;
+class FunctionPass;
+
+// Insert edge profiling instrumentation
+ModulePass *createEdgeProfilerPass();
+
+// Insert optimal edge profiling instrumentation
+ModulePass *createOptimalEdgeProfilerPass();
+
+// Insert path profiling instrumentation
+ModulePass *createPathProfilerPass();
+
+// Insert GCOV profiling instrumentation
+ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
+ bool Use402Format = false,
+ bool UseExtraChecksum = false);
+
+// Insert AddressSanitizer (address sanity checking) instrumentation
+ModulePass *createAddressSanitizerPass();
+// Insert ThreadSanitizer (race detection) instrumentation
+FunctionPass *createThreadSanitizerPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Scalar.h b/contrib/llvm/include/llvm/Transforms/Scalar.h
new file mode 100644
index 000000000000..7f055d446171
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Scalar.h
@@ -0,0 +1,369 @@
+//===-- Scalar.h - Scalar Transformations -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the Scalar transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_H
+#define LLVM_TRANSFORMS_SCALAR_H
+
+namespace llvm {
+
+class FunctionPass;
+class Pass;
+class GetElementPtrInst;
+class PassInfo;
+class TerminatorInst;
+class TargetLowering;
+
+//===----------------------------------------------------------------------===//
+//
+// ConstantPropagation - A worklist driven constant propagation pass
+//
+FunctionPass *createConstantPropagationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SCCP - Sparse conditional constant propagation.
+//
+FunctionPass *createSCCPPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadInstElimination - This pass quickly removes trivially dead instructions
+// without modifying the CFG of the function. It is a BasicBlockPass, so it
+// runs efficiently when queued next to other BasicBlockPass's.
+//
+Pass *createDeadInstEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadCodeElimination - This pass is more powerful than DeadInstElimination,
+// because it is worklist driven that can potentially revisit instructions when
+// their other instructions become dead, to eliminate chains of dead
+// computations.
+//
+FunctionPass *createDeadCodeEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadStoreElimination - This pass deletes stores that are post-dominated by
+// must-aliased stores and are not loaded used between the stores.
+//
+FunctionPass *createDeadStoreEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// AggressiveDCE - This pass uses the SSA based Aggressive DCE algorithm. This
+// algorithm assumes instructions are dead until proven otherwise, which makes
+// it more successful are removing non-obviously dead instructions.
+//
+FunctionPass *createAggressiveDCEPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ScalarReplAggregates - Break up alloca's of aggregates into multiple allocas
+// if possible.
+//
+FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1,
+ bool UseDomTree = true);
+
+//===----------------------------------------------------------------------===//
+//
+// InductionVariableSimplify - Transform induction variables in a program to all
+// use a single canonical induction variable per loop.
+//
+Pass *createIndVarSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionCombining - Combine instructions to form fewer, simple
+// instructions. This pass does not modify the CFG, and has a tendency to make
+// instructions dead, so a subsequent DCE pass is useful.
+//
+// This pass combines things like:
+// %Y = add int 1, %X
+// %Z = add int 1, %Y
+// into:
+// %Z = add int 2, %X
+//
+FunctionPass *createInstructionCombiningPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LICM - This pass is a loop invariant code motion and memory promotion pass.
+//
+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.
+//
+Pass *createLoopStrengthReducePass(const TargetLowering *TLI = 0);
+
+Pass *createGlobalMergePass(const TargetLowering *TLI = 0);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopUnswitch - This pass is a simple loop unswitching pass.
+//
+Pass *createLoopUnswitchPass(bool OptimizeForSize = false);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopInstSimplify - This pass simplifies instructions in a loop's body.
+//
+Pass *createLoopInstSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopUnroll - This pass is a simple loop unrolling pass.
+//
+Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1, int AllowPartial = -1);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopRotate - This pass is a simple loop rotating pass.
+//
+Pass *createLoopRotatePass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopIdiom - This pass recognizes and replaces idioms in loops.
+//
+Pass *createLoopIdiomPass();
+
+//===----------------------------------------------------------------------===//
+//
+// PromoteMemoryToRegister - This pass is used to promote memory references to
+// be register references. A simple example of the transformation performed by
+// this pass is:
+//
+// FROM CODE TO CODE
+// %X = alloca i32, i32 1 ret i32 42
+// store i32 42, i32 *%X
+// %Y = load i32* %X
+// ret i32 %Y
+//
+FunctionPass *createPromoteMemoryToRegisterPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DemoteRegisterToMemoryPass - This pass is used to demote registers to memory
+// references. In basically undoes the PromoteMemoryToRegister pass to make cfg
+// hacking easier.
+//
+FunctionPass *createDemoteRegisterToMemoryPass();
+extern char &DemoteRegisterToMemoryID;
+
+//===----------------------------------------------------------------------===//
+//
+// Reassociate - This pass reassociates commutative expressions in an order that
+// is designed to promote better constant propagation, GCSE, LICM, PRE...
+//
+// For example: 4 + (x + 5) -> x + (4 + 5)
+//
+FunctionPass *createReassociatePass();
+
+//===----------------------------------------------------------------------===//
+//
+// JumpThreading - Thread control through mult-pred/multi-succ blocks where some
+// preds always go to some succ.
+//
+FunctionPass *createJumpThreadingPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
+// simplify terminator instructions, etc...
+//
+FunctionPass *createCFGSimplificationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// BreakCriticalEdges - Break all of the critical edges in the CFG by inserting
+// a dummy basic block. This pass may be "required" by passes that cannot deal
+// with critical edges. For this usage, a pass must call:
+//
+// AU.addRequiredID(BreakCriticalEdgesID);
+//
+// This pass obviously invalidates the CFG, but can update forward dominator
+// (set, immediate dominators, tree, and frontier) information.
+//
+FunctionPass *createBreakCriticalEdgesPass();
+extern char &BreakCriticalEdgesID;
+
+//===----------------------------------------------------------------------===//
+//
+// LoopSimplify - Insert Pre-header blocks into the CFG for every function in
+// the module. This pass updates dominator information, loop information, and
+// does not add critical edges to the CFG.
+//
+// AU.addRequiredID(LoopSimplifyID);
+//
+Pass *createLoopSimplifyPass();
+extern char &LoopSimplifyID;
+
+//===----------------------------------------------------------------------===//
+//
+// TailCallElimination - This pass eliminates call instructions to the current
+// function which occur immediately before return instructions.
+//
+FunctionPass *createTailCallEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerSwitch - This pass converts SwitchInst instructions into a sequence of
+// chained binary branch instructions.
+//
+FunctionPass *createLowerSwitchPass();
+extern char &LowerSwitchID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerInvoke - This pass converts invoke and unwind instructions to use sjlj
+// exception handling mechanisms. Note that after this pass runs the CFG is not
+// entirely accurate (exceptional control flow edges are not correct anymore) so
+// only very simple things should be done after the lowerinvoke pass has run
+// (like generation of native code). This should *NOT* be used as a general
+// purpose "my LLVM-to-LLVM pass doesn't support the invoke instruction yet"
+// lowering pass.
+//
+FunctionPass *createLowerInvokePass(const TargetLowering *TLI = 0);
+FunctionPass *createLowerInvokePass(const TargetLowering *TLI,
+ bool useExpensiveEHSupport);
+extern char &LowerInvokePassID;
+
+//===----------------------------------------------------------------------===//
+//
+// BlockPlacement - This pass reorders basic blocks in order to increase the
+// number of fall-through conditional branches.
+//
+FunctionPass *createBlockPlacementPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LCSSA - This pass inserts phi nodes at loop boundaries to simplify other loop
+// optimizations.
+//
+Pass *createLCSSAPass();
+extern char &LCSSAID;
+
+//===----------------------------------------------------------------------===//
+//
+// EarlyCSE - This pass performs a simple and fast CSE pass over the dominator
+// tree.
+//
+FunctionPass *createEarlyCSEPass();
+
+//===----------------------------------------------------------------------===//
+//
+// GVN - This pass performs global value numbering and redundant load
+// elimination cotemporaneously.
+//
+FunctionPass *createGVNPass(bool NoLoads = false);
+
+//===----------------------------------------------------------------------===//
+//
+// MemCpyOpt - This pass performs optimizations related to eliminating memcpy
+// calls and/or combining multiple stores into memset's.
+//
+FunctionPass *createMemCpyOptPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopDeletion - This pass performs DCE of non-infinite loops that it
+// can prove are dead.
+//
+Pass *createLoopDeletionPass();
+
+//===----------------------------------------------------------------------===//
+//
+/// createSimplifyLibCallsPass - This pass optimizes specific calls to
+/// specific well-known (library) functions.
+FunctionPass *createSimplifyLibCallsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CodeGenPrepare - This pass prepares a function for instruction selection.
+//
+FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0);
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionNamer - Give any unnamed non-void instructions "tmp" names.
+//
+FunctionPass *createInstructionNamerPass();
+extern char &InstructionNamerID;
+
+//===----------------------------------------------------------------------===//
+//
+// Sink - Code Sinking
+//
+FunctionPass *createSinkingPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerAtomic - Lower atomic intrinsics to non-atomic form
+//
+Pass *createLowerAtomicPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ValuePropagation - Propagate CFG-derived value information
+//
+Pass *createCorrelatedValuePropagationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCAPElim - ObjC ARC autorelease pool elimination.
+//
+Pass *createObjCARCAPElimPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCExpand - ObjC ARC preliminary simplifications.
+//
+Pass *createObjCARCExpandPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCContract - Late ObjC ARC cleanups.
+//
+Pass *createObjCARCContractPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCOpt - ObjC ARC optimization.
+//
+Pass *createObjCARCOptPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionSimplifier - Remove redundant instructions.
+//
+FunctionPass *createInstructionSimplifierPass();
+extern char &InstructionSimplifierID;
+
+
+//===----------------------------------------------------------------------===//
+//
+// LowerExpectIntriniscs - Removes llvm.expect intrinsics and creates
+// "block_weights" metadata.
+FunctionPass *createLowerExpectIntrinsicPass();
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h b/contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h
new file mode 100644
index 000000000000..90485eb4c69c
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/AddrModeMatcher.h
@@ -0,0 +1,108 @@
+//===- 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/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
new file mode 100644
index 000000000000..2f9dc54541b9
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -0,0 +1,211 @@
+//===-- Transform/Utils/BasicBlockUtils.h - BasicBlock Utils ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform manipulations on basic blocks, and
+// instructions contained within basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCK_H
+#define LLVM_TRANSFORMS_UTILS_BASICBLOCK_H
+
+// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/DebugLoc.h"
+
+namespace llvm {
+
+class AliasAnalysis;
+class Instruction;
+class Pass;
+class ReturnInst;
+
+/// DeleteDeadBlock - Delete the specified block, which must have no
+/// predecessors.
+void DeleteDeadBlock(BasicBlock *BB);
+
+
+/// FoldSingleEntryPHINodes - We know that BB has one predecessor. If there are
+/// any single-entry PHI nodes in it, fold them away. This handles the case
+/// when all entries to the PHI nodes in a block are guaranteed equal, such as
+/// when the block has exactly one predecessor.
+void FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P = 0);
+
+/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
+/// is dead. Also recursively delete any operands that become dead as
+/// a result. This includes tracing the def-use list from the PHI to see if
+/// it is ultimately unused or if it reaches an unused cycle. Return true
+/// if any PHIs were deleted.
+bool DeleteDeadPHIs(BasicBlock *BB);
+
+/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
+/// if possible. The return value indicates success or failure.
+bool MergeBlockIntoPredecessor(BasicBlock *BB, Pass *P = 0);
+
+// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
+// with a value, then remove and delete the original instruction.
+//
+void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
+ BasicBlock::iterator &BI, Value *V);
+
+// ReplaceInstWithInst - Replace the instruction specified by BI with the
+// instruction specified by I. The original instruction is deleted and BI is
+// updated to point to the new instruction.
+//
+void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
+ BasicBlock::iterator &BI, Instruction *I);
+
+// ReplaceInstWithInst - Replace the instruction specified by From with the
+// instruction specified by To.
+//
+void ReplaceInstWithInst(Instruction *From, Instruction *To);
+
+/// FindFunctionBackedges - Analyze the specified function to find all of the
+/// loop backedges in the function and return them. This is a relatively cheap
+/// (compared to computing dominators and loop info) analysis.
+///
+/// The output is added to Result, as pairs of <from,to> edge info.
+void FindFunctionBackedges(const Function &F,
+ SmallVectorImpl<std::pair<const BasicBlock*,const BasicBlock*> > &Result);
+
+
+/// GetSuccessorNumber - Search for the specified successor of basic block BB
+/// and return its position in the terminator instruction's list of
+/// successors. It is an error to call this with a block that is not a
+/// successor.
+unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ);
+
+/// isCriticalEdge - Return true if the specified edge is a critical edge.
+/// Critical edges are edges from a block with multiple successors to a block
+/// with multiple predecessors.
+///
+bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
+ bool AllowIdenticalEdges = false);
+
+/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
+/// split the critical edge. This will update DominatorTree and
+/// DominatorFrontier information if it is available, thus calling this pass
+/// will not invalidate either of them. This returns the new block if the edge
+/// was split, null otherwise.
+///
+/// If MergeIdenticalEdges is true (not the default), *all* edges from TI to the
+/// specified successor will be merged into the same critical edge block.
+/// This is most commonly interesting with switch instructions, which may
+/// have many edges to any one destination. This ensures that all edges to that
+/// dest go to one block instead of each going to a different block, but isn't
+/// the standard definition of a "critical edge".
+///
+/// It is invalid to call this function on a critical edge that starts at an
+/// IndirectBrInst. Splitting these edges will almost always create an invalid
+/// program because the address of the new block won't be the one that is jumped
+/// to.
+///
+BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum,
+ Pass *P = 0, bool MergeIdenticalEdges = false,
+ bool DontDeleteUselessPHIs = false,
+ bool SplitLandingPads = false);
+
+inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI,
+ Pass *P = 0) {
+ return SplitCriticalEdge(BB->getTerminator(), SI.getSuccessorIndex(), P);
+}
+
+/// SplitCriticalEdge - If the edge from *PI to BB is not critical, return
+/// false. Otherwise, split all edges between the two blocks and return true.
+/// This updates all of the same analyses as the other SplitCriticalEdge
+/// function. If P is specified, it updates the analyses
+/// described above.
+inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI, Pass *P = 0) {
+ bool MadeChange = false;
+ TerminatorInst *TI = (*PI)->getTerminator();
+ for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
+ if (TI->getSuccessor(i) == Succ)
+ MadeChange |= !!SplitCriticalEdge(TI, i, P);
+ return MadeChange;
+}
+
+/// SplitCriticalEdge - If an edge from Src to Dst is critical, split the edge
+/// and return true, otherwise return false. This method requires that there be
+/// an edge between the two blocks. If P is specified, it updates the analyses
+/// described above.
+inline BasicBlock *SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst,
+ Pass *P = 0,
+ bool MergeIdenticalEdges = false,
+ bool DontDeleteUselessPHIs = false) {
+ TerminatorInst *TI = Src->getTerminator();
+ unsigned i = 0;
+ while (1) {
+ assert(i != TI->getNumSuccessors() && "Edge doesn't exist!");
+ if (TI->getSuccessor(i) == Dst)
+ return SplitCriticalEdge(TI, i, P, MergeIdenticalEdges,
+ DontDeleteUselessPHIs);
+ ++i;
+ }
+}
+
+/// SplitEdge - Split the edge connecting specified block. Pass P must
+/// not be NULL.
+BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, Pass *P);
+
+/// SplitBlock - Split the specified block at the specified instruction - every
+/// thing before SplitPt stays in Old and everything starting with SplitPt moves
+/// to a new block. The two blocks are joined by an unconditional branch and
+/// the loop info is updated.
+///
+BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P);
+
+/// SplitBlockPredecessors - This method transforms BB by introducing a new
+/// basic block into the function, and moving some of the predecessors of BB to
+/// be predecessors of the new block. The new predecessors are indicated by the
+/// Preds array, which has NumPreds elements in it. The new block is given a
+/// suffix of 'Suffix'. This function returns the new block.
+///
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
+/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses.
+/// In particular, it does not preserve LoopSimplify (because it's
+/// complicated to handle the case where one of the edges being split
+/// is an exit of a loop with other exits).
+///
+BasicBlock *SplitBlockPredecessors(BasicBlock *BB, ArrayRef<BasicBlock*> Preds,
+ const char *Suffix, Pass *P = 0);
+
+/// SplitLandingPadPredecessors - This method transforms the landing pad,
+/// OrigBB, by introducing two new basic blocks into the function. One of those
+/// new basic blocks gets the predecessors listed in Preds. The other basic
+/// block gets the remaining predecessors of OrigBB. The landingpad instruction
+/// OrigBB is clone into both of the new basic blocks. The new blocks are given
+/// the suffixes 'Suffix1' and 'Suffix2', and are returned in the NewBBs vector.
+///
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
+/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. In particular,
+/// it does not preserve LoopSimplify (because it's complicated to handle the
+/// case where one of the edges being split is an exit of a loop with other
+/// exits).
+///
+void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef<BasicBlock*> Preds,
+ const char *Suffix, const char *Suffix2,
+ Pass *P, SmallVectorImpl<BasicBlock*> &NewBBs);
+
+/// FoldReturnIntoUncondBranch - This method duplicates the specified return
+/// instruction into a predecessor which ends in an unconditional branch. If
+/// the return instruction returns a value defined by a PHI, propagate the
+/// right value into the return. It returns the new return instruction in the
+/// predecessor.
+ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
+ BasicBlock *Pred);
+
+/// GetFirstDebugLocInBasicBlock - Return first valid DebugLoc entry in a
+/// given basic block.
+DebugLoc GetFirstDebugLocInBasicBlock(const BasicBlock *BB);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
new file mode 100644
index 000000000000..17cd58eb014e
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -0,0 +1,112 @@
+//===- BuildLibCalls.h - Utility builder for libcalls -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to build some C language libcalls for
+// optimization passes that need to call the various functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H
+#define TRANSFORMS_UTILS_BUILDLIBCALLS_H
+
+#include "llvm/Support/IRBuilder.h"
+
+namespace llvm {
+ class Value;
+ class TargetData;
+ class TargetLibraryInfo;
+
+ /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
+ Value *CastToCStr(Value *V, IRBuilder<> &B);
+
+ /// EmitStrLen - Emit a call to the strlen function to the builder, for the
+ /// specified pointer. Ptr is required to be some pointer type, and the
+ /// return value has 'intptr_t' type.
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitStrChr - Emit a call to the strchr function to the builder, for the
+ /// specified pointer and character. Ptr is required to be some pointer type,
+ /// and the return value has 'i8*' type.
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitStrNCmp - Emit a call to the strncmp function to the builder.
+ Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
+ /// specified pointer arguments.
+ Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
+ const TargetData *TD, 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, 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);
+
+ /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
+ /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
+ Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitMemCmp - Emit a call to the memcmp function.
+ Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
+ /// (e.g. 'floor'). This function is known to take a single of type matching
+ /// 'Op' and returns one value with the same type. If 'Op' is a long double,
+ /// 'l' is added as the suffix of name, if 'Op' is a float, we add a 'f'
+ /// suffix.
+ Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
+ const AttrListPtr &Attrs);
+
+ /// EmitPutChar - Emit a call to the putchar function. This assumes that Char
+ /// is an integer.
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitPutS - Emit a call to the puts function. This assumes that Str is
+ /// some pointer.
+ void EmitPutS(Value *Str, IRBuilder<> &B, const TargetData *TD);
+
+ /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
+ /// an i32, and File is a pointer to FILE.
+ void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
+ const TargetData *TD);
+
+ /// EmitFPutS - Emit a call to the puts function. Str is required to be a
+ /// pointer and File is a pointer to FILE.
+ void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const TargetData *TD,
+ 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.
+ void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
+ const TargetData *TD, const TargetLibraryInfo *TLI);
+
+ /// SimplifyFortifiedLibCalls - Helper class for folding checked library
+ /// calls (e.g. __strcpy_chk) into their unchecked counterparts.
+ class SimplifyFortifiedLibCalls {
+ protected:
+ CallInst *CI;
+ virtual void replaceCall(Value *With) = 0;
+ virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp,
+ bool isString) const = 0;
+ public:
+ virtual ~SimplifyFortifiedLibCalls();
+ bool fold(CallInst *CI, const TargetData *TD);
+ };
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h b/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h
new file mode 100644
index 000000000000..b7b5d29b320f
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -0,0 +1,206 @@
+//===- Cloning.h - Clone various parts of LLVM programs ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various functions that are used to clone chunks of LLVM
+// code for various purposes. This varies from copying whole modules into new
+// modules, to cloning functions with different arguments, to inlining
+// functions, to copying basic blocks to support loop unrolling or superblock
+// formation, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Support/ValueHandle.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+
+namespace llvm {
+
+class Module;
+class Function;
+class Instruction;
+class Pass;
+class LPPassManager;
+class BasicBlock;
+class Value;
+class CallInst;
+class InvokeInst;
+class ReturnInst;
+class CallSite;
+class Trace;
+class CallGraph;
+class TargetData;
+class Loop;
+class LoopInfo;
+class AllocaInst;
+
+/// CloneModule - Return an exact copy of the specified module
+///
+Module *CloneModule(const Module *M);
+Module *CloneModule(const Module *M, ValueToValueMapTy &VMap);
+
+/// ClonedCodeInfo - This struct can be used to capture information about code
+/// being cloned, while it is being cloned.
+struct ClonedCodeInfo {
+ /// ContainsCalls - This is set to true if the cloned code contains a normal
+ /// call instruction.
+ bool ContainsCalls;
+
+ /// ContainsDynamicAllocas - This is set to true if the cloned code contains
+ /// a 'dynamic' alloca. Dynamic allocas are allocas that are either not in
+ /// the entry block or they are in the entry block but are not a constant
+ /// size.
+ bool ContainsDynamicAllocas;
+
+ ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {}
+};
+
+
+/// CloneBasicBlock - Return a copy of the specified basic block, but without
+/// embedding the block into a particular function. The block returned is an
+/// exact copy of the specified basic block, without any remapping having been
+/// performed. Because of this, this is only suitable for applications where
+/// the basic block will be inserted into the same function that it was cloned
+/// from (loop unrolling would use this, for example).
+///
+/// Also, note that this function makes a direct copy of the basic block, and
+/// can thus produce illegal LLVM code. In particular, it will copy any PHI
+/// nodes from the original block, even though there are no predecessors for the
+/// newly cloned block (thus, phi nodes will have to be updated). Also, this
+/// block will branch to the old successors of the original block: these
+/// successors will have to have any PHI nodes updated to account for the new
+/// incoming edges.
+///
+/// The correlation between instructions in the source and result basic blocks
+/// is recorded in the VMap map.
+///
+/// If you have a particular suffix you'd like to use to add to any cloned
+/// names, specify it as the optional third parameter.
+///
+/// If you would like the basic block to be auto-inserted into the end of a
+/// function, you can specify it as the optional fourth parameter.
+///
+/// If you would like to collect additional information about the cloned
+/// function, you can specify a ClonedCodeInfo object with the optional fifth
+/// parameter.
+///
+BasicBlock *CloneBasicBlock(const BasicBlock *BB,
+ ValueToValueMapTy &VMap,
+ const Twine &NameSuffix = "", Function *F = 0,
+ ClonedCodeInfo *CodeInfo = 0);
+
+/// CloneFunction - Return a copy of the specified function, but without
+/// embedding the function into another module. Also, any references specified
+/// in the VMap are changed to refer to their mapped value instead of the
+/// original one. If any of the arguments to the function are in the VMap,
+/// the arguments are deleted from the resultant function. The VMap is
+/// updated to include mappings from all of the instructions and basicblocks in
+/// the function from their old to new values. The final argument captures
+/// information about the cloned code if non-null.
+///
+/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
+/// mappings.
+///
+Function *CloneFunction(const Function *F,
+ ValueToValueMapTy &VMap,
+ 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
+/// fills in a list of return instructions, and can optionally remap types
+/// and/or append the specified suffix to all values cloned.
+///
+/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
+/// mappings.
+///
+void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap,
+ bool ModuleLevelChanges,
+ SmallVectorImpl<ReturnInst*> &Returns,
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = 0,
+ ValueMapTypeRemapper *TypeMapper = 0);
+
+/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
+/// except that it does some simple constant prop and DCE on the fly. The
+/// effect of this is to copy significantly less code in cases where (for
+/// example) a function call with constant arguments is inlined, and those
+/// constant arguments cause a significant amount of code in the callee to be
+/// dead. Since this doesn't produce an exactly copy of the input, it can't be
+/// used for things like CloneFunction or CloneModule.
+///
+/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
+/// mappings.
+///
+void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
+ ValueToValueMapTy &VMap,
+ bool ModuleLevelChanges,
+ SmallVectorImpl<ReturnInst*> &Returns,
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = 0,
+ const TargetData *TD = 0,
+ Instruction *TheCall = 0);
+
+
+/// InlineFunctionInfo - This class captures the data input to the
+/// InlineFunction call, and records the auxiliary results produced by it.
+class InlineFunctionInfo {
+public:
+ explicit InlineFunctionInfo(CallGraph *cg = 0, const TargetData *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;
+
+ /// StaticAllocas - InlineFunction fills this in with all static allocas that
+ /// get copied into the caller.
+ SmallVector<AllocaInst*, 4> StaticAllocas;
+
+ /// InlinedCalls - InlineFunction fills this in with callsites that were
+ /// inlined from the callee. This is only filled in if CG is non-null.
+ SmallVector<WeakVH, 8> InlinedCalls;
+
+ void reset() {
+ StaticAllocas.clear();
+ InlinedCalls.clear();
+ }
+};
+
+/// InlineFunction - This function inlines the called function into the basic
+/// block of the caller. This returns false if it is not possible to inline
+/// this call. The program is still in a well defined state if this occurs
+/// though.
+///
+/// Note that this only does one level of inlining. For example, if the
+/// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
+/// exists in the instruction stream. Similarly this will inline a recursive
+/// function by one level.
+///
+bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, bool InsertLifetime = true);
+bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, bool InsertLifetime = true);
+bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, bool InsertLifetime = true);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h
new file mode 100644
index 000000000000..7ad7bddce503
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h
@@ -0,0 +1,66 @@
+//===-- CmpInstAnalysis.h - Utils to help fold compare insts ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file holds routines to help analyse compare instructions
+// and fold them into constants or other compare instructions
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
+#define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
+
+#include "llvm/InstrTypes.h"
+
+namespace llvm {
+ class ICmpInst;
+ class Value;
+
+ /// getICmpCode - Encode a icmp predicate into a three bit mask. These bits
+ /// are carefully arranged to allow folding of expressions such as:
+ ///
+ /// (A < B) | (A > B) --> (A != B)
+ ///
+ /// Note that this is only valid if the first and second predicates have the
+ /// same sign. Is illegal to do: (A u< B) | (A s> B)
+ ///
+ /// Three bits are used to represent the condition, as follows:
+ /// 0 A > B
+ /// 1 A == B
+ /// 2 A < B
+ ///
+ /// <=> Value Definition
+ /// 000 0 Always false
+ /// 001 1 A > B
+ /// 010 2 A == B
+ /// 011 3 A >= B
+ /// 100 4 A < B
+ /// 101 5 A != B
+ /// 110 6 A <= B
+ /// 111 7 Always true
+ ///
+ unsigned getICmpCode(const ICmpInst *ICI, bool InvertPred = false);
+
+ /// getICmpValue - This is the complement of getICmpCode, which turns an
+ /// opcode and two operands into either a constant true or false, or the
+ /// predicate for a new ICmp instruction. The sign is passed in to determine
+ /// which kind of predicate to use in the new icmp instruction.
+ /// Non-NULL return value will be a true or false constant.
+ /// NULL return means a new ICmp is needed. The predicate for which is
+ /// output in NewICmpPred.
+ Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
+ CmpInst::Predicate &NewICmpPred);
+
+ /// PredicatesFoldable - Return true if both predicates match sign or if at
+ /// least one of them is an equality comparison (which is signless).
+ bool PredicatesFoldable(CmpInst::Predicate p1, CmpInst::Predicate p2);
+
+} // end namespace llvm
+
+#endif
+
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/FunctionUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/FunctionUtils.h
new file mode 100644
index 000000000000..8d71e43aa921
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/FunctionUtils.h
@@ -0,0 +1,45 @@
+//===-- Transform/Utils/FunctionUtils.h - Function Utils --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of transformations manipulate LLVM functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_FUNCTION_H
+#define LLVM_TRANSFORMS_UTILS_FUNCTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include <vector>
+
+namespace llvm {
+ class BasicBlock;
+ class DominatorTree;
+ class Function;
+ class Loop;
+
+ /// ExtractCodeRegion - Rip out a sequence of basic blocks into a new
+ /// function.
+ ///
+ Function* ExtractCodeRegion(DominatorTree& DT,
+ ArrayRef<BasicBlock*> code,
+ bool AggregateArgs = false);
+
+ /// ExtractLoop - Rip out a natural loop into a new function.
+ ///
+ Function* ExtractLoop(DominatorTree& DT, Loop *L,
+ bool AggregateArgs = false);
+
+ /// ExtractBasicBlock - Rip out a basic block (and the associated landing pad)
+ /// into a new function.
+ ///
+ Function* ExtractBasicBlock(ArrayRef<BasicBlock*> BBs,
+ bool AggregateArgs = false);
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/Local.h b/contrib/llvm/include/llvm/Transforms/Utils/Local.h
new file mode 100644
index 000000000000..7f99dbcf895a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/Local.h
@@ -0,0 +1,187 @@
+//===-- Local.h - Functions to perform local transformations ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform various local transformations to the
+// program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
+#define LLVM_TRANSFORMS_UTILS_LOCAL_H
+
+namespace llvm {
+
+class User;
+class BasicBlock;
+class Function;
+class BranchInst;
+class Instruction;
+class DbgDeclareInst;
+class StoreInst;
+class LoadInst;
+class Value;
+class Pass;
+class PHINode;
+class AllocaInst;
+class ConstantExpr;
+class TargetData;
+class DIBuilder;
+
+template<typename T> class SmallVectorImpl;
+
+//===----------------------------------------------------------------------===//
+// Local constant propagation.
+//
+
+/// ConstantFoldTerminator - If a terminator instruction is predicated on a
+/// constant value, convert it into an unconditional branch to the constant
+/// destination. This is a nontrivial operation because the successors of this
+/// basic block must have their PHI nodes updated.
+/// Also calls RecursivelyDeleteTriviallyDeadInstructions() on any branch/switch
+/// conditions and indirectbr addresses this might make dead if
+/// DeleteDeadConditions is true.
+bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false);
+
+//===----------------------------------------------------------------------===//
+// Local dead code elimination.
+//
+
+/// isInstructionTriviallyDead - Return true if the result produced by the
+/// instruction is not used, and the instruction has no side effects.
+///
+bool isInstructionTriviallyDead(Instruction *I);
+
+/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
+/// trivially dead instruction, delete it. If that makes any of its operands
+/// trivially dead, delete them too, recursively. Return true if any
+/// instructions were deleted.
+bool RecursivelyDeleteTriviallyDeadInstructions(Value *V);
+
+/// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
+/// dead PHI node, due to being a def-use chain of single-use nodes that
+/// either forms a cycle or is terminated by a trivially dead instruction,
+/// delete it. If that makes any of its operands trivially dead, delete them
+/// too, recursively. Return true if a change was made.
+bool RecursivelyDeleteDeadPHINode(PHINode *PN);
+
+
+/// SimplifyInstructionsInBlock - Scan the specified basic block and try to
+/// simplify any instructions in it and recursively delete dead instructions.
+///
+/// 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);
+
+//===----------------------------------------------------------------------===//
+// Control Flow Graph Restructuring.
+//
+
+/// RemovePredecessorAndSimplify - Like BasicBlock::removePredecessor, this
+/// method is called when we're about to delete Pred as a predecessor of BB. If
+/// BB contains any PHI nodes, this drops the entries in the PHI nodes for Pred.
+///
+/// Unlike the removePredecessor method, this attempts to simplify uses of PHI
+/// nodes that collapse into identity values. For example, if we have:
+/// x = phi(1, 0, 0, 0)
+/// y = and x, z
+///
+/// .. 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);
+
+
+/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
+/// predecessor is known to have one successor (BB!). Eliminate the edge
+/// between them, moving the instructions in the predecessor into BB. This
+/// deletes the predecessor block.
+///
+void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, Pass *P = 0);
+
+
+/// TryToSimplifyUncondBranchFromEmptyBlock - BB is known to contain an
+/// unconditional branch, and contains no instructions other than PHI nodes,
+/// potential debug intrinsics and the branch. If possible, eliminate BB by
+/// rewriting all the predecessors to branch to the successor block and return
+/// true. If we can't transform, return false.
+bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB);
+
+/// EliminateDuplicatePHINodes - Check for and eliminate duplicate PHI
+/// nodes in this block. This doesn't try to be clever about PHI nodes
+/// which differ only in the order of the incoming values, but instcombine
+/// orders them so it usually won't matter.
+///
+bool EliminateDuplicatePHINodes(BasicBlock *BB);
+
+/// SimplifyCFG - This function is used to do simplification of a CFG. For
+/// example, it adjusts branches to branches to eliminate the extra hop, it
+/// eliminates unreachable basic blocks, and does other "peephole" optimization
+/// 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);
+
+/// 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
+/// setcc into the predecessor and use logical operations to pick the right
+/// destination.
+bool FoldBranchToCommonDest(BranchInst *BI);
+
+/// DemoteRegToStack - This function takes a virtual register computed by an
+/// Instruction and replaces it with a slot in the stack frame, allocated via
+/// alloca. This allows the CFG to be changed around without fear of
+/// invalidating the SSA information for the value. It returns the pointer to
+/// the alloca inserted to create a stack slot for X.
+///
+AllocaInst *DemoteRegToStack(Instruction &X,
+ bool VolatileLoads = false,
+ Instruction *AllocaPoint = 0);
+
+/// DemotePHIToStack - This function takes a virtual register computed by a phi
+/// node and replaces it with a slot in the stack frame, allocated via alloca.
+/// The phi node is deleted and it returns the pointer to the alloca inserted.
+AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = 0);
+
+/// getOrEnforceKnownAlignment - If the specified pointer has an alignment that
+/// we can determine, return it, otherwise return 0. If PrefAlign is specified,
+/// 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);
+
+/// getKnownAlignment - Try to infer an alignment for the specified pointer.
+static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) {
+ return getOrEnforceKnownAlignment(V, 0, TD);
+}
+
+///===---------------------------------------------------------------------===//
+/// Dbg Intrinsic utilities
+///
+
+/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value
+/// that has an associated llvm.dbg.decl intrinsic.
+bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+ StoreInst *SI, DIBuilder &Builder);
+
+/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value
+/// that has an associated llvm.dbg.decl intrinsic.
+bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
+ LoadInst *LI, DIBuilder &Builder);
+
+/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set
+/// of llvm.dbg.value intrinsics.
+bool LowerDbgDeclare(Function &F);
+
+/// FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic corresponding to
+/// an alloca, if any.
+DbgDeclareInst *FindAllocaDbgDeclare(Value *V);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
new file mode 100644
index 000000000000..2c0ec9b118cf
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -0,0 +1,33 @@
+//===-- ModuleUtils.h - Functions to manipulate Modules ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform manipulations on Modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H
+#define LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H
+
+namespace llvm {
+
+class Module;
+class Function;
+
+/// Append F to the list of global ctors of module M with the given Priority.
+/// This wraps the function in the appropriate structure and stores it along
+/// side other global constructors. For details see
+/// http://llvm.org/docs/LangRef.html#intg_global_ctors
+void appendToGlobalCtors(Module &M, Function *F, int Priority);
+
+/// Same as appendToGlobalCtors(), but for global dtors.
+void appendToGlobalDtors(Module &M, Function *F, int Priority);
+
+} // End llvm namespace
+
+#endif // LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h b/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
new file mode 100644
index 000000000000..98d51a29ad71
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -0,0 +1,45 @@
+//===- PromoteMemToReg.h - Promote Allocas to Scalars -----------*- 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 promote alloca instructions to SSA
+// registers, by using the SSA construction algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+#define TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+
+#include <vector>
+
+namespace llvm {
+
+class AllocaInst;
+class DominatorTree;
+class DominanceFrontier;
+class AliasSetTracker;
+
+/// isAllocaPromotable - Return true if this alloca is legal for promotion.
+/// This is true if there are only loads and stores to the alloca...
+///
+bool isAllocaPromotable(const AllocaInst *AI);
+
+/// PromoteMemToReg - Promote the specified list of alloca instructions into
+/// scalar registers, inserting PHI nodes as appropriate. This function makes
+/// use of DominanceFrontier information. This function does not modify the CFG
+/// of the function at all. All allocas must be from the same function.
+///
+/// If AST is specified, the specified tracker is updated to reflect changes
+/// made to the IR.
+///
+void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
+ DominatorTree &DT, AliasSetTracker *AST = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h
new file mode 100644
index 000000000000..4c821491b210
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdater.h
@@ -0,0 +1,166 @@
+//===-- SSAUpdater.h - Unstructured SSA Update Tool -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SSAUpdater class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
+#define LLVM_TRANSFORMS_UTILS_SSAUPDATER_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+ class BasicBlock;
+ class Instruction;
+ class LoadInst;
+ template<typename T> class SmallVectorImpl;
+ template<typename T> class SSAUpdaterTraits;
+ class PHINode;
+ class Type;
+ class Use;
+ class Value;
+
+/// SSAUpdater - This class updates SSA form for a set of values defined in
+/// multiple blocks. This is used when code duplication or another unstructured
+/// transformation wants to rewrite a set of uses of one value with uses of a
+/// set of values.
+class SSAUpdater {
+ friend class SSAUpdaterTraits<SSAUpdater>;
+
+private:
+ /// AvailableVals - This keeps track of which value to use on a per-block
+ /// basis. When we insert PHI nodes, we keep track of them here.
+ //typedef DenseMap<BasicBlock*, Value*> AvailableValsTy;
+ void *AV;
+
+ /// ProtoType holds the type of the values being rewritten.
+ Type *ProtoType;
+
+ // PHI nodes are given a name based on ProtoName.
+ std::string ProtoName;
+
+ /// InsertedPHIs - If this is non-null, the SSAUpdater adds all PHI nodes that
+ /// it creates to the vector.
+ SmallVectorImpl<PHINode*> *InsertedPHIs;
+
+public:
+ /// SSAUpdater constructor. If InsertedPHIs is specified, it will be filled
+ /// in with all PHI Nodes created by rewriting.
+ explicit SSAUpdater(SmallVectorImpl<PHINode*> *InsertedPHIs = 0);
+ ~SSAUpdater();
+
+ /// Initialize - Reset this object to get ready for a new set of SSA
+ /// updates with type 'Ty'. PHI nodes get a name based on 'Name'.
+ void Initialize(Type *Ty, StringRef Name);
+
+ /// AddAvailableValue - Indicate that a rewritten value is available at the
+ /// end of the specified block with the specified value.
+ void AddAvailableValue(BasicBlock *BB, Value *V);
+
+ /// HasValueForBlock - Return true if the SSAUpdater already has a value for
+ /// the specified block.
+ bool HasValueForBlock(BasicBlock *BB) const;
+
+ /// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
+ /// live at the end of the specified block.
+ Value *GetValueAtEndOfBlock(BasicBlock *BB);
+
+ /// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
+ /// is live in the middle of the specified block.
+ ///
+ /// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
+ /// important case: if there is a definition of the rewritten value after the
+ /// 'use' in BB. Consider code like this:
+ ///
+ /// X1 = ...
+ /// SomeBB:
+ /// use(X)
+ /// X2 = ...
+ /// br Cond, SomeBB, OutBB
+ ///
+ /// In this case, there are two values (X1 and X2) added to the AvailableVals
+ /// set by the client of the rewriter, and those values are both live out of
+ /// their respective blocks. However, the use of X happens in the *middle* of
+ /// a block. Because of this, we need to insert a new PHI node in SomeBB to
+ /// merge the appropriate values, and this value isn't live out of the block.
+ ///
+ Value *GetValueInMiddleOfBlock(BasicBlock *BB);
+
+ /// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
+ /// which use their value in the corresponding predecessor. Note that this
+ /// will not work if the use is supposed to be rewritten to a value defined in
+ /// the same block as the use, but above it. Any 'AddAvailableValue's added
+ /// for the use's block will be considered to be below it.
+ void RewriteUse(Use &U);
+
+ /// RewriteUseAfterInsertions - Rewrite a use, just like RewriteUse. However,
+ /// this version of the method can rewrite uses in the same block as a
+ /// definition, because it assumes that all uses of a value are below any
+ /// inserted values.
+ void RewriteUseAfterInsertions(Use &U);
+
+private:
+ Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
+
+ void operator=(const SSAUpdater&); // DO NOT IMPLEMENT
+ SSAUpdater(const SSAUpdater&); // DO NOT IMPLEMENT
+};
+
+/// LoadAndStorePromoter - This little helper class provides a convenient way to
+/// promote a collection of loads and stores into SSA Form using the SSAUpdater.
+/// This handles complexities that SSAUpdater doesn't, such as multiple loads
+/// and stores in one block.
+///
+/// Clients of this class are expected to subclass this and implement the
+/// virtual methods.
+///
+class LoadAndStorePromoter {
+protected:
+ SSAUpdater &SSA;
+public:
+ LoadAndStorePromoter(const SmallVectorImpl<Instruction*> &Insts,
+ SSAUpdater &S, StringRef Name = StringRef());
+ virtual ~LoadAndStorePromoter() {}
+
+ /// run - This does the promotion. Insts is a list of loads and stores to
+ /// promote, and Name is the basename for the PHIs to insert. After this is
+ /// complete, the loads and stores are removed from the code.
+ void run(const SmallVectorImpl<Instruction*> &Insts) const;
+
+
+ /// Return true if the specified instruction is in the Inst list (which was
+ /// passed into the run method). Clients should implement this with a more
+ /// efficient version if possible.
+ virtual bool isInstInList(Instruction *I,
+ const SmallVectorImpl<Instruction*> &Insts) const;
+
+ /// doExtraRewritesBeforeFinalDeletion - This hook is invoked after all the
+ /// stores are found and inserted as available values, but
+ virtual void doExtraRewritesBeforeFinalDeletion() const {
+ }
+
+ /// replaceLoadWithValue - Clients can choose to implement this to get
+ /// notified right before a load is RAUW'd another value.
+ virtual void replaceLoadWithValue(LoadInst *LI, Value *V) const {
+ }
+
+ /// This is called before each instruction is deleted.
+ virtual void instructionDeleted(Instruction *I) const {
+ }
+
+ /// updateDebugInfo - This is called to update debug info associated with the
+ /// instruction.
+ virtual void updateDebugInfo(Instruction *I) const {
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
new file mode 100644
index 000000000000..a9adbd73c152
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -0,0 +1,456 @@
+//===-- SSAUpdaterImpl.h - SSA Updater Implementation -----------*- 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 template that implements the core algorithm for the
+// SSAUpdater and MachineSSAUpdater.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ValueHandle.h"
+
+namespace llvm {
+
+class CastInst;
+class PHINode;
+template<typename T> class SSAUpdaterTraits;
+
+template<typename UpdaterT>
+class SSAUpdaterImpl {
+private:
+ UpdaterT *Updater;
+
+ typedef SSAUpdaterTraits<UpdaterT> Traits;
+ typedef typename Traits::BlkT BlkT;
+ typedef typename Traits::ValT ValT;
+ typedef typename Traits::PhiT PhiT;
+
+ /// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
+ /// The predecessors of each block are cached here since pred_iterator is
+ /// slow and we need to iterate over the blocks at least a few times.
+ class BBInfo {
+ public:
+ BlkT *BB; // Back-pointer to the corresponding block.
+ ValT AvailableVal; // Value to use in this block.
+ BBInfo *DefBB; // Block that defines the available value.
+ int BlkNum; // Postorder number.
+ BBInfo *IDom; // Immediate dominator.
+ unsigned NumPreds; // Number of predecessor blocks.
+ BBInfo **Preds; // Array[NumPreds] of predecessor blocks.
+ PhiT *PHITag; // Marker for existing PHIs that match.
+
+ BBInfo(BlkT *ThisBB, ValT V)
+ : BB(ThisBB), AvailableVal(V), DefBB(V ? this : 0), BlkNum(0), IDom(0),
+ NumPreds(0), Preds(0), PHITag(0) { }
+ };
+
+ typedef DenseMap<BlkT*, ValT> AvailableValsTy;
+ AvailableValsTy *AvailableVals;
+
+ SmallVectorImpl<PhiT*> *InsertedPHIs;
+
+ typedef SmallVectorImpl<BBInfo*> BlockListTy;
+ typedef DenseMap<BlkT*, BBInfo*> BBMapTy;
+ BBMapTy BBMap;
+ BumpPtrAllocator Allocator;
+
+public:
+ explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
+ SmallVectorImpl<PhiT*> *Ins) :
+ Updater(U), AvailableVals(A), InsertedPHIs(Ins) { }
+
+ /// GetValue - Check to see if AvailableVals has an entry for the specified
+ /// BB and if so, return it. If not, construct SSA form by first
+ /// calculating the required placement of PHIs and then inserting new PHIs
+ /// where needed.
+ ValT GetValue(BlkT *BB) {
+ SmallVector<BBInfo*, 100> BlockList;
+ BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
+
+ // Special case: bail out if BB is unreachable.
+ if (BlockList.size() == 0) {
+ ValT V = Traits::GetUndefVal(BB, Updater);
+ (*AvailableVals)[BB] = V;
+ return V;
+ }
+
+ FindDominators(&BlockList, PseudoEntry);
+ FindPHIPlacement(&BlockList);
+ FindAvailableVals(&BlockList);
+
+ return BBMap[BB]->DefBB->AvailableVal;
+ }
+
+ /// BuildBlockList - Starting from the specified basic block, traverse back
+ /// through its predecessors until reaching blocks with known values.
+ /// Create BBInfo structures for the blocks and append them to the block
+ /// list.
+ BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
+ SmallVector<BBInfo*, 10> RootList;
+ SmallVector<BBInfo*, 64> WorkList;
+
+ BBInfo *Info = new (Allocator) BBInfo(BB, 0);
+ BBMap[BB] = Info;
+ WorkList.push_back(Info);
+
+ // Search backward from BB, creating BBInfos along the way and stopping
+ // when reaching blocks that define the value. Record those defining
+ // blocks on the RootList.
+ SmallVector<BlkT*, 10> Preds;
+ while (!WorkList.empty()) {
+ Info = WorkList.pop_back_val();
+ Preds.clear();
+ Traits::FindPredecessorBlocks(Info->BB, &Preds);
+ Info->NumPreds = Preds.size();
+ if (Info->NumPreds == 0)
+ Info->Preds = 0;
+ else
+ Info->Preds = static_cast<BBInfo**>
+ (Allocator.Allocate(Info->NumPreds * sizeof(BBInfo*),
+ AlignOf<BBInfo*>::Alignment));
+
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ BlkT *Pred = Preds[p];
+ // Check if BBMap already has a BBInfo for the predecessor block.
+ typename BBMapTy::value_type &BBMapBucket =
+ BBMap.FindAndConstruct(Pred);
+ if (BBMapBucket.second) {
+ Info->Preds[p] = BBMapBucket.second;
+ continue;
+ }
+
+ // Create a new BBInfo for the predecessor.
+ ValT PredVal = AvailableVals->lookup(Pred);
+ BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
+ BBMapBucket.second = PredInfo;
+ Info->Preds[p] = PredInfo;
+
+ if (PredInfo->AvailableVal) {
+ RootList.push_back(PredInfo);
+ continue;
+ }
+ WorkList.push_back(PredInfo);
+ }
+ }
+
+ // Now that we know what blocks are backwards-reachable from the starting
+ // block, do a forward depth-first traversal to assign postorder numbers
+ // to those blocks.
+ BBInfo *PseudoEntry = new (Allocator) BBInfo(0, 0);
+ unsigned BlkNum = 1;
+
+ // Initialize the worklist with the roots from the backward traversal.
+ while (!RootList.empty()) {
+ Info = RootList.pop_back_val();
+ Info->IDom = PseudoEntry;
+ Info->BlkNum = -1;
+ WorkList.push_back(Info);
+ }
+
+ while (!WorkList.empty()) {
+ Info = WorkList.back();
+
+ if (Info->BlkNum == -2) {
+ // All the successors have been handled; assign the postorder number.
+ Info->BlkNum = BlkNum++;
+ // If not a root, put it on the BlockList.
+ if (!Info->AvailableVal)
+ BlockList->push_back(Info);
+ WorkList.pop_back();
+ continue;
+ }
+
+ // Leave this entry on the worklist, but set its BlkNum to mark that its
+ // successors have been put on the worklist. When it returns to the top
+ // the list, after handling its successors, it will be assigned a
+ // number.
+ Info->BlkNum = -2;
+
+ // Add unvisited successors to the work list.
+ for (typename Traits::BlkSucc_iterator SI =
+ Traits::BlkSucc_begin(Info->BB),
+ E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
+ BBInfo *SuccInfo = BBMap[*SI];
+ if (!SuccInfo || SuccInfo->BlkNum)
+ continue;
+ SuccInfo->BlkNum = -1;
+ WorkList.push_back(SuccInfo);
+ }
+ }
+ PseudoEntry->BlkNum = BlkNum;
+ return PseudoEntry;
+ }
+
+ /// IntersectDominators - This is the dataflow lattice "meet" operation for
+ /// finding dominators. Given two basic blocks, it walks up the dominator
+ /// tree until it finds a common dominator of both. It uses the postorder
+ /// number of the blocks to determine how to do that.
+ BBInfo *IntersectDominators(BBInfo *Blk1, BBInfo *Blk2) {
+ while (Blk1 != Blk2) {
+ while (Blk1->BlkNum < Blk2->BlkNum) {
+ Blk1 = Blk1->IDom;
+ if (!Blk1)
+ return Blk2;
+ }
+ while (Blk2->BlkNum < Blk1->BlkNum) {
+ Blk2 = Blk2->IDom;
+ if (!Blk2)
+ return Blk1;
+ }
+ }
+ return Blk1;
+ }
+
+ /// FindDominators - Calculate the dominator tree for the subset of the CFG
+ /// corresponding to the basic blocks on the BlockList. This uses the
+ /// algorithm from: "A Simple, Fast Dominance Algorithm" by Cooper, Harvey
+ /// and Kennedy, published in Software--Practice and Experience, 2001,
+ /// 4:1-10. Because the CFG subset does not include any edges leading into
+ /// blocks that define the value, the results are not the usual dominator
+ /// tree. The CFG subset has a single pseudo-entry node with edges to a set
+ /// of root nodes for blocks that define the value. The dominators for this
+ /// subset CFG are not the standard dominators but they are adequate for
+ /// placing PHIs within the subset CFG.
+ void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
+ bool Changed;
+ do {
+ Changed = false;
+ // Iterate over the list in reverse order, i.e., forward on CFG edges.
+ for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+ E = BlockList->rend(); I != E; ++I) {
+ BBInfo *Info = *I;
+ BBInfo *NewIDom = 0;
+
+ // Iterate through the block's predecessors.
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ BBInfo *Pred = Info->Preds[p];
+
+ // Treat an unreachable predecessor as a definition with 'undef'.
+ if (Pred->BlkNum == 0) {
+ Pred->AvailableVal = Traits::GetUndefVal(Pred->BB, Updater);
+ (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
+ Pred->DefBB = Pred;
+ Pred->BlkNum = PseudoEntry->BlkNum;
+ PseudoEntry->BlkNum++;
+ }
+
+ if (!NewIDom)
+ NewIDom = Pred;
+ else
+ NewIDom = IntersectDominators(NewIDom, Pred);
+ }
+
+ // Check if the IDom value has changed.
+ if (NewIDom && NewIDom != Info->IDom) {
+ Info->IDom = NewIDom;
+ Changed = true;
+ }
+ }
+ } while (Changed);
+ }
+
+ /// IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for
+ /// any blocks containing definitions of the value. If one is found, then
+ /// the successor of Pred is in the dominance frontier for the definition,
+ /// and this function returns true.
+ bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom) {
+ for (; Pred != IDom; Pred = Pred->IDom) {
+ if (Pred->DefBB == Pred)
+ return true;
+ }
+ return false;
+ }
+
+ /// FindPHIPlacement - PHIs are needed in the iterated dominance frontiers
+ /// of the known definitions. Iteratively add PHIs in the dom frontiers
+ /// until nothing changes. Along the way, keep track of the nearest
+ /// dominating definitions for non-PHI blocks.
+ void FindPHIPlacement(BlockListTy *BlockList) {
+ bool Changed;
+ do {
+ Changed = false;
+ // Iterate over the list in reverse order, i.e., forward on CFG edges.
+ for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+ E = BlockList->rend(); I != E; ++I) {
+ BBInfo *Info = *I;
+
+ // If this block already needs a PHI, there is nothing to do here.
+ if (Info->DefBB == Info)
+ continue;
+
+ // Default to use the same def as the immediate dominator.
+ BBInfo *NewDefBB = Info->IDom->DefBB;
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ if (IsDefInDomFrontier(Info->Preds[p], Info->IDom)) {
+ // Need a PHI here.
+ NewDefBB = Info;
+ break;
+ }
+ }
+
+ // Check if anything changed.
+ if (NewDefBB != Info->DefBB) {
+ Info->DefBB = NewDefBB;
+ Changed = true;
+ }
+ }
+ } while (Changed);
+ }
+
+ /// FindAvailableVal - If this block requires a PHI, first check if an
+ /// existing PHI matches the PHI placement and reaching definitions computed
+ /// earlier, and if not, create a new PHI. Visit all the block's
+ /// predecessors to calculate the available value for each one and fill in
+ /// the incoming values for a new PHI.
+ void FindAvailableVals(BlockListTy *BlockList) {
+ // Go through the worklist in forward order (i.e., backward through the CFG)
+ // and check if existing PHIs can be used. If not, create empty PHIs where
+ // they are needed.
+ for (typename BlockListTy::iterator I = BlockList->begin(),
+ E = BlockList->end(); I != E; ++I) {
+ BBInfo *Info = *I;
+ // Check if there needs to be a PHI in BB.
+ if (Info->DefBB != Info)
+ continue;
+
+ // Look for an existing PHI.
+ FindExistingPHI(Info->BB, BlockList);
+ if (Info->AvailableVal)
+ continue;
+
+ ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
+ Info->AvailableVal = PHI;
+ (*AvailableVals)[Info->BB] = PHI;
+ }
+
+ // Now go back through the worklist in reverse order to fill in the
+ // arguments for any new PHIs added in the forward traversal.
+ for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
+ E = BlockList->rend(); I != E; ++I) {
+ BBInfo *Info = *I;
+
+ if (Info->DefBB != Info) {
+ // Record the available value at join nodes to speed up subsequent
+ // uses of this SSAUpdater for the same value.
+ if (Info->NumPreds > 1)
+ (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
+ continue;
+ }
+
+ // Check if this block contains a newly added PHI.
+ PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
+ if (!PHI)
+ continue;
+
+ // Iterate through the block's predecessors.
+ for (unsigned p = 0; p != Info->NumPreds; ++p) {
+ BBInfo *PredInfo = Info->Preds[p];
+ BlkT *Pred = PredInfo->BB;
+ // Skip to the nearest preceding definition.
+ if (PredInfo->DefBB != PredInfo)
+ PredInfo = PredInfo->DefBB;
+ Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
+ }
+
+ DEBUG(dbgs() << " Inserted PHI: " << *PHI << "\n");
+
+ // If the client wants to know about all new instructions, tell it.
+ if (InsertedPHIs) InsertedPHIs->push_back(PHI);
+ }
+ }
+
+ /// FindExistingPHI - Look through the PHI nodes in a block to see if any of
+ /// them match what is needed.
+ void FindExistingPHI(BlkT *BB, BlockListTy *BlockList) {
+ for (typename BlkT::iterator BBI = BB->begin(), BBE = BB->end();
+ BBI != BBE; ++BBI) {
+ PhiT *SomePHI = Traits::InstrIsPHI(BBI);
+ if (!SomePHI)
+ break;
+ if (CheckIfPHIMatches(SomePHI)) {
+ RecordMatchingPHIs(BlockList);
+ break;
+ }
+ // Match failed: clear all the PHITag values.
+ for (typename BlockListTy::iterator I = BlockList->begin(),
+ E = BlockList->end(); I != E; ++I)
+ (*I)->PHITag = 0;
+ }
+ }
+
+ /// CheckIfPHIMatches - Check if a PHI node matches the placement and values
+ /// in the BBMap.
+ bool CheckIfPHIMatches(PhiT *PHI) {
+ SmallVector<PhiT*, 20> WorkList;
+ WorkList.push_back(PHI);
+
+ // Mark that the block containing this PHI has been visited.
+ BBMap[PHI->getParent()]->PHITag = PHI;
+
+ while (!WorkList.empty()) {
+ PHI = WorkList.pop_back_val();
+
+ // Iterate through the PHI's incoming values.
+ for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
+ E = Traits::PHI_end(PHI); I != E; ++I) {
+ ValT IncomingVal = I.getIncomingValue();
+ BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
+ // Skip to the nearest preceding definition.
+ if (PredInfo->DefBB != PredInfo)
+ PredInfo = PredInfo->DefBB;
+
+ // Check if it matches the expected value.
+ if (PredInfo->AvailableVal) {
+ if (IncomingVal == PredInfo->AvailableVal)
+ continue;
+ return false;
+ }
+
+ // Check if the value is a PHI in the correct block.
+ PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
+ if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
+ return false;
+
+ // If this block has already been visited, check if this PHI matches.
+ if (PredInfo->PHITag) {
+ if (IncomingPHIVal == PredInfo->PHITag)
+ continue;
+ return false;
+ }
+ PredInfo->PHITag = IncomingPHIVal;
+
+ WorkList.push_back(IncomingPHIVal);
+ }
+ }
+ return true;
+ }
+
+ /// RecordMatchingPHIs - For each PHI node that matches, record it in both
+ /// the BBMap and the AvailableVals mapping.
+ void RecordMatchingPHIs(BlockListTy *BlockList) {
+ for (typename BlockListTy::iterator I = BlockList->begin(),
+ E = BlockList->end(); I != E; ++I)
+ if (PhiT *PHI = (*I)->PHITag) {
+ BlkT *BB = PHI->getParent();
+ ValT PHIVal = Traits::GetPHIValue(PHI);
+ (*AvailableVals)[BB] = PHIVal;
+ BBMap[BB]->AvailableVal = PHIVal;
+ }
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
new file mode 100644
index 000000000000..2632d186ff9b
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -0,0 +1,54 @@
+//===-- llvm/Transforms/Utils/SimplifyIndVar.h - Indvar Utils ---*- 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 in interface for induction variable simplification. It does
+// not define any actual pass or policy, but provides a single function to
+// simplify a loop's induction variables based on ScalarEvolution.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
+#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ValueHandle.h"
+
+namespace llvm {
+
+extern cl::opt<bool> DisableIVRewrite;
+
+class CastInst;
+class IVUsers;
+class Loop;
+class LPPassManager;
+class PHINode;
+class ScalarEvolution;
+
+/// Interface for visiting interesting IV users that are recognized but not
+/// simplified by this utility.
+class IVVisitor {
+ virtual void anchor();
+public:
+ virtual ~IVVisitor() {}
+ virtual void visitCast(CastInst *Cast) = 0;
+};
+
+/// simplifyUsersOfIV - Simplify instructions that use this induction variable
+/// by using ScalarEvolution to analyze the IV's recurrence.
+bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM,
+ SmallVectorImpl<WeakVH> &Dead, IVVisitor *V = NULL);
+
+/// SimplifyLoopIVs - Simplify users of induction variables within this
+/// loop. This does not actually change or add IVs.
+bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, LPPassManager *LPM,
+ SmallVectorImpl<WeakVH> &Dead);
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
new file mode 100644
index 000000000000..54506cfff4c3
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -0,0 +1,51 @@
+//===-- UnifyFunctionExitNodes.h - Ensure fn's have one return --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to ensure that functions have at most one return and one
+// unwind instruction in them. Additionally, it keeps track of which node is
+// the new exit node of the CFG. If there are no return or unwind instructions
+// in the function, the getReturnBlock/getUnwindBlock methods will return a null
+// pointer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+#define LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+struct UnifyFunctionExitNodes : public FunctionPass {
+ BasicBlock *ReturnBlock, *UnwindBlock, *UnreachableBlock;
+public:
+ static char ID; // Pass identification, replacement for typeid
+ UnifyFunctionExitNodes() : FunctionPass(ID),
+ ReturnBlock(0), UnwindBlock(0) {
+ initializeUnifyFunctionExitNodesPass(*PassRegistry::getPassRegistry());
+ }
+
+ // We can preserve non-critical-edgeness when we unify function exit nodes
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ // getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistant)
+ // return, unwind, or unreachable basic blocks in the CFG.
+ //
+ BasicBlock *getReturnBlock() const { return ReturnBlock; }
+ BasicBlock *getUnwindBlock() const { return UnwindBlock; }
+ BasicBlock *getUnreachableBlock() const { return UnreachableBlock; }
+
+ virtual bool runOnFunction(Function &F);
+};
+
+Pass *createUnifyFunctionExitNodesPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h b/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
new file mode 100644
index 000000000000..f175e8371e79
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -0,0 +1,33 @@
+//===- llvm/Transforms/Utils/UnrollLoop.h - Unrolling utilities -*- 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 some loop unrolling utilities. It does not define any
+// actual pass or policy, but provides a single function to perform loop
+// unrolling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
+#define LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
+
+namespace llvm {
+
+class Loop;
+class LoopInfo;
+class LPPassManager;
+
+bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime,
+ unsigned TripMultiple, LoopInfo* LI, LPPassManager* LPM);
+
+bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
+ LPPassManager* LPM);
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h
new file mode 100644
index 000000000000..8594707a8482
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Utils/ValueMapper.h
@@ -0,0 +1,80 @@
+//===- ValueMapper.h - Remapping for constants and metadata -----*- 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 MapValue interface which is used by various parts of
+// the Transforms/Utils library to implement cloning and linking facilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
+#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
+
+#include "llvm/ADT/ValueMap.h"
+
+namespace llvm {
+ class Value;
+ class Instruction;
+ typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;
+
+ /// 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.
+ public:
+ virtual ~ValueMapTypeRemapper() {}
+
+ /// remapType - The client should implement this method if they want to
+ /// remap types while mapping values.
+ virtual Type *remapType(Type *SrcTy) = 0;
+ };
+
+ /// RemapFlags - These are flags that the value mapping APIs allow.
+ enum RemapFlags {
+ RF_None = 0,
+
+ /// RF_NoModuleLevelChanges - If this flag is set, the remapper knows that
+ /// only local values within a function (such as an instruction or argument)
+ /// are mapped, not global values like functions and global metadata.
+ RF_NoModuleLevelChanges = 1,
+
+ /// RF_IgnoreMissingEntries - If this flag is set, the remapper ignores
+ /// entries that are not in the value map. If it is unset, it aborts if an
+ /// operand is asked to be remapped which doesn't exist in the mapping.
+ RF_IgnoreMissingEntries = 2
+ };
+
+ static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
+ return RemapFlags(unsigned(LHS)|unsigned(RHS));
+ }
+
+ Value *MapValue(const Value *V, ValueToValueMapTy &VM,
+ RemapFlags Flags = RF_None,
+ ValueMapTypeRemapper *TypeMapper = 0);
+
+ void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
+ RemapFlags Flags = RF_None,
+ ValueMapTypeRemapper *TypeMapper = 0);
+
+ /// MapValue - provide versions that preserve type safety for MDNode and
+ /// Constants.
+ inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM,
+ RemapFlags Flags = RF_None,
+ ValueMapTypeRemapper *TypeMapper = 0) {
+ return cast<MDNode>(MapValue((const Value*)V, VM, Flags, TypeMapper));
+ }
+ inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
+ RemapFlags Flags = RF_None,
+ ValueMapTypeRemapper *TypeMapper = 0) {
+ return cast<Constant>(MapValue((const Value*)V, VM, Flags, TypeMapper));
+ }
+
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Transforms/Vectorize.h b/contrib/llvm/include/llvm/Transforms/Vectorize.h
new file mode 100644
index 000000000000..652916c26c22
--- /dev/null
+++ b/contrib/llvm/include/llvm/Transforms/Vectorize.h
@@ -0,0 +1,115 @@
+//===-- Vectorize.h - Vectorization Transformations -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the Vectorize transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_H
+#define LLVM_TRANSFORMS_VECTORIZE_H
+
+namespace llvm {
+class BasicBlock;
+class BasicBlockPass;
+
+//===----------------------------------------------------------------------===//
+/// @brief Vectorize configuration.
+struct VectorizeConfig {
+ //===--------------------------------------------------------------------===//
+ // Target architecture related parameters
+
+ /// @brief The size of the native vector registers.
+ unsigned VectorBits;
+
+ /// @brief Vectorize integer values.
+ bool VectorizeInts;
+
+ /// @brief Vectorize floating-point values.
+ bool VectorizeFloats;
+
+ /// @brief Vectorize pointer values.
+ bool VectorizePointers;
+
+ /// @brief Vectorize casting (conversion) operations.
+ bool VectorizeCasts;
+
+ /// @brief Vectorize floating-point math intrinsics.
+ bool VectorizeMath;
+
+ /// @brief Vectorize the fused-multiply-add intrinsic.
+ bool VectorizeFMA;
+
+ /// @brief Vectorize select instructions.
+ bool VectorizeSelect;
+
+ /// @brief Vectorize getelementptr instructions.
+ bool VectorizeGEP;
+
+ /// @brief Vectorize loads and stores.
+ bool VectorizeMemOps;
+
+ /// @brief Only generate aligned loads and stores.
+ bool AlignedOnly;
+
+ //===--------------------------------------------------------------------===//
+ // Misc parameters
+
+ /// @brief The required chain depth for vectorization.
+ unsigned ReqChainDepth;
+
+ /// @brief The maximum search distance for instruction pairs.
+ unsigned SearchLimit;
+
+ /// @brief The maximum number of candidate pairs with which to use a full
+ /// cycle check.
+ unsigned MaxCandPairsForCycleCheck;
+
+ /// @brief Replicating one element to a pair breaks the chain.
+ bool SplatBreaksChain;
+
+ /// @brief The maximum number of pairable instructions per group.
+ unsigned MaxInsts;
+
+ /// @brief The maximum number of pairing iterations.
+ unsigned MaxIter;
+
+ /// @brief Don't boost the chain-depth contribution of loads and stores.
+ bool NoMemOpBoost;
+
+ /// @brief Use a fast instruction dependency analysis.
+ bool FastDep;
+
+ /// @brief Initialize the VectorizeConfig from command line options.
+ VectorizeConfig();
+};
+
+//===----------------------------------------------------------------------===//
+//
+// BBVectorize - A basic-block vectorization pass.
+//
+BasicBlockPass *
+createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
+
+//===----------------------------------------------------------------------===//
+/// @brief Vectorize the BasicBlock.
+///
+/// @param BB The BasicBlock to be vectorized
+/// @param P The current running pass, should require AliasAnalysis and
+/// ScalarEvolution. After the vectorization, AliasAnalysis,
+/// ScalarEvolution and CFG are preserved.
+///
+/// @return True if the BB is changed, false otherwise.
+///
+bool vectorizeBasicBlock(Pass *P, BasicBlock &BB,
+ const VectorizeConfig &C = VectorizeConfig());
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Type.h b/contrib/llvm/include/llvm/Type.h
new file mode 100644
index 000000000000..185258d8ff2a
--- /dev/null
+++ b/contrib/llvm/include/llvm/Type.h
@@ -0,0 +1,453 @@
+//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Type class. For more "Type"
+// stuff, look in DerivedTypes.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TYPE_H
+#define LLVM_TYPE_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class PointerType;
+class IntegerType;
+class raw_ostream;
+class Module;
+class LLVMContext;
+class LLVMContextImpl;
+class StringRef;
+template<class GraphType> struct GraphTraits;
+
+/// The instances of the Type class are immutable: once they are created,
+/// they are never changed. Also note that only one instance of a particular
+/// type is ever created. Thus seeing if two types are equal is a matter of
+/// doing a trivial pointer comparison. To enforce that no two equal instances
+/// are created, Type instances can only be created via static factory methods
+/// in class Type and in derived classes. Once allocated, Types are never
+/// free'd.
+///
+class Type {
+public:
+ //===--------------------------------------------------------------------===//
+ /// Definitions of all of the base types for the Type system. Based on this
+ /// value, you can cast to a class defined in DerivedTypes.h.
+ /// Note: If you add an element to this, you need to add an element to the
+ /// Type::getPrimitiveType function, or else things will break!
+ /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding.
+ ///
+ enum TypeID {
+ // PrimitiveTypes - make sure LastPrimitiveTyID stays up to date.
+ VoidTyID = 0, ///< 0: type with no size
+ HalfTyID, ///< 1: 16-bit floating point type
+ FloatTyID, ///< 2: 32-bit floating point type
+ DoubleTyID, ///< 3: 64-bit floating point type
+ X86_FP80TyID, ///< 4: 80-bit floating point type (X87)
+ FP128TyID, ///< 5: 128-bit floating point type (112-bit mantissa)
+ PPC_FP128TyID, ///< 6: 128-bit floating point type (two 64-bits, PowerPC)
+ LabelTyID, ///< 7: Labels
+ MetadataTyID, ///< 8: Metadata
+ X86_MMXTyID, ///< 9: MMX vectors (64 bits, X86 specific)
+
+ // Derived types... see DerivedTypes.h file.
+ // Make sure FirstDerivedTyID stays up to date!
+ IntegerTyID, ///< 10: Arbitrary bit width integers
+ FunctionTyID, ///< 11: Functions
+ StructTyID, ///< 12: Structures
+ ArrayTyID, ///< 13: Arrays
+ PointerTyID, ///< 14: Pointers
+ VectorTyID, ///< 15: SIMD 'packed' format, or other vector type
+
+ NumTypeIDs, // Must remain as last defined ID
+ LastPrimitiveTyID = X86_MMXTyID,
+ FirstDerivedTyID = IntegerTyID
+ };
+
+private:
+ /// Context - This refers to the LLVMContext in which this type was uniqued.
+ LLVMContext &Context;
+
+ // Due to Ubuntu GCC bug 910363:
+ // https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/910363
+ // Bitpack ID and SubclassData manually.
+ // Note: TypeID : low 8 bit; SubclassData : high 24 bit.
+ uint32_t IDAndSubclassData;
+
+protected:
+ friend class LLVMContextImpl;
+ explicit Type(LLVMContext &C, TypeID tid)
+ : Context(C), IDAndSubclassData(0),
+ NumContainedTys(0), ContainedTys(0) {
+ setTypeID(tid);
+ }
+ ~Type() {}
+
+ void setTypeID(TypeID ID) {
+ IDAndSubclassData = (ID & 0xFF) | (IDAndSubclassData & 0xFFFFFF00);
+ assert(getTypeID() == ID && "TypeID data too large for field");
+ }
+
+ unsigned getSubclassData() const { return IDAndSubclassData >> 8; }
+
+ void setSubclassData(unsigned val) {
+ IDAndSubclassData = (IDAndSubclassData & 0xFF) | (val << 8);
+ // Ensure we don't have any accidental truncation.
+ assert(getSubclassData() == val && "Subclass data too large for field");
+ }
+
+ /// NumContainedTys - Keeps track of how many Type*'s there are in the
+ /// ContainedTys list.
+ unsigned NumContainedTys;
+
+ /// ContainedTys - A pointer to the array of Types contained by this Type.
+ /// For example, this includes the arguments of a function type, the elements
+ /// of a structure, the pointee of a pointer, the element type of an array,
+ /// etc. This pointer may be 0 for types that don't contain other types
+ /// (Integer, Double, Float).
+ Type * const *ContainedTys;
+
+public:
+ void print(raw_ostream &O) const;
+ void dump() const;
+
+ /// getContext - Return the LLVMContext in which this type was uniqued.
+ LLVMContext &getContext() const { return Context; }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors for working with types.
+ //
+
+ /// getTypeID - Return the type id for the type. This will return one
+ /// of the TypeID enum elements defined above.
+ ///
+ TypeID getTypeID() const { return (TypeID)(IDAndSubclassData & 0xFF); }
+
+ /// isVoidTy - Return true if this is 'void'.
+ bool isVoidTy() const { return getTypeID() == VoidTyID; }
+
+ /// isHalfTy - Return true if this is 'half', a 16-bit IEEE fp type.
+ bool isHalfTy() const { return getTypeID() == HalfTyID; }
+
+ /// isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
+ bool isFloatTy() const { return getTypeID() == FloatTyID; }
+
+ /// isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
+ bool isDoubleTy() const { return getTypeID() == DoubleTyID; }
+
+ /// isX86_FP80Ty - Return true if this is x86 long double.
+ bool isX86_FP80Ty() const { return getTypeID() == X86_FP80TyID; }
+
+ /// isFP128Ty - Return true if this is 'fp128'.
+ bool isFP128Ty() const { return getTypeID() == FP128TyID; }
+
+ /// 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
+ /// types
+ bool isFloatingPointTy() const {
+ return getTypeID() == HalfTyID || getTypeID() == FloatTyID ||
+ getTypeID() == DoubleTyID ||
+ getTypeID() == X86_FP80TyID || getTypeID() == FP128TyID ||
+ getTypeID() == PPC_FP128TyID;
+ }
+
+ /// isX86_MMXTy - Return true if this is X86 MMX.
+ bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }
+
+ /// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP.
+ ///
+ bool isFPOrFPVectorTy() const;
+
+ /// isLabelTy - Return true if this is 'label'.
+ bool isLabelTy() const { return getTypeID() == LabelTyID; }
+
+ /// isMetadataTy - Return true if this is 'metadata'.
+ bool isMetadataTy() const { return getTypeID() == MetadataTyID; }
+
+ /// isIntegerTy - True if this is an instance of IntegerType.
+ ///
+ bool isIntegerTy() const { return getTypeID() == IntegerTyID; }
+
+ /// isIntegerTy - Return true if this is an IntegerType of the given width.
+ bool isIntegerTy(unsigned Bitwidth) const;
+
+ /// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
+ /// integer types.
+ ///
+ bool isIntOrIntVectorTy() const;
+
+ /// isFunctionTy - True if this is an instance of FunctionType.
+ ///
+ bool isFunctionTy() const { return getTypeID() == FunctionTyID; }
+
+ /// isStructTy - True if this is an instance of StructType.
+ ///
+ bool isStructTy() const { return getTypeID() == StructTyID; }
+
+ /// isArrayTy - True if this is an instance of ArrayType.
+ ///
+ bool isArrayTy() const { return getTypeID() == ArrayTyID; }
+
+ /// isPointerTy - True if this is an instance of PointerType.
+ ///
+ bool isPointerTy() const { return getTypeID() == PointerTyID; }
+
+ /// isVectorTy - True if this is an instance of VectorType.
+ ///
+ bool isVectorTy() const { return getTypeID() == VectorTyID; }
+
+ /// canLosslesslyBitCastTo - Return true if this type could be converted
+ /// with a lossless BitCast to type 'Ty'. For example, i8* to i32*. BitCasts
+ /// are valid for types of the same size only where no re-interpretation of
+ /// the bits is done.
+ /// @brief Determine if this type could be losslessly bitcast to Ty
+ bool canLosslesslyBitCastTo(Type *Ty) const;
+
+ /// isEmptyTy - Return true if this type is empty, that is, it has no
+ /// elements or all its elements are empty.
+ bool isEmptyTy() const;
+
+ /// Here are some useful little methods to query what type derived types are
+ /// Note that all other types can just compare to see if this == Type::xxxTy;
+ ///
+ bool isPrimitiveType() const { return getTypeID() <= LastPrimitiveTyID; }
+ bool isDerivedType() const { return getTypeID() >= FirstDerivedTyID; }
+
+ /// isFirstClassType - Return true if the type is "first class", meaning it
+ /// is a valid type for a Value.
+ ///
+ bool isFirstClassType() const {
+ return getTypeID() != FunctionTyID && getTypeID() != VoidTyID;
+ }
+
+ /// isSingleValueType - Return true if the type is a valid type for a
+ /// register in codegen. This includes all first-class types except struct
+ /// and array types.
+ ///
+ bool isSingleValueType() const {
+ return (getTypeID() != VoidTyID && isPrimitiveType()) ||
+ getTypeID() == IntegerTyID || getTypeID() == PointerTyID ||
+ getTypeID() == VectorTyID;
+ }
+
+ /// isAggregateType - Return true if the type is an aggregate type. This
+ /// means it is valid as the first operand of an insertvalue or
+ /// extractvalue instruction. This includes struct and array types, but
+ /// does not include vector types.
+ ///
+ bool isAggregateType() const {
+ return getTypeID() == StructTyID || getTypeID() == ArrayTyID;
+ }
+
+ /// 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.
+ ///
+ bool isSized() const {
+ // If it's a primitive, it is always sized.
+ if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
+ getTypeID() == PointerTyID ||
+ getTypeID() == X86_MMXTyID)
+ return true;
+ // If it is not something that can have a size (e.g. a function or label),
+ // it doesn't have a size.
+ if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
+ getTypeID() != VectorTyID)
+ return false;
+ // Otherwise we have to try harder to decide.
+ return isSizedDerivedType();
+ }
+
+ /// getPrimitiveSizeInBits - Return the basic size of this type if it is a
+ /// primitive type. These are fixed by LLVM and are not target dependent.
+ /// This will return zero if the type does not have a size or is not a
+ /// primitive type.
+ ///
+ /// 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
+ /// additional query functions to provide this information.
+ ///
+ unsigned getPrimitiveSizeInBits() const;
+
+ /// getScalarSizeInBits - If this is a vector type, return the
+ /// getPrimitiveSizeInBits value for the element type. Otherwise return the
+ /// getPrimitiveSizeInBits value for this type.
+ unsigned getScalarSizeInBits();
+
+ /// getFPMantissaWidth - Return the width of the mantissa of this type. This
+ /// is only valid on floating point types. If the FP type does not
+ /// have a stable mantissa (e.g. ppc long double), this method returns -1.
+ int getFPMantissaWidth() const;
+
+ /// getScalarType - If this is a vector type, return the element type,
+ /// otherwise return 'this'.
+ Type *getScalarType();
+
+ //===--------------------------------------------------------------------===//
+ // Type Iteration support.
+ //
+ typedef Type * const *subtype_iterator;
+ subtype_iterator subtype_begin() const { return ContainedTys; }
+ subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
+
+ /// getContainedType - This method is used to implement the type iterator
+ /// (defined a the end of the file). For derived types, this returns the
+ /// types 'contained' in the derived type.
+ ///
+ Type *getContainedType(unsigned i) const {
+ assert(i < NumContainedTys && "Index out of range!");
+ return ContainedTys[i];
+ }
+
+ /// getNumContainedTypes - Return the number of types in the derived type.
+ ///
+ unsigned getNumContainedTypes() const { return NumContainedTys; }
+
+ //===--------------------------------------------------------------------===//
+ // Helper methods corresponding to subclass methods. This forces a cast to
+ // the specified subclass and calls its accessor. "getVectorNumElements" (for
+ // example) is shorthand for cast<VectorType>(Ty)->getNumElements(). This is
+ // only intended to cover the core methods that are frequently used, helper
+ // methods should not be added here.
+
+ unsigned getIntegerBitWidth() const;
+
+ Type *getFunctionParamType(unsigned i) const;
+ unsigned getFunctionNumParams() const;
+ bool isFunctionVarArg() const;
+
+ StringRef getStructName() const;
+ unsigned getStructNumElements() const;
+ Type *getStructElementType(unsigned N) const;
+
+ Type *getSequentialElementType() const;
+
+ uint64_t getArrayNumElements() const;
+ Type *getArrayElementType() const { return getSequentialElementType(); }
+
+ unsigned getVectorNumElements() const;
+ Type *getVectorElementType() const { return getSequentialElementType(); }
+
+ unsigned getPointerAddressSpace() const;
+ Type *getPointerElementType() const { return getSequentialElementType(); }
+
+ //===--------------------------------------------------------------------===//
+ // Static members exported by the Type class itself. Useful for getting
+ // instances of Type.
+ //
+
+ /// getPrimitiveType - Return a type based on an identifier.
+ static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber);
+
+ //===--------------------------------------------------------------------===//
+ // These are the builtin types that are always available.
+ //
+ static Type *getVoidTy(LLVMContext &C);
+ static Type *getLabelTy(LLVMContext &C);
+ static Type *getHalfTy(LLVMContext &C);
+ static Type *getFloatTy(LLVMContext &C);
+ static Type *getDoubleTy(LLVMContext &C);
+ static Type *getMetadataTy(LLVMContext &C);
+ static Type *getX86_FP80Ty(LLVMContext &C);
+ static Type *getFP128Ty(LLVMContext &C);
+ static Type *getPPC_FP128Ty(LLVMContext &C);
+ static Type *getX86_MMXTy(LLVMContext &C);
+ static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
+ static IntegerType *getInt1Ty(LLVMContext &C);
+ static IntegerType *getInt8Ty(LLVMContext &C);
+ static IntegerType *getInt16Ty(LLVMContext &C);
+ static IntegerType *getInt32Ty(LLVMContext &C);
+ static IntegerType *getInt64Ty(LLVMContext &C);
+
+ //===--------------------------------------------------------------------===//
+ // Convenience methods for getting pointer types with one of the above builtin
+ // types as pointee.
+ //
+ static PointerType *getHalfPtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getFP128PtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getPPC_FP128PtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getX86_MMXPtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS = 0);
+ static PointerType *getInt1PtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getInt8PtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getInt16PtrTy(LLVMContext &C, unsigned AS = 0);
+ 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);
+
+private:
+ /// isSizedDerivedType - Derived types like structures and arrays are sized
+ /// iff all of the members of the type are sized as well. Since asking for
+ /// their size is relatively uncommon, move this operation out of line.
+ bool isSizedDerivedType() const;
+};
+
+// Printing of types.
+static inline raw_ostream &operator<<(raw_ostream &OS, Type &T) {
+ T.print(OS);
+ return OS;
+}
+
+// allow isa<PointerType>(x) to work without DerivedTypes.h included.
+template <> struct isa_impl<PointerType, Type> {
+ static inline bool doit(const Type &Ty) {
+ return Ty.getTypeID() == Type::PointerTyID;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Provide specializations of GraphTraits to be able to treat a type as a
+// graph of sub types.
+
+
+template <> struct GraphTraits<Type*> {
+ typedef Type NodeType;
+ typedef Type::subtype_iterator ChildIteratorType;
+
+ static inline NodeType *getEntryNode(Type *T) { return T; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->subtype_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->subtype_end();
+ }
+};
+
+template <> struct GraphTraits<const Type*> {
+ typedef const Type NodeType;
+ typedef Type::subtype_iterator ChildIteratorType;
+
+ static inline NodeType *getEntryNode(NodeType *T) { return T; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->subtype_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->subtype_end();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Use.h b/contrib/llvm/include/llvm/Use.h
new file mode 100644
index 000000000000..a496325c1fc6
--- /dev/null
+++ b/contrib/llvm/include/llvm/Use.h
@@ -0,0 +1,219 @@
+//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines the Use class. The Use class represents the operand of an
+// instruction or some other User instance which refers to a Value. The Use
+// class keeps the "use list" of the referenced value up to date.
+//
+// Pointer tagging is used to efficiently find the User corresponding
+// to a Use without having to store a User pointer in every Use. A
+// User is preceded in memory by all the Uses corresponding to its
+// operands, and the low bits of one of the fields (Prev) of the Use
+// class are used to encode offsets to be able to find that User given
+// a pointer to any Use. For details, see:
+//
+// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_USE_H
+#define LLVM_USE_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include <cstddef>
+#include <iterator>
+
+namespace llvm {
+
+class Value;
+class User;
+class Use;
+template<typename>
+struct simplify_type;
+
+// Use** is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<Use**> {
+public:
+ static inline void *getAsVoidPointer(Use** P) { return P; }
+ static inline Use **getFromVoidPointer(void *P) {
+ return static_cast<Use**>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+
+//===----------------------------------------------------------------------===//
+// Use Class
+//===----------------------------------------------------------------------===//
+
+/// Use is here to make keeping the "use" list of a Value up-to-date really
+/// easy.
+class Use {
+public:
+ /// swap - provide a fast substitute to std::swap<Use>
+ /// that also works with less standard-compliant compilers
+ void swap(Use &RHS);
+
+ // A type for the word following an array of hung-off Uses in memory, which is
+ // a pointer back to their User with the bottom bit set.
+ typedef PointerIntPair<User*, 1, unsigned> UserRef;
+
+private:
+ /// Copy ctor - do not implement
+ Use(const Use &U);
+
+ /// Destructor - Only for zap()
+ ~Use() {
+ if (Val) removeFromList();
+ }
+
+ enum PrevPtrTag { zeroDigitTag
+ , oneDigitTag
+ , stopTag
+ , fullStopTag };
+
+ /// Constructor
+ Use(PrevPtrTag tag) : Val(0) {
+ Prev.setInt(tag);
+ }
+
+public:
+ /// Normally Use will just implicitly convert to a Value* that it holds.
+ operator Value*() const { return Val; }
+
+ /// If implicit conversion to Value* doesn't work, the get() method returns
+ /// the Value*.
+ Value *get() const { return Val; }
+
+ /// getUser - This returns the User that contains this Use. For an
+ /// instruction operand, for example, this will return the instruction.
+ User *getUser() const;
+
+ inline void set(Value *Val);
+
+ Value *operator=(Value *RHS) {
+ set(RHS);
+ return RHS;
+ }
+ const Use &operator=(const Use &RHS) {
+ set(RHS.Val);
+ return *this;
+ }
+
+ Value *operator->() { return Val; }
+ const Value *operator->() const { return Val; }
+
+ Use *getNext() const { return Next; }
+
+
+ /// initTags - initialize the waymarking tags on an array of Uses, so that
+ /// getUser() can find the User from any of those Uses.
+ static Use *initTags(Use *Start, Use *Stop);
+
+ /// zap - This is used to destroy Use operands when the number of operands of
+ /// a User changes.
+ static void zap(Use *Start, const Use *Stop, bool del = false);
+
+private:
+ const Use* getImpliedUser() const;
+
+ Value *Val;
+ Use *Next;
+ PointerIntPair<Use**, 2, PrevPtrTag> Prev;
+
+ void setPrev(Use **NewPrev) {
+ Prev.setPointer(NewPrev);
+ }
+ void addToList(Use **List) {
+ Next = *List;
+ if (Next) Next->setPrev(&Next);
+ setPrev(List);
+ *List = this;
+ }
+ void removeFromList() {
+ Use **StrippedPrev = Prev.getPointer();
+ *StrippedPrev = Next;
+ if (Next) Next->setPrev(StrippedPrev);
+ }
+
+ friend class Value;
+};
+
+// simplify_type - Allow clients to treat uses just like values when using
+// casting operators.
+template<> struct simplify_type<Use> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const Use &Val) {
+ return static_cast<SimpleType>(Val.get());
+ }
+};
+template<> struct simplify_type<const Use> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const Use &Val) {
+ return static_cast<SimpleType>(Val.get());
+ }
+};
+
+
+
+template<typename UserTy> // UserTy == 'User' or 'const User'
+class value_use_iterator : public std::iterator<std::forward_iterator_tag,
+ UserTy*, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag, UserTy*, ptrdiff_t> super;
+ typedef value_use_iterator<UserTy> _Self;
+
+ Use *U;
+ explicit value_use_iterator(Use *u) : U(u) {}
+ friend class Value;
+public:
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ value_use_iterator(const _Self &I) : U(I.U) {}
+ value_use_iterator() {}
+
+ bool operator==(const _Self &x) const {
+ return U == x.U;
+ }
+ bool operator!=(const _Self &x) const {
+ return !operator==(x);
+ }
+
+ /// atEnd - return true if this iterator is equal to use_end() on the value.
+ bool atEnd() const { return U == 0; }
+
+ // Iterator traversal: forward iteration only
+ _Self &operator++() { // Preincrement
+ assert(U && "Cannot increment end iterator!");
+ U = U->getNext();
+ return *this;
+ }
+ _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // Retrieve a pointer to the current User.
+ UserTy *operator*() const {
+ assert(U && "Cannot dereference end iterator!");
+ return U->getUser();
+ }
+
+ UserTy *operator->() const { return operator*(); }
+
+ Use &getUse() const { return *U; }
+
+ /// getOperandNo - Return the operand # of this use in its User. Defined in
+ /// User.h
+ ///
+ unsigned getOperandNo() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/User.h b/contrib/llvm/include/llvm/User.h
new file mode 100644
index 000000000000..c52f32f425c4
--- /dev/null
+++ b/contrib/llvm/include/llvm/User.h
@@ -0,0 +1,177 @@
+//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines the interface that one who 'use's a Value must implement.
+// Each instance of the Value class keeps track of what User's have handles
+// to it.
+//
+// * Instructions are the largest class of User's.
+// * Constants may be users of other constants (think arrays and stuff)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_USER_H
+#define LLVM_USER_H
+
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Value.h"
+
+namespace llvm {
+
+/// OperandTraits - Compile-time customization of
+/// operand-related allocators and accessors
+/// for use of the User class
+template <class>
+struct OperandTraits;
+
+class User : public Value {
+ User(const User &); // Do not implement
+ void *operator new(size_t); // Do not implement
+ template <unsigned>
+ friend struct HungoffOperandTraits;
+ virtual void anchor();
+protected:
+ /// OperandList - This is a pointer to the array of Uses for this User.
+ /// For nodes of fixed arity (e.g. a binary operator) this array will live
+ /// prefixed to some derived class instance. For nodes of resizable variable
+ /// arity (e.g. PHINodes, SwitchInst etc.), this memory will be dynamically
+ /// allocated and should be destroyed by the classes' virtual dtor.
+ Use *OperandList;
+
+ /// NumOperands - The number of values used by this User.
+ ///
+ unsigned NumOperands;
+
+ void *operator new(size_t s, unsigned Us);
+ User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps)
+ : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {}
+ Use *allocHungoffUses(unsigned) const;
+ void dropHungoffUses() {
+ Use::zap(OperandList, OperandList + NumOperands, true);
+ OperandList = 0;
+ // Reset NumOperands so User::operator delete() does the right thing.
+ NumOperands = 0;
+ }
+public:
+ ~User() {
+ Use::zap(OperandList, OperandList + NumOperands);
+ }
+ /// operator delete - free memory allocated for User and Use objects
+ void operator delete(void *Usr);
+ /// placement delete - required by std, but never called.
+ void operator delete(void*, unsigned) {
+ llvm_unreachable("Constructor throws?");
+ }
+ /// placement delete - required by std, but never called.
+ void operator delete(void*, unsigned, bool) {
+ llvm_unreachable("Constructor throws?");
+ }
+protected:
+ template <int Idx, typename U> static Use &OpFrom(const U *that) {
+ return Idx < 0
+ ? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx]
+ : OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx];
+ }
+ template <int Idx> Use &Op() {
+ return OpFrom<Idx>(this);
+ }
+ template <int Idx> const Use &Op() const {
+ return OpFrom<Idx>(this);
+ }
+public:
+ Value *getOperand(unsigned i) const {
+ assert(i < NumOperands && "getOperand() out of range!");
+ return OperandList[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < NumOperands && "setOperand() out of range!");
+ assert((!isa<Constant>((const Value*)this) ||
+ isa<GlobalValue>((const Value*)this)) &&
+ "Cannot mutate a constant with setOperand!");
+ OperandList[i] = Val;
+ }
+ const Use &getOperandUse(unsigned i) const {
+ assert(i < NumOperands && "getOperandUse() out of range!");
+ return OperandList[i];
+ }
+ Use &getOperandUse(unsigned i) {
+ assert(i < NumOperands && "getOperandUse() out of range!");
+ return OperandList[i];
+ }
+
+ unsigned getNumOperands() const { return NumOperands; }
+
+ // ---------------------------------------------------------------------------
+ // Operand Iterator interface...
+ //
+ typedef Use* op_iterator;
+ typedef const Use* const_op_iterator;
+
+ inline op_iterator op_begin() { return OperandList; }
+ inline const_op_iterator op_begin() const { return OperandList; }
+ inline op_iterator op_end() { return OperandList+NumOperands; }
+ inline const_op_iterator op_end() const { return OperandList+NumOperands; }
+
+ // 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
+ // references... First all references are dropped, and all use counts go to
+ // zero. Then everything is deleted for real. Note that no operations are
+ // valid on an object that has "dropped all references", except operator
+ // delete.
+ //
+ void dropAllReferences() {
+ for (op_iterator i = op_begin(), e = op_end(); i != e; ++i)
+ i->set(0);
+ }
+
+ /// replaceUsesOfWith - Replaces all references to the "From" definition with
+ /// references to the "To" definition.
+ ///
+ 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);
+ }
+};
+
+template<> struct simplify_type<User::op_iterator> {
+ typedef Value* SimpleType;
+
+ static SimpleType getSimplifiedValue(const User::op_iterator &Val) {
+ return static_cast<SimpleType>(Val->get());
+ }
+};
+
+template<> struct simplify_type<const User::op_iterator>
+ : public simplify_type<User::op_iterator> {};
+
+template<> struct simplify_type<User::const_op_iterator> {
+ typedef Value* SimpleType;
+
+ static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) {
+ return static_cast<SimpleType>(Val->get());
+ }
+};
+
+template<> struct simplify_type<const User::const_op_iterator>
+ : public simplify_type<User::const_op_iterator> {};
+
+
+// value_use_iterator::getOperandNo - Requires the definition of the User class.
+template<typename UserTy>
+unsigned value_use_iterator<UserTy>::getOperandNo() const {
+ return U - U->getUser()->op_begin();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/Value.h b/contrib/llvm/include/llvm/Value.h
new file mode 100644
index 000000000000..a82ac45c49ed
--- /dev/null
+++ b/contrib/llvm/include/llvm/Value.h
@@ -0,0 +1,415 @@
+//===-- llvm/Value.h - Definition of the Value class ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Value class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_VALUE_H
+#define LLVM_VALUE_H
+
+#include "llvm/Use.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+
+class Constant;
+class Argument;
+class Instruction;
+class BasicBlock;
+class GlobalValue;
+class Function;
+class GlobalVariable;
+class GlobalAlias;
+class InlineAsm;
+class ValueSymbolTable;
+template<typename ValueTy> class StringMapEntry;
+typedef StringMapEntry<Value*> ValueName;
+class raw_ostream;
+class AssemblyAnnotationWriter;
+class ValueHandleBase;
+class LLVMContext;
+class Twine;
+class MDNode;
+class Type;
+class StringRef;
+
+//===----------------------------------------------------------------------===//
+// Value Class
+//===----------------------------------------------------------------------===//
+
+/// This is a very important LLVM class. It is the base class of all values
+/// computed by a program that may be used as operands to other values. Value is
+/// the super class of other important classes such as Instruction and Function.
+/// All Values have a Type. Type is not a subclass of Value. Some values can
+/// have a name and they belong to some Module. Setting the name on the Value
+/// automatically updates the module's symbol table.
+///
+/// Every value has a "use list" that keeps track of which other Values are
+/// using this Value. A Value can also have an arbitrary number of ValueHandle
+/// objects that watch it and listen to RAUW and Destroy events. See
+/// llvm/Support/ValueHandle.h for details.
+///
+/// @brief LLVM Value Representation
+class Value {
+ const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast)
+ unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this?
+protected:
+ /// SubclassOptionalData - This member is similar to SubclassData, however it
+ /// is for holding information which may be used to aid optimization, but
+ /// which may be cleared to zero without affecting conservative
+ /// interpretation.
+ unsigned char SubclassOptionalData : 7;
+
+private:
+ /// SubclassData - This member is defined by this class, but is not used for
+ /// anything. Subclasses can use it to hold whatever state they find useful.
+ /// This field is initialized to zero by the ctor.
+ unsigned short SubclassData;
+
+ Type *VTy;
+ Use *UseList;
+
+ friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
+ friend class ValueHandleBase;
+ ValueName *Name;
+
+ void operator=(const Value &); // Do not implement
+ Value(const Value &); // Do not implement
+
+protected:
+ /// printCustom - Value subclasses can override this to implement custom
+ /// printing behavior.
+ virtual void printCustom(raw_ostream &O) const;
+
+ Value(Type *Ty, unsigned scid);
+public:
+ virtual ~Value();
+
+ /// dump - Support for debugging, callable in GDB: V->dump()
+ //
+ void dump() const;
+
+ /// print - Implement operator<< on Value.
+ ///
+ void print(raw_ostream &O, AssemblyAnnotationWriter *AAW = 0) const;
+
+ /// All values are typed, get the type of this value.
+ ///
+ Type *getType() const { return VTy; }
+
+ /// All values hold a context through their type.
+ LLVMContext &getContext() const;
+
+ // All values can potentially be named.
+ bool hasName() const { return Name != 0 && SubclassID != MDStringVal; }
+ ValueName *getValueName() const { return Name; }
+ void setValueName(ValueName *VN) { Name = VN; }
+
+ /// getName() - Return a constant reference to the value's name. This is cheap
+ /// and guaranteed to return the same reference as long as the value is not
+ /// modified.
+ StringRef getName() const;
+
+ /// 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.
+ void setName(const Twine &Name);
+
+
+ /// takeName - transfer the name from V to this value, setting V's name to
+ /// empty. It is an error to call V->takeName(V).
+ void takeName(Value *V);
+
+ /// replaceAllUsesWith - Go through the uses list for this definition and make
+ /// each use point to "V" instead of "this". After this completes, 'this's
+ /// use list is guaranteed to be empty.
+ ///
+ void replaceAllUsesWith(Value *V);
+
+ //----------------------------------------------------------------------
+ // Methods for handling the chain of uses of this Value.
+ //
+ typedef value_use_iterator<User> use_iterator;
+ typedef value_use_iterator<const User> const_use_iterator;
+
+ bool use_empty() const { return UseList == 0; }
+ use_iterator use_begin() { return use_iterator(UseList); }
+ const_use_iterator use_begin() const { return const_use_iterator(UseList); }
+ use_iterator use_end() { return use_iterator(0); }
+ const_use_iterator use_end() const { return const_use_iterator(0); }
+ User *use_back() { return *use_begin(); }
+ const User *use_back() const { return *use_begin(); }
+
+ /// hasOneUse - Return true if there is exactly one user of this value. This
+ /// is specialized because it is a common request and does not require
+ /// traversing the whole use list.
+ ///
+ bool hasOneUse() const {
+ const_use_iterator I = use_begin(), E = use_end();
+ if (I == E) return false;
+ return ++I == E;
+ }
+
+ /// hasNUses - Return true if this Value has exactly N users.
+ ///
+ bool hasNUses(unsigned N) const;
+
+ /// hasNUsesOrMore - Return true if this value has N users or more. This is
+ /// logically equivalent to getNumUses() >= N.
+ ///
+ bool hasNUsesOrMore(unsigned N) const;
+
+ bool isUsedInBasicBlock(const BasicBlock *BB) const;
+
+ /// getNumUses - This method computes the number of uses of this Value. This
+ /// is a linear time operation. Use hasOneUse, hasNUses, or hasNUsesOrMore
+ /// to check for specific values.
+ unsigned getNumUses() const;
+
+ /// addUse - This method should only be used by the Use class.
+ ///
+ void addUse(Use &U) { U.addToList(&UseList); }
+
+ /// An enumeration for keeping track of the concrete subclass of Value that
+ /// is actually instantiated. Values of this enumeration are kept in the
+ /// Value classes SubclassID field. They are used for concrete type
+ /// identification.
+ enum ValueTy {
+ ArgumentVal, // This is an instance of Argument
+ BasicBlockVal, // This is an instance of BasicBlock
+ FunctionVal, // This is an instance of Function
+ GlobalAliasVal, // This is an instance of GlobalAlias
+ GlobalVariableVal, // This is an instance of GlobalVariable
+ UndefValueVal, // This is an instance of UndefValue
+ BlockAddressVal, // This is an instance of BlockAddress
+ ConstantExprVal, // This is an instance of ConstantExpr
+ ConstantAggregateZeroVal, // This is an instance of ConstantAggregateZero
+ ConstantDataArrayVal, // This is an instance of ConstantDataArray
+ ConstantDataVectorVal, // This is an instance of ConstantDataVector
+ ConstantIntVal, // This is an instance of ConstantInt
+ ConstantFPVal, // This is an instance of ConstantFP
+ ConstantArrayVal, // This is an instance of ConstantArray
+ ConstantStructVal, // This is an instance of ConstantStruct
+ ConstantVectorVal, // This is an instance of ConstantVector
+ ConstantPointerNullVal, // This is an instance of ConstantPointerNull
+ MDNodeVal, // This is an instance of MDNode
+ MDStringVal, // This is an instance of MDString
+ InlineAsmVal, // This is an instance of InlineAsm
+ PseudoSourceValueVal, // This is an instance of PseudoSourceValue
+ FixedStackPseudoSourceValueVal, // This is an instance of
+ // FixedStackPseudoSourceValue
+ InstructionVal, // This is an instance of Instruction
+ // Enum values starting at InstructionVal are used for Instructions;
+ // don't add new values here!
+
+ // Markers:
+ ConstantFirstVal = FunctionVal,
+ ConstantLastVal = ConstantPointerNullVal
+ };
+
+ /// getValueID - Return an ID for the concrete type of this object. This is
+ /// used to implement the classof checks. This should not be used for any
+ /// other purpose, as the values may change as LLVM evolves. Also, note that
+ /// for instructions, the Instruction's opcode is added to InstructionVal. So
+ /// this means three things:
+ /// # there is no value with code InstructionVal (no opcode==0).
+ /// # there are more possible values for the value type than in ValueTy enum.
+ /// # the InstructionVal enumerator must be the highest valued enumerator in
+ /// the ValueTy enum.
+ unsigned getValueID() const {
+ return SubclassID;
+ }
+
+ /// getRawSubclassOptionalData - Return the raw optional flags value
+ /// contained in this value. This should only be used when testing two
+ /// Values for equivalence.
+ unsigned getRawSubclassOptionalData() const {
+ return SubclassOptionalData;
+ }
+
+ /// clearSubclassOptionalData - Clear the optional flags contained in
+ /// this value.
+ void clearSubclassOptionalData() {
+ SubclassOptionalData = 0;
+ }
+
+ /// hasSameSubclassOptionalData - Test whether the optional flags contained
+ /// in this value are equal to the optional flags in the given value.
+ bool hasSameSubclassOptionalData(const Value *V) const {
+ return SubclassOptionalData == V->SubclassOptionalData;
+ }
+
+ /// intersectOptionalDataWith - Clear any optional flags in this value
+ /// that are not also set in the given value.
+ void intersectOptionalDataWith(const Value *V) {
+ SubclassOptionalData &= V->SubclassOptionalData;
+ }
+
+ /// 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
+ /// value. If this is called on a non-pointer value, it returns 'this'.
+ Value *stripPointerCasts();
+ const Value *stripPointerCasts() const {
+ return const_cast<Value*>(this)->stripPointerCasts();
+ }
+
+ /// stripInBoundsConstantOffsets - This method strips off unneeded pointer casts and
+ /// all-constant GEPs from the specified value, returning the original
+ /// pointer value. If this is called on a non-pointer value, it returns
+ /// 'this'.
+ Value *stripInBoundsConstantOffsets();
+ const Value *stripInBoundsConstantOffsets() const {
+ return const_cast<Value*>(this)->stripInBoundsConstantOffsets();
+ }
+
+ /// stripInBoundsOffsets - This method strips off unneeded pointer casts and
+ /// any in-bounds Offsets from the specified value, returning the original
+ /// pointer value. If this is called on a non-pointer value, it returns
+ /// 'this'.
+ Value *stripInBoundsOffsets();
+ const Value *stripInBoundsOffsets() const {
+ return const_cast<Value*>(this)->stripInBoundsOffsets();
+ }
+
+ /// isDereferenceablePointer - Test if this value is always a pointer to
+ /// allocated and suitably aligned memory for a simple load or store.
+ bool isDereferenceablePointer() const;
+
+ /// DoPHITranslation - If this value is a PHI node with CurBB as its parent,
+ /// return the value in the PHI node corresponding to PredBB. If not, return
+ /// ourself. This is useful if you want to know the value something has in a
+ /// predecessor block.
+ Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB);
+
+ const Value *DoPHITranslation(const BasicBlock *CurBB,
+ const BasicBlock *PredBB) const{
+ return const_cast<Value*>(this)->DoPHITranslation(CurBB, PredBB);
+ }
+
+ /// MaximumAlignment - This is the greatest alignment value supported by
+ /// load, store, and alloca instructions, and global values.
+ static const unsigned MaximumAlignment = 1u << 29;
+
+ /// mutateType - Mutate the type of this Value to be of the specified type.
+ /// Note that this is an extremely dangerous operation which can create
+ /// completely invalid IR very easily. It is strongly recommended that you
+ /// recreate IR objects with the right types instead of mutating them in
+ /// place.
+ void mutateType(Type *Ty) {
+ VTy = Ty;
+ }
+
+protected:
+ unsigned short getSubclassDataFromValue() const { return SubclassData; }
+ void setValueSubclassData(unsigned short D) { SubclassData = D; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) {
+ V.print(OS);
+ return OS;
+}
+
+void Use::set(Value *V) {
+ if (Val) removeFromList();
+ Val = V;
+ if (V) V->addUse(*this);
+}
+
+
+// isa - Provide some specializations of isa so that we don't have to include
+// the subtype header files to test to see if the value is a subclass...
+//
+template <> struct isa_impl<Constant, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() >= Value::ConstantFirstVal &&
+ Val.getValueID() <= Value::ConstantLastVal;
+ }
+};
+
+template <> struct isa_impl<Argument, Value> {
+ static inline bool doit (const Value &Val) {
+ return Val.getValueID() == Value::ArgumentVal;
+ }
+};
+
+template <> struct isa_impl<InlineAsm, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() == Value::InlineAsmVal;
+ }
+};
+
+template <> struct isa_impl<Instruction, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() >= Value::InstructionVal;
+ }
+};
+
+template <> struct isa_impl<BasicBlock, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() == Value::BasicBlockVal;
+ }
+};
+
+template <> struct isa_impl<Function, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() == Value::FunctionVal;
+ }
+};
+
+template <> struct isa_impl<GlobalVariable, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() == Value::GlobalVariableVal;
+ }
+};
+
+template <> struct isa_impl<GlobalAlias, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() == Value::GlobalAliasVal;
+ }
+};
+
+template <> struct isa_impl<GlobalValue, Value> {
+ static inline bool doit(const Value &Val) {
+ return isa<GlobalVariable>(Val) || isa<Function>(Val) ||
+ isa<GlobalAlias>(Val);
+ }
+};
+
+template <> struct isa_impl<MDNode, Value> {
+ static inline bool doit(const Value &Val) {
+ return Val.getValueID() == Value::MDNodeVal;
+ }
+};
+
+// Value* is only 4-byte aligned.
+template<>
+class PointerLikeTypeTraits<Value*> {
+ typedef Value* PT;
+public:
+ static inline void *getAsVoidPointer(PT P) { return P; }
+ static inline PT getFromVoidPointer(void *P) {
+ return static_cast<PT>(P);
+ }
+ enum { NumLowBitsAvailable = 2 };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/contrib/llvm/include/llvm/ValueSymbolTable.h b/contrib/llvm/include/llvm/ValueSymbolTable.h
new file mode 100644
index 000000000000..1738cc4a7a79
--- /dev/null
+++ b/contrib/llvm/include/llvm/ValueSymbolTable.h
@@ -0,0 +1,133 @@
+//===-- llvm/ValueSymbolTable.h - Implement a Value Symtab ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the name/Value symbol table for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_VALUE_SYMBOL_TABLE_H
+#define LLVM_VALUE_SYMBOL_TABLE_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+ class BasicBlock;
+ class Function;
+ class NamedMDNode;
+ class Module;
+ class StringRef;
+
+/// This class provides a symbol table of name/value pairs. It is essentially
+/// a std::map<std::string,Value*> but has a controlled interface provided by
+/// LLVM as well as ensuring uniqueness of names.
+///
+class ValueSymbolTable {
+ friend class Value;
+ friend class SymbolTableListTraits<Argument, Function>;
+ friend class SymbolTableListTraits<BasicBlock, Function>;
+ friend class SymbolTableListTraits<Instruction, BasicBlock>;
+ friend class SymbolTableListTraits<Function, Module>;
+ friend class SymbolTableListTraits<GlobalVariable, Module>;
+ friend class SymbolTableListTraits<GlobalAlias, Module>;
+/// @name Types
+/// @{
+public:
+ /// @brief A mapping of names to values.
+ typedef StringMap<Value*> ValueMap;
+
+ /// @brief An iterator over a ValueMap.
+ typedef ValueMap::iterator iterator;
+
+ /// @brief A const_iterator over a ValueMap.
+ typedef ValueMap::const_iterator const_iterator;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+
+ ValueSymbolTable() : vmap(0), LastUnique(0) {}
+ ~ValueSymbolTable();
+
+/// @}
+/// @name Accessors
+/// @{
+public:
+
+ /// This method finds the value with the given \p Name in the
+ /// the symbol table.
+ /// @returns the value associated with the \p Name
+ /// @brief Lookup a named Value.
+ Value *lookup(StringRef Name) const { return vmap.lookup(Name); }
+
+ /// @returns true iff the symbol table is empty
+ /// @brief Determine if the symbol table is empty
+ inline bool empty() const { return vmap.empty(); }
+
+ /// @brief The number of name/type pairs is returned.
+ inline unsigned size() const { return unsigned(vmap.size()); }
+
+ /// This function can be used from the debugger to display the
+ /// content of the symbol table while debugging.
+ /// @brief Print out symbol table on stderr
+ void dump() const;
+
+/// @}
+/// @name Iteration
+/// @{
+public:
+ /// @brief Get an iterator that from the beginning of the symbol table.
+ inline iterator begin() { return vmap.begin(); }
+
+ /// @brief Get a const_iterator that from the beginning of the symbol table.
+ inline const_iterator begin() const { return vmap.begin(); }
+
+ /// @brief Get an iterator to the end of the symbol table.
+ inline iterator end() { return vmap.end(); }
+
+ /// @brief Get a const_iterator to the end of the symbol table.
+ inline const_iterator end() const { return vmap.end(); }
+
+/// @}
+/// @name Mutators
+/// @{
+private:
+ /// This method adds the provided value \p N to the symbol table. The Value
+ /// must have a name which is used to place the value in the symbol table.
+ /// If the inserted name conflicts, this renames the value.
+ /// @brief Add a named value to the symbol table
+ void reinsertValue(Value *V);
+
+ /// createValueName - This method attempts to create a value name and insert
+ /// it into the symbol table with the specified name. If it conflicts, it
+ /// auto-renames the name and returns that instead.
+ ValueName *createValueName(StringRef Name, Value *V);
+
+ /// This method removes a value from the symbol table. It leaves the
+ /// ValueName attached to the value, but it is no longer inserted in the
+ /// symtab.
+ void removeValueName(ValueName *V);
+
+/// @}
+/// @name Internal Data
+/// @{
+private:
+ ValueMap vmap; ///< The map that holds the symbol table.
+ mutable uint32_t LastUnique; ///< Counter for tracking unique names
+
+/// @}
+};
+
+} // End llvm namespace
+
+#endif