aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /include
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Core.h34
-rw-r--r--include/llvm-c/Disassembler.h24
-rw-r--r--include/llvm-c/ExecutionEngine.h2
-rw-r--r--include/llvm-c/IRReader.h2
-rw-r--r--include/llvm-c/Support.h21
-rw-r--r--include/llvm-c/TargetMachine.h5
-rw-r--r--include/llvm-c/Transforms/Scalar.h3
-rw-r--r--include/llvm-c/lto.h160
-rw-r--r--include/llvm/ADT/APFloat.h4
-rw-r--r--include/llvm/ADT/APInt.h35
-rw-r--r--include/llvm/ADT/APSInt.h14
-rw-r--r--include/llvm/ADT/ArrayRef.h10
-rw-r--r--include/llvm/ADT/BitVector.h24
-rw-r--r--include/llvm/ADT/DenseMap.h43
-rw-r--r--include/llvm/ADT/DenseSet.h9
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h1
-rw-r--r--include/llvm/ADT/FoldingSet.h28
-rw-r--r--include/llvm/ADT/Hashing.h25
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h30
-rw-r--r--include/llvm/ADT/MapVector.h6
-rw-r--r--include/llvm/ADT/Optional.h7
-rw-r--r--include/llvm/ADT/OwningPtr.h18
-rw-r--r--include/llvm/ADT/PointerIntPair.h26
-rw-r--r--include/llvm/ADT/PointerUnion.h2
-rw-r--r--include/llvm/ADT/SCCIterator.h188
-rw-r--r--include/llvm/ADT/STLExtras.h233
-rw-r--r--include/llvm/ADT/SetVector.h5
-rw-r--r--include/llvm/ADT/SmallBitVector.h4
-rw-r--r--include/llvm/ADT/SmallPtrSet.h108
-rw-r--r--include/llvm/ADT/SmallSet.h11
-rw-r--r--include/llvm/ADT/SmallString.h3
-rw-r--r--include/llvm/ADT/SmallVector.h36
-rw-r--r--include/llvm/ADT/SparseBitVector.h2
-rw-r--r--include/llvm/ADT/SparseMultiSet.h17
-rw-r--r--include/llvm/ADT/SparseSet.h14
-rw-r--r--include/llvm/ADT/StringExtras.h7
-rw-r--r--include/llvm/ADT/StringMap.h35
-rw-r--r--include/llvm/ADT/StringRef.h18
-rw-r--r--include/llvm/ADT/TinyPtrVector.h8
-rw-r--r--include/llvm/ADT/Triple.h113
-rw-r--r--include/llvm/ADT/iterator_range.h45
-rw-r--r--include/llvm/ADT/polymorphic_ptr.h117
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h8
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h6
-rw-r--r--include/llvm/Analysis/BlockFrequencyImpl.h54
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfo.h23
-rw-r--r--include/llvm/Analysis/BranchProbabilityInfo.h10
-rw-r--r--include/llvm/Analysis/CFG.h2
-rw-r--r--include/llvm/Analysis/CFGPrinter.h7
-rw-r--r--include/llvm/Analysis/CallGraph.h454
-rw-r--r--include/llvm/Analysis/CallGraphSCCPass.h10
-rw-r--r--include/llvm/Analysis/CaptureTracking.h4
-rw-r--r--include/llvm/Analysis/CodeMetrics.h2
-rw-r--r--include/llvm/Analysis/ConstantsScanner.h2
-rw-r--r--include/llvm/Analysis/DOTGraphTraitsPass.h84
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h28
-rw-r--r--include/llvm/Analysis/DominanceFrontier.h14
-rw-r--r--include/llvm/Analysis/FindUsedTypes.h6
-rw-r--r--include/llvm/Analysis/IVUsers.h14
-rw-r--r--include/llvm/Analysis/InlineCost.h5
-rw-r--r--include/llvm/Analysis/Interval.h3
-rw-r--r--include/llvm/Analysis/IntervalIterator.h2
-rw-r--r--include/llvm/Analysis/IntervalPartition.h10
-rw-r--r--include/llvm/Analysis/LazyCallGraph.h337
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h10
-rw-r--r--include/llvm/Analysis/LibCallAliasAnalysis.h16
-rw-r--r--include/llvm/Analysis/LibCallSemantics.h2
-rw-r--r--include/llvm/Analysis/LoopInfo.h27
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h4
-rw-r--r--include/llvm/Analysis/LoopPass.h29
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h9
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h16
-rw-r--r--include/llvm/Analysis/PHITransAddr.h6
-rw-r--r--include/llvm/Analysis/Passes.h21
-rw-r--r--include/llvm/Analysis/PostDominators.h16
-rw-r--r--include/llvm/Analysis/PtrUseVisitor.h4
-rw-r--r--include/llvm/Analysis/RegionInfo.h42
-rw-r--r--include/llvm/Analysis/RegionIterator.h2
-rw-r--r--include/llvm/Analysis/RegionPass.h27
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h64
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h10
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h22
-rw-r--r--include/llvm/Analysis/TargetFolder.h (renamed from include/llvm/Support/TargetFolder.h)12
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h75
-rw-r--r--include/llvm/Analysis/Verifier.h75
-rw-r--r--include/llvm/AsmParser/Parser.h (renamed from include/llvm/Assembly/Parser.h)6
-rw-r--r--include/llvm/Assembly/PrintModulePass.h48
-rw-r--r--include/llvm/Assembly/Writer.h37
-rw-r--r--include/llvm/Bitcode/BitcodeWriterPass.h51
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h3
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h2
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h27
-rw-r--r--include/llvm/CMakeLists.txt5
-rw-r--r--include/llvm/CodeGen/Analysis.h7
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h78
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h23
-rw-r--r--include/llvm/CodeGen/CommandFlags.h30
-rw-r--r--include/llvm/CodeGen/EdgeBundles.h4
-rw-r--r--include/llvm/CodeGen/FastISel.h12
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h5
-rw-r--r--include/llvm/CodeGen/GCMetadata.h2
-rw-r--r--include/llvm/CodeGen/GCs.h8
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h4
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h6
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h41
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h22
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h91
-rw-r--r--include/llvm/CodeGen/LinkAllAsmWriterComponents.h2
-rw-r--r--include/llvm/CodeGen/LiveInterval.h5
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h13
-rw-r--r--include/llvm/CodeGen/LivePhysRegs.h146
-rw-r--r--include/llvm/CodeGen/LiveRangeEdit.h2
-rw-r--r--include/llvm/CodeGen/LiveRegMatrix.h6
-rw-r--r--include/llvm/CodeGen/LiveRegUnits.h88
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h8
-rw-r--r--include/llvm/CodeGen/LiveVariables.h8
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h18
-rw-r--r--include/llvm/CodeGen/MachineBlockFrequencyInfo.h29
-rw-r--r--include/llvm/CodeGen/MachineBranchProbabilityInfo.h14
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h2
-rw-r--r--include/llvm/CodeGen/MachineDominators.h12
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h52
-rw-r--r--include/llvm/CodeGen/MachineFunction.h28
-rw-r--r--include/llvm/CodeGen/MachineFunctionAnalysis.h12
-rw-r--r--include/llvm/CodeGen/MachineFunctionPass.h8
-rw-r--r--include/llvm/CodeGen/MachineInstr.h76
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h7
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h7
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h2
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h28
-rw-r--r--include/llvm/CodeGen/MachineOperand.h74
-rw-r--r--include/llvm/CodeGen/MachinePassRegistry.h6
-rw-r--r--include/llvm/CodeGen/MachinePostDominators.h7
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h370
-rw-r--r--include/llvm/CodeGen/MachineSSAUpdater.h3
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h526
-rw-r--r--include/llvm/CodeGen/MachineTraceMetrics.h8
-rw-r--r--include/llvm/CodeGen/MachineValueType.h578
-rw-r--r--include/llvm/CodeGen/PBQP/CostAllocator.h147
-rw-r--r--include/llvm/CodeGen/PBQP/Graph.h764
-rw-r--r--include/llvm/CodeGen/PBQP/HeuristicBase.h247
-rw-r--r--include/llvm/CodeGen/PBQP/HeuristicSolver.h618
-rw-r--r--include/llvm/CodeGen/PBQP/Heuristics/Briggs.h468
-rw-r--r--include/llvm/CodeGen/PBQP/Math.h638
-rw-r--r--include/llvm/CodeGen/PBQP/ReductionRules.h191
-rw-r--r--include/llvm/CodeGen/PBQP/RegAllocSolver.h359
-rw-r--r--include/llvm/CodeGen/PBQP/Solution.h6
-rw-r--r--include/llvm/CodeGen/Passes.h25
-rw-r--r--include/llvm/CodeGen/PseudoSourceValue.h10
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h43
-rw-r--r--include/llvm/CodeGen/ResourcePriorityQueue.h22
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h19
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h33
-rw-r--r--include/llvm/CodeGen/ScheduleHazardRecognizer.h16
-rw-r--r--include/llvm/CodeGen/ScoreboardHazardRecognizer.h12
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h44
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h8
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h80
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h16
-rw-r--r--include/llvm/CodeGen/StackMapLivenessAnalysis.h65
-rw-r--r--include/llvm/CodeGen/StackMaps.h54
-rw-r--r--include/llvm/CodeGen/StackProtector.h11
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h158
-rw-r--r--include/llvm/CodeGen/TargetSchedule.h10
-rw-r--r--include/llvm/CodeGen/ValueTypes.h585
-rw-r--r--include/llvm/CodeGen/VirtRegMap.h6
-rw-r--r--include/llvm/Config/config.h.cmake6
-rw-r--r--include/llvm/Config/config.h.in99
-rw-r--r--include/llvm/Config/llvm-config.h.cmake4
-rw-r--r--include/llvm/DebugInfo/DIContext.h3
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h64
-rw-r--r--include/llvm/ExecutionEngine/JITEventListener.h2
-rw-r--r--include/llvm/ExecutionEngine/ObjectBuffer.h13
-rw-r--r--include/llvm/ExecutionEngine/ObjectImage.h9
-rw-r--r--include/llvm/ExecutionEngine/RTDyldMemoryManager.h16
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h25
-rw-r--r--include/llvm/ExecutionEngine/SectionMemoryManager.h15
-rw-r--r--include/llvm/IR/Argument.h10
-rw-r--r--include/llvm/IR/AssemblyAnnotationWriter.h (renamed from include/llvm/Assembly/AssemblyAnnotationWriter.h)4
-rw-r--r--include/llvm/IR/Attributes.h7
-rw-r--r--include/llvm/IR/AutoUpgrade.h (renamed from include/llvm/AutoUpgrade.h)6
-rw-r--r--include/llvm/IR/BasicBlock.h2
-rw-r--r--include/llvm/IR/CFG.h (renamed from include/llvm/Support/CFG.h)74
-rw-r--r--include/llvm/IR/CMakeLists.txt4
-rw-r--r--include/llvm/IR/CallSite.h (renamed from include/llvm/Support/CallSite.h)43
-rw-r--r--include/llvm/IR/CallingConv.h16
-rw-r--r--include/llvm/IR/Constant.h4
-rw-r--r--include/llvm/IR/ConstantFolder.h (renamed from include/llvm/Support/ConstantFolder.h)6
-rw-r--r--include/llvm/IR/ConstantRange.h (renamed from include/llvm/Support/ConstantRange.h)7
-rw-r--r--include/llvm/IR/Constants.h48
-rw-r--r--include/llvm/IR/DIBuilder.h (renamed from include/llvm/DIBuilder.h)66
-rw-r--r--include/llvm/IR/DataLayout.h198
-rw-r--r--include/llvm/IR/DebugInfo.h (renamed from include/llvm/DebugInfo.h)161
-rw-r--r--include/llvm/IR/DebugLoc.h (renamed from include/llvm/Support/DebugLoc.h)14
-rw-r--r--include/llvm/IR/DerivedTypes.h22
-rw-r--r--include/llvm/IR/DiagnosticInfo.h240
-rw-r--r--include/llvm/IR/DiagnosticPrinter.h87
-rw-r--r--include/llvm/IR/Dominators.h190
-rw-r--r--include/llvm/IR/Function.h23
-rw-r--r--include/llvm/IR/GVMaterializer.h (renamed from include/llvm/GVMaterializer.h)6
-rw-r--r--include/llvm/IR/GetElementPtrTypeIterator.h (renamed from include/llvm/Support/GetElementPtrTypeIterator.h)6
-rw-r--r--include/llvm/IR/GlobalAlias.h20
-rw-r--r--include/llvm/IR/GlobalValue.h80
-rw-r--r--include/llvm/IR/GlobalVariable.h8
-rw-r--r--include/llvm/IR/IRBuilder.h45
-rw-r--r--include/llvm/IR/IRPrintingPasses.h85
-rw-r--r--include/llvm/IR/InlineAsm.h5
-rw-r--r--include/llvm/IR/InstIterator.h (renamed from include/llvm/Support/InstIterator.h)6
-rw-r--r--include/llvm/IR/InstVisitor.h (renamed from include/llvm/InstVisitor.h)8
-rw-r--r--include/llvm/IR/InstrTypes.h13
-rw-r--r--include/llvm/IR/Instruction.h26
-rw-r--r--include/llvm/IR/Instructions.h233
-rw-r--r--include/llvm/IR/IntrinsicInst.h9
-rw-r--r--include/llvm/IR/Intrinsics.h10
-rw-r--r--include/llvm/IR/Intrinsics.td58
-rw-r--r--include/llvm/IR/IntrinsicsAArch64.td201
-rw-r--r--include/llvm/IR/IntrinsicsARM.td90
-rw-r--r--include/llvm/IR/IntrinsicsARM64.td628
-rw-r--r--include/llvm/IR/IntrinsicsMips.td46
-rw-r--r--include/llvm/IR/IntrinsicsNVVM.td10
-rw-r--r--include/llvm/IR/IntrinsicsX86.td453
-rw-r--r--include/llvm/IR/IntrinsicsXCore.td3
-rw-r--r--include/llvm/IR/LLVMContext.h35
-rw-r--r--include/llvm/IR/LeakDetector.h (renamed from include/llvm/Support/LeakDetector.h)6
-rw-r--r--include/llvm/IR/LegacyPassManager.h4
-rw-r--r--include/llvm/IR/LegacyPassManagers.h34
-rw-r--r--include/llvm/IR/LegacyPassNameParser.h (renamed from include/llvm/Support/PassNameParser.h)19
-rw-r--r--include/llvm/IR/MDBuilder.h7
-rw-r--r--include/llvm/IR/Mangler.h (renamed from include/llvm/Target/Mangler.h)34
-rw-r--r--include/llvm/IR/Metadata.h57
-rw-r--r--include/llvm/IR/Module.h83
-rw-r--r--include/llvm/IR/NoFolder.h (renamed from include/llvm/Support/NoFolder.h)6
-rw-r--r--include/llvm/IR/Operator.h36
-rw-r--r--include/llvm/IR/PassManager.h1057
-rw-r--r--include/llvm/IR/PatternMatch.h (renamed from include/llvm/Support/PatternMatch.h)98
-rw-r--r--include/llvm/IR/PredIteratorCache.h (renamed from include/llvm/Support/PredIteratorCache.h)8
-rw-r--r--include/llvm/IR/Type.h36
-rw-r--r--include/llvm/IR/Use.h198
-rw-r--r--include/llvm/IR/User.h22
-rw-r--r--include/llvm/IR/Value.h138
-rw-r--r--include/llvm/IR/ValueHandle.h (renamed from include/llvm/Support/ValueHandle.h)6
-rw-r--r--include/llvm/IR/ValueMap.h (renamed from include/llvm/ADT/ValueMap.h)14
-rw-r--r--include/llvm/IR/Verifier.h75
-rw-r--r--include/llvm/InitializePasses.h18
-rw-r--r--include/llvm/LTO/LTOCodeGenerator.h28
-rw-r--r--include/llvm/LTO/LTOModule.h48
-rw-r--r--include/llvm/LineEditor/LineEditor.h153
-rw-r--r--include/llvm/LinkAllIR.h2
-rw-r--r--include/llvm/LinkAllPasses.h10
-rw-r--r--include/llvm/Linker/Linker.h (renamed from include/llvm/Linker.h)10
-rw-r--r--include/llvm/MC/MCAsmBackend.h21
-rw-r--r--include/llvm/MC/MCAsmInfo.h129
-rw-r--r--include/llvm/MC/MCAsmInfoCOFF.h4
-rw-r--r--include/llvm/MC/MCAssembler.h169
-rw-r--r--include/llvm/MC/MCAtom.h8
-rw-r--r--include/llvm/MC/MCCodeEmitter.h4
-rw-r--r--include/llvm/MC/MCContext.h105
-rw-r--r--include/llvm/MC/MCDirectives.h5
-rw-r--r--include/llvm/MC/MCDisassembler.h15
-rw-r--r--include/llvm/MC/MCDwarf.h149
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h46
-rw-r--r--include/llvm/MC/MCELFStreamer.h97
-rw-r--r--include/llvm/MC/MCELFSymbolFlags.h13
-rw-r--r--include/llvm/MC/MCExpr.h34
-rw-r--r--include/llvm/MC/MCExternalSymbolizer.h18
-rw-r--r--include/llvm/MC/MCFixup.h3
-rw-r--r--include/llvm/MC/MCInstrAnalysis.h7
-rw-r--r--include/llvm/MC/MCLinkerOptimizationHint.h194
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h29
-rw-r--r--include/llvm/MC/MCModuleYAML.h3
-rw-r--r--include/llvm/MC/MCObjectDisassembler.h17
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h26
-rw-r--r--include/llvm/MC/MCObjectStreamer.h94
-rw-r--r--include/llvm/MC/MCObjectSymbolizer.h12
-rw-r--r--include/llvm/MC/MCObjectWriter.h1
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h6
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h21
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h4
-rw-r--r--include/llvm/MC/MCSchedule.h17
-rw-r--r--include/llvm/MC/MCSection.h3
-rw-r--r--include/llvm/MC/MCSectionCOFF.h13
-rw-r--r--include/llvm/MC/MCSectionELF.h23
-rw-r--r--include/llvm/MC/MCSectionMachO.h112
-rw-r--r--include/llvm/MC/MCStreamer.h175
-rw-r--r--include/llvm/MC/MCSymbol.h2
-rw-r--r--include/llvm/MC/MCSymbolizer.h10
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h2
-rw-r--r--include/llvm/MC/MCValue.h19
-rw-r--r--include/llvm/MC/MachineLocation.h7
-rw-r--r--include/llvm/Object/Archive.h17
-rw-r--r--include/llvm/Object/Binary.h27
-rw-r--r--include/llvm/Object/COFF.h339
-rw-r--r--include/llvm/Object/COFFYAML.h47
-rw-r--r--include/llvm/Object/ELF.h6
-rw-r--r--include/llvm/Object/ELFObjectFile.h332
-rw-r--r--include/llvm/Object/ELFYAML.h8
-rw-r--r--include/llvm/Object/Error.h6
-rw-r--r--include/llvm/Object/IRObjectFile.h46
-rw-r--r--include/llvm/Object/MachO.h132
-rw-r--r--include/llvm/Object/MachOUniversal.h7
-rw-r--r--include/llvm/Object/ObjectFile.h279
-rw-r--r--include/llvm/Object/RelocVisitor.h70
-rw-r--r--include/llvm/Object/SymbolicFile.h194
-rw-r--r--include/llvm/Option/ArgList.h12
-rw-r--r--include/llvm/Pass.h38
-rw-r--r--include/llvm/PassRegistry.h2
-rw-r--r--include/llvm/PassSupport.h26
-rw-r--r--include/llvm/ProfileData/InstrProf.h56
-rw-r--r--include/llvm/ProfileData/InstrProfReader.h196
-rw-r--r--include/llvm/ProfileData/InstrProfWriter.h49
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h189
-rw-r--r--include/llvm/Support/ARMEHABI.h134
-rw-r--r--include/llvm/Support/AlignOf.h20
-rw-r--r--include/llvm/Support/Allocator.h332
-rw-r--r--include/llvm/Support/ArrayRecycler.h8
-rw-r--r--include/llvm/Support/BlockFrequency.h11
-rw-r--r--include/llvm/Support/COFF.h56
-rw-r--r--include/llvm/Support/Casting.h32
-rw-r--r--include/llvm/Support/CommandLine.h141
-rw-r--r--include/llvm/Support/Compiler.h137
-rw-r--r--include/llvm/Support/Compression.h16
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h21
-rw-r--r--include/llvm/Support/DataFlow.h103
-rw-r--r--include/llvm/Support/Dwarf.h48
-rw-r--r--include/llvm/Support/ELF.h111
-rw-r--r--include/llvm/Support/Endian.h13
-rw-r--r--include/llvm/Support/EndianStream.h39
-rw-r--r--include/llvm/Support/ErrorOr.h89
-rw-r--r--include/llvm/Support/FileOutputBuffer.h5
-rw-r--r--include/llvm/Support/FileSystem.h142
-rw-r--r--include/llvm/Support/FileUtilities.h6
-rw-r--r--include/llvm/Support/Format.h10
-rw-r--r--include/llvm/Support/FormattedStream.h22
-rw-r--r--include/llvm/Support/GCOV.h244
-rw-r--r--include/llvm/Support/GenericDomTree.h (renamed from include/llvm/Analysis/Dominators.h)295
-rw-r--r--include/llvm/Support/GenericDomTreeConstruction.h (renamed from include/llvm/Analysis/DominatorInternals.h)38
-rw-r--r--include/llvm/Support/Host.h2
-rw-r--r--include/llvm/Support/LEB128.h6
-rw-r--r--include/llvm/Support/LineIterator.h84
-rw-r--r--include/llvm/Support/MD5.h3
-rw-r--r--include/llvm/Support/MachO.h69
-rw-r--r--include/llvm/Support/MathExtras.h55
-rw-r--r--include/llvm/Support/Memory.h2
-rw-r--r--include/llvm/Support/MemoryBuffer.h24
-rw-r--r--include/llvm/Support/Path.h6
-rw-r--r--include/llvm/Support/PrettyStackTrace.h4
-rw-r--r--include/llvm/Support/Process.h10
-rw-r--r--include/llvm/Support/Program.h26
-rw-r--r--include/llvm/Support/Recycler.h11
-rw-r--r--include/llvm/Support/Regex.h15
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h34
-rw-r--r--include/llvm/Support/StringRefMemoryObject.h8
-rw-r--r--include/llvm/Support/TargetRegistry.h42
-rw-r--r--include/llvm/Support/TimeValue.h12
-rw-r--r--include/llvm/Support/ToolOutputFile.h2
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h19
-rw-r--r--include/llvm/Support/Valgrind.h10
-rw-r--r--include/llvm/Support/Win64EH.h8
-rw-r--r--include/llvm/Support/YAMLParser.h57
-rw-r--r--include/llvm/Support/YAMLTraits.h243
-rw-r--r--include/llvm/Support/circular_raw_ostream.h4
-rw-r--r--include/llvm/Support/raw_os_ostream.h4
-rw-r--r--include/llvm/Support/raw_ostream.h32
-rw-r--r--include/llvm/Support/system_error.h52
-rw-r--r--include/llvm/Support/type_traits.h196
-rw-r--r--include/llvm/TableGen/Error.h4
-rw-r--r--include/llvm/TableGen/Record.h496
-rw-r--r--include/llvm/Target/Target.td44
-rw-r--r--include/llvm/Target/TargetCallingConv.h6
-rw-r--r--include/llvm/Target/TargetCallingConv.td14
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h24
-rw-r--r--include/llvm/Target/TargetLowering.h157
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h139
-rw-r--r--include/llvm/Target/TargetMachine.h42
-rw-r--r--include/llvm/Target/TargetOpcodes.h168
-rw-r--r--include/llvm/Target/TargetOptions.h79
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h26
-rw-r--r--include/llvm/Target/TargetSchedule.td48
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td15
-rw-r--r--include/llvm/Target/TargetSelectionDAGInfo.h4
-rw-r--r--include/llvm/Transforms/IPO.h12
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h6
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h1
-rw-r--r--include/llvm/Transforms/Instrumentation.h8
-rw-r--r--include/llvm/Transforms/Scalar.h29
-rw-r--r--include/llvm/Transforms/Utils/ASanStackFrameLayout.h64
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h39
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h8
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h14
-rw-r--r--include/llvm/Transforms/Utils/CmpInstAnalysis.h2
-rw-r--r--include/llvm/Transforms/Utils/IntegerDivision.h39
-rw-r--r--include/llvm/Transforms/Utils/Local.h2
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h39
-rw-r--r--include/llvm/Transforms/Utils/SSAUpdaterImpl.h2
-rw-r--r--include/llvm/Transforms/Utils/SimplifyIndVar.h19
-rw-r--r--include/llvm/Transforms/Utils/SpecialCaseList.h6
-rw-r--r--include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h4
-rw-r--r--include/llvm/Transforms/Utils/UnrollLoop.h4
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h2
-rw-r--r--include/llvm/Transforms/Vectorize.h3
401 files changed, 15480 insertions, 9062 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index 9953d52..50c5e3a 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -15,7 +15,7 @@
#ifndef LLVM_C_CORE_H
#define LLVM_C_CORE_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm-c/Support.h"
#ifdef __cplusplus
extern "C" {
@@ -62,8 +62,6 @@ extern "C" {
* @{
*/
-typedef int LLVMBool;
-
/* Opaque types. */
/**
@@ -114,13 +112,6 @@ typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
*/
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;
@@ -167,7 +158,8 @@ typedef enum {
LLVMAddressSafety = 1ULL << 32,
LLVMStackProtectStrongAttribute = 1ULL<<33,
LLVMCold = 1ULL << 34,
- LLVMOptimizeNone = 1ULL << 35
+ LLVMOptimizeNone = 1ULL << 35,
+ LLVMInAllocaAttribute = 1ULL << 36
*/
} LLVMAttribute;
@@ -283,8 +275,8 @@ typedef enum {
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 */
+ LLVMDLLImportLinkage, /**< Obsolete */
+ LLVMDLLExportLinkage, /**< Obsolete */
LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */
LLVMGhostLinkage, /**< Obsolete */
LLVMCommonLinkage, /**< Tentative definitions */
@@ -299,6 +291,12 @@ typedef enum {
} LLVMVisibility;
typedef enum {
+ LLVMDefaultStorageClass = 0,
+ LLVMDLLImportStorageClass = 1, /**< Function to be imported from DLL. */
+ LLVMDLLExportStorageClass = 2 /**< Function to be accessible from DLL. */
+} LLVMDLLStorageClass;
+
+typedef enum {
LLVMCCallConv = 0,
LLVMFastCallConv = 8,
LLVMColdCallConv = 9,
@@ -1688,6 +1686,10 @@ const char *LLVMGetSection(LLVMValueRef Global);
void LLVMSetSection(LLVMValueRef Global, const char *Section);
LLVMVisibility LLVMGetVisibility(LLVMValueRef Global);
void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz);
+LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global);
+void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class);
+LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global);
+void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr);
/**
* @defgroup LLVMCCoreValueWithAlignment Values with alignment
@@ -1698,6 +1700,7 @@ void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz);
/**
* Obtain the preferred alignment of the value.
+ * @see llvm::AllocaInst::getAlignment()
* @see llvm::LoadInst::getAlignment()
* @see llvm::StoreInst::getAlignment()
* @see llvm::GlobalValue::getAlignment()
@@ -1706,6 +1709,7 @@ unsigned LLVMGetAlignment(LLVMValueRef V);
/**
* Set the preferred alignment of the value.
+ * @see llvm::AllocaInst::setAlignment()
* @see llvm::LoadInst::setAlignment()
* @see llvm::StoreInst::setAlignment()
* @see llvm::GlobalValue::setAlignment()
@@ -2663,7 +2667,9 @@ LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef Val,
const char *Name);
LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef LHS,
LLVMValueRef RHS, const char *Name);
-LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op,
+LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering ordering,
+ LLVMBool singleThread, const char *Name);
+LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B, LLVMAtomicRMWBinOp op,
LLVMValueRef PTR, LLVMValueRef Val,
LLVMAtomicOrdering ordering,
LLVMBool singleThread);
diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h
index 79bcfcd..8f31150 100644
--- a/include/llvm-c/Disassembler.h
+++ b/include/llvm-c/Disassembler.h
@@ -96,6 +96,16 @@ struct LLVMOpInfo1 {
#define LLVMDisassembler_VariantKind_ARM_LO16 2 /* :lower16: */
/**
+ * The ARM64 target VariantKinds.
+ */
+#define LLVMDisassembler_VariantKind_ARM64_PAGE 1 /* @page */
+#define LLVMDisassembler_VariantKind_ARM64_PAGEOFF 2 /* @pageoff */
+#define LLVMDisassembler_VariantKind_ARM64_GOTPAGE 3 /* @gotpage */
+#define LLVMDisassembler_VariantKind_ARM64_GOTPAGEOFF 4 /* @gotpageoff */
+#define LLVMDisassembler_VariantKind_ARM64_TLVP 5 /* @tvlppage */
+#define LLVMDisassembler_VariantKind_ARM64_TLVOFF 6 /* @tvlppageoff */
+
+/**
* 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.
@@ -123,6 +133,17 @@ typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
/* The input reference is from a PC relative load instruction. */
#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2
+/* The input reference is from an ARM64::ADRP instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_ADRP 0x100000001
+/* The input reference is from an ARM64::ADDXri instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_ADDXri 0x100000002
+/* The input reference is from an ARM64::LDRXui instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_LDRXui 0x100000003
+/* The input reference is from an ARM64::LDRXl instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_LDRXl 0x100000004
+/* The input reference is from an ARM64::ADR instruction. */
+#define LLVMDisassembler_ReferenceType_In_ARM64_ADR 0x100000005
+
/* 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. */
@@ -141,6 +162,9 @@ typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo,
/* The output reference is to a Objective-C class ref. */
#define LLVMDisassembler_ReferenceType_Out_Objc_Class_Ref 8
+/* The output reference is to a C++ symbol name. */
+#define LLVMDisassembler_ReferenceType_DeMangled_Name 9
+
#ifdef __cplusplus
extern "C" {
#endif /* !defined(__cplusplus) */
diff --git a/include/llvm-c/ExecutionEngine.h b/include/llvm-c/ExecutionEngine.h
index 3564312..7cdf0d7 100644
--- a/include/llvm-c/ExecutionEngine.h
+++ b/include/llvm-c/ExecutionEngine.h
@@ -163,6 +163,8 @@ void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
LLVMValueRef Fn);
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE);
+LLVMTargetMachineRef
+LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE);
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
void* Addr);
diff --git a/include/llvm-c/IRReader.h b/include/llvm-c/IRReader.h
index d0a23be..5001afb 100644
--- a/include/llvm-c/IRReader.h
+++ b/include/llvm-c/IRReader.h
@@ -24,7 +24,7 @@ extern "C" {
* Read LLVM IR from a memory buffer and convert it into an in-memory Module
* object. Returns 0 on success.
* Optionally returns a human-readable description of any errors that
- * occured during parsing IR. OutMessage must be disposed with
+ * occurred during parsing IR. OutMessage must be disposed with
* LLVMDisposeMessage.
*
* @see llvm::ParseIR()
diff --git a/include/llvm-c/Support.h b/include/llvm-c/Support.h
index 7f03ede..4e6ff22 100644
--- a/include/llvm-c/Support.h
+++ b/include/llvm-c/Support.h
@@ -14,13 +14,32 @@
#ifndef LLVM_C_SUPPORT_H
#define LLVM_C_SUPPORT_H
-#include "llvm-c/Core.h"
+#include "llvm/Support/DataTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
+ * @defgroup LLVMCSupportTypes Types and Enumerations
+ *
+ * @{
+ */
+
+typedef int LLVMBool;
+
+/**
+ * Used to pass regions of memory through LLVM interfaces.
+ *
+ * @see llvm::MemoryBuffer
+ */
+typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
+
+/**
+ * @}
+ */
+
+/**
* This function permanently loads the dynamic library at the given path.
* It is safe to call this function multiple times for the same library.
*
diff --git a/include/llvm-c/TargetMachine.h b/include/llvm-c/TargetMachine.h
index e159411..d4993e7 100644
--- a/include/llvm-c/TargetMachine.h
+++ b/include/llvm-c/TargetMachine.h
@@ -62,7 +62,7 @@ LLVMTargetRef LLVMGetFirstTarget(void);
LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T);
/*===-- Target ------------------------------------------------------------===*/
-/** Finds the target corresponding to the given name and stores it in \p T.
+/** Finds the target corresponding to the given name and stores it in \p T.
Returns 0 on success. */
LLVMTargetRef LLVMGetTargetFromName(const char *Name);
@@ -137,6 +137,9 @@ LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleR
disposed with LLVMDisposeMessage. */
char* LLVMGetDefaultTargetTriple(void);
+/** Adds the target-specific analysis passes to the pass manager. */
+void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h
index 355e8dc..9b820b2 100644
--- a/include/llvm-c/Transforms/Scalar.h
+++ b/include/llvm-c/Transforms/Scalar.h
@@ -41,6 +41,9 @@ void LLVMAddCFGSimplificationPass(LLVMPassManagerRef PM);
/** See llvm::createDeadStoreEliminationPass function. */
void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef PM);
+/** See llvm::createScalarizerPass function. */
+void LLVMAddScalarizerPass(LLVMPassManagerRef PM);
+
/** See llvm::createGVNPass function. */
void LLVMAddGVNPass(LLVMPassManagerRef PM);
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
index 89f54b7..049c4d7 100644
--- a/include/llvm-c/lto.h
+++ b/include/llvm-c/lto.h
@@ -40,8 +40,11 @@ typedef bool lto_bool_t;
* @{
*/
-#define LTO_API_VERSION 5
+#define LTO_API_VERSION 10
+/**
+ * \since prior to LTO_API_VERSION=3
+ */
typedef enum {
LTO_SYMBOL_ALIGNMENT_MASK = 0x0000001F, /* log2 of alignment */
LTO_SYMBOL_PERMISSIONS_MASK = 0x000000E0,
@@ -62,18 +65,23 @@ typedef enum {
LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800
} lto_symbol_attributes;
+/**
+ * \since prior to LTO_API_VERSION=3
+ */
typedef enum {
LTO_DEBUG_MODEL_NONE = 0,
LTO_DEBUG_MODEL_DWARF = 1
} lto_debug_model;
+/**
+ * \since prior to LTO_API_VERSION=3
+ */
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;
@@ -86,6 +94,8 @@ extern "C" {
/**
* Returns a printable string.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern const char*
lto_get_version(void);
@@ -93,12 +103,16 @@ lto_get_version(void);
/**
* Returns the last error string or NULL if last operation was successful.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern const char*
lto_get_error_message(void);
/**
* Checks if a file is a loadable object file.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
lto_module_is_object_file(const char* path);
@@ -106,6 +120,8 @@ lto_module_is_object_file(const char* path);
/**
* Checks if a file is a loadable object compiled for requested target.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
lto_module_is_object_file_for_target(const char* path,
@@ -114,6 +130,8 @@ lto_module_is_object_file_for_target(const char* path,
/**
* Checks if a buffer is a loadable object file.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
lto_module_is_object_file_in_memory(const void* mem, size_t length);
@@ -121,6 +139,8 @@ 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.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length,
@@ -130,6 +150,8 @@ lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length,
/**
* Loads an object file from disk.
* Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_module_t
lto_module_create(const char* path);
@@ -138,13 +160,27 @@ lto_module_create(const char* path);
/**
* Loads an object file from memory.
* Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_module_t
lto_module_create_from_memory(const void* mem, size_t length);
/**
+ * Loads an object file from memory with an extra path argument.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=9
+ */
+extern lto_module_t
+lto_module_create_from_memory_with_path(const void* mem, size_t length,
+ const char *path);
+
+/**
* 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).
+ *
+ * \since LTO_API_VERSION=5
*/
extern lto_module_t
lto_module_create_from_fd(int fd, const char *path, size_t file_size);
@@ -152,28 +188,34 @@ 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).
+ *
+ * \since LTO_API_VERSION=5
*/
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.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern void
lto_module_dispose(lto_module_t mod);
-
/**
* Returns triple string which the object module was compiled under.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern const char*
lto_module_get_target_triple(lto_module_t mod);
/**
* Sets triple string with which the object will be codegened.
+ *
+ * \since LTO_API_VERSION=4
*/
extern void
lto_module_set_target_triple(lto_module_t mod, const char *triple);
@@ -181,6 +223,8 @@ lto_module_set_target_triple(lto_module_t mod, const char *triple);
/**
* Returns the number of symbols in the object module.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern unsigned int
lto_module_get_num_symbols(lto_module_t mod);
@@ -188,6 +232,8 @@ lto_module_get_num_symbols(lto_module_t mod);
/**
* Returns the name of the ith symbol in the object module.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern const char*
lto_module_get_symbol_name(lto_module_t mod, unsigned int index);
@@ -195,40 +241,116 @@ lto_module_get_symbol_name(lto_module_t mod, unsigned int index);
/**
* Returns the attributes of the ith symbol in the object module.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_symbol_attributes
lto_module_get_symbol_attribute(lto_module_t mod, unsigned int index);
/**
+ * Returns the number of dependent libraries in the object module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern unsigned int
+lto_module_get_num_deplibs(lto_module_t mod);
+
+
+/**
+ * Returns the ith dependent library in the module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern const char*
+lto_module_get_deplib(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Returns the number of linker options in the object module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern unsigned int
+lto_module_get_num_linkeropts(lto_module_t mod);
+
+
+/**
+ * Returns the ith linker option in the module.
+ *
+ * \since LTO_API_VERSION=8
+ */
+extern const char*
+lto_module_get_linkeropt(lto_module_t mod, unsigned int index);
+
+
+/**
+ * Diagnostic severity.
+ *
+ * \since LTO_API_VERSION=7
+ */
+typedef enum {
+ LTO_DS_ERROR = 0,
+ LTO_DS_WARNING = 1,
+ LTO_DS_REMARK = 3, // Added in LTO_API_VERSION=10.
+ LTO_DS_NOTE = 2
+} lto_codegen_diagnostic_severity_t;
+
+/**
+ * Diagnostic handler type.
+ * \p severity defines the severity.
+ * \p diag is the actual diagnostic.
+ * The diagnostic is not prefixed by any of severity keyword, e.g., 'error: '.
+ * \p ctxt is used to pass the context set with the diagnostic handler.
+ *
+ * \since LTO_API_VERSION=7
+ */
+typedef void (*lto_diagnostic_handler_t)(
+ lto_codegen_diagnostic_severity_t severity, const char *diag, void *ctxt);
+
+/**
+ * Set a diagnostic handler and the related context (void *).
+ * This is more general than lto_get_error_message, as the diagnostic handler
+ * can be called at anytime within lto.
+ *
+ * \since LTO_API_VERSION=7
+ */
+extern void lto_codegen_set_diagnostic_handler(lto_code_gen_t,
+ lto_diagnostic_handler_t,
+ void *);
+
+/**
* Instantiates a code generator.
* Returns NULL on error (check lto_get_error_message() for details).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
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.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
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).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
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).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model);
@@ -237,6 +359,8 @@ 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).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern lto_bool_t
lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model);
@@ -244,6 +368,8 @@ lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model);
/**
* Sets the cpu to generate code for.
+ *
+ * \since LTO_API_VERSION=4
*/
extern void
lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu);
@@ -252,12 +378,16 @@ 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.
+ *
+ * \since LTO_API_VERSION=3
*/
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.
+ *
+ * \since LTO_API_VERSION=4
*/
extern void
lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
@@ -266,6 +396,8 @@ lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
/**
* Tells LTO optimization passes that this symbol must be preserved
* because it is referenced by native code or a command line option.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern void
lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
@@ -274,6 +406,8 @@ 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).
+ *
+ * \since LTO_API_VERSION=5
*/
extern lto_bool_t
lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
@@ -285,6 +419,8 @@ lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
* 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).
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern const void*
lto_codegen_compile(lto_code_gen_t cg, size_t* length);
@@ -292,6 +428,8 @@ 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.
+ *
+ * \since LTO_API_VERSION=5
*/
extern lto_bool_t
lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
@@ -299,6 +437,8 @@ lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
/**
* Sets options to help debug codegen bugs.
+ *
+ * \since prior to LTO_API_VERSION=3
*/
extern void
lto_codegen_debug_options(lto_code_gen_t cg, const char *);
@@ -306,6 +446,8 @@ lto_codegen_debug_options(lto_code_gen_t cg, const char *);
/**
* Initializes LLVM disassemblers.
* FIXME: This doesn't really belong here.
+ *
+ * \since LTO_API_VERSION=5
*/
extern void
lto_initialize_disassembler(void);
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 43a7866..acfefe9 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -1,4 +1,4 @@
-//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
+//===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -196,6 +196,7 @@ public:
explicit APFloat(double d);
explicit APFloat(float f);
APFloat(const APFloat &);
+ APFloat(APFloat &&);
~APFloat();
/// @}
@@ -411,6 +412,7 @@ public:
/// @}
APFloat &operator=(const APFloat &);
+ APFloat &operator=(APFloat &&);
/// \brief Overload to compute a hash code for an APFloat value.
///
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index d494ad2..aa3c3f6 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -284,12 +284,10 @@ public:
initSlowCase(that);
}
-#if LLVM_HAS_RVALUE_REFERENCES
/// \brief Move Constructor.
APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) {
that.BitWidth = 0;
}
-#endif
/// \brief Destructor.
~APInt() {
@@ -656,7 +654,6 @@ public:
return AssignSlowCase(RHS);
}
-#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move assignment operator.
APInt &operator=(APInt &&that) {
if (!isSingleWord())
@@ -669,7 +666,6 @@ public:
return *this;
}
-#endif
/// \brief Assignment operator.
///
@@ -1265,7 +1261,7 @@ public:
/// \returns the number of words to hold the integer value with a given bit
/// width.
static unsigned getNumWords(unsigned BitWidth) {
- return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
}
/// \brief Compute the number of active bits in the value
@@ -1504,6 +1500,35 @@ public:
return BitWidth - (*this - 1).countLeadingZeros();
}
+ /// \returns the nearest log base 2 of this APInt. Ties round up.
+ ///
+ /// NOTE: When we have a BitWidth of 1, we define:
+ ///
+ /// log2(0) = UINT32_MAX
+ /// log2(1) = 0
+ ///
+ /// to get around any mathematical concerns resulting from
+ /// referencing 2 in a space where 2 does no exist.
+ unsigned nearestLogBase2() const {
+ // Special case when we have a bitwidth of 1. If VAL is 1, then we
+ // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to
+ // UINT32_MAX.
+ if (BitWidth == 1)
+ return VAL - 1;
+
+ // Handle the zero case.
+ if (!getBoolValue())
+ return UINT32_MAX;
+
+ // The non-zero case is handled by computing:
+ //
+ // nearestLogBase2(x) = logBase2(x) + x[logBase2(x)-1].
+ //
+ // where x[i] is referring to the value of the ith bit of x.
+ unsigned lg = logBase2();
+ return lg + unsigned((*this)[lg - 1]);
+ }
+
/// \returns the log base 2 of this APInt if its an exact power of two, -1
/// otherwise
int32_t exactLogBase2() const {
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index ad035a7..053deff 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -30,18 +30,12 @@ public:
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) {}
+ explicit APSInt(APInt I, bool isUnsigned = true)
+ : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
- APSInt &operator=(const APSInt &RHS) {
- APInt::operator=(RHS);
- IsUnsigned = RHS.IsUnsigned;
- return *this;
- }
-
- APSInt &operator=(const APInt &RHS) {
+ APSInt &operator=(APInt RHS) {
// Retain our current sign.
- APInt::operator=(RHS);
+ APInt::operator=(std::move(RHS));
return *this;
}
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index e5562c3..fcf280d 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include <vector>
namespace llvm {
@@ -76,7 +77,7 @@ namespace llvm {
/// Construct an ArrayRef from a std::vector.
template<typename A>
/*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
- : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
+ : Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef from a C array.
template <size_t N>
@@ -120,6 +121,13 @@ namespace llvm {
return Data[Length-1];
}
+ // copy - Allocate copy in BumpPtrAllocator and return ArrayRef<T> to it.
+ ArrayRef<T> copy(BumpPtrAllocator &Allocator) {
+ T *Buff = Allocator.Allocate<T>(Length);
+ std::copy(begin(), end(), Buff);
+ return ArrayRef<T>(Buff, Length);
+ }
+
/// equals - Check for element-wise equality.
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 8fb538f..b531820 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -58,14 +58,14 @@ public:
reference& operator=(bool t) {
if (t)
- *WordRef |= 1L << BitPos;
+ *WordRef |= BitWord(1) << BitPos;
else
- *WordRef &= ~(1L << BitPos);
+ *WordRef &= ~(BitWord(1) << BitPos);
return *this;
}
operator bool() const {
- return ((*WordRef) & (1L << BitPos)) ? true : false;
+ return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
}
};
@@ -98,12 +98,10 @@ public:
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
}
-#if LLVM_HAS_RVALUE_REFERENCES
BitVector(BitVector &&RHS)
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
RHS.Bits = 0;
}
-#endif
~BitVector() {
std::free(Bits);
@@ -240,7 +238,7 @@ public:
}
BitVector &set(unsigned Idx) {
- Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
return *this;
}
@@ -267,7 +265,8 @@ public:
Bits[I / BITWORD_SIZE] = ~0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
- Bits[I / BITWORD_SIZE] |= PostfixMask;
+ if (I < E)
+ Bits[I / BITWORD_SIZE] |= PostfixMask;
return *this;
}
@@ -278,7 +277,7 @@ public:
}
BitVector &reset(unsigned Idx) {
- Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
return *this;
}
@@ -305,7 +304,8 @@ public:
Bits[I / BITWORD_SIZE] = 0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
- Bits[I / BITWORD_SIZE] &= ~PostfixMask;
+ if (I < E)
+ Bits[I / BITWORD_SIZE] &= ~PostfixMask;
return *this;
}
@@ -318,7 +318,7 @@ public:
}
BitVector &flip(unsigned Idx) {
- Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
+ Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
return *this;
}
@@ -330,7 +330,7 @@ public:
bool operator[](unsigned Idx) const {
assert (Idx < Size && "Out-of-bounds Bit access.");
- BitWord Mask = 1L << (Idx % BITWORD_SIZE);
+ BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
}
@@ -459,7 +459,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this;
@@ -472,7 +471,6 @@ public:
return *this;
}
-#endif
void swap(BitVector &RHS) {
std::swap(Bits, RHS.Bits);
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index ce322cc..037989f 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -161,7 +161,6 @@ public:
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
-#if LLVM_HAS_RVALUE_REFERENCES
// 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.
@@ -177,8 +176,7 @@ public:
TheBucket);
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
-#endif
-
+
/// insert - Range insertion of pairs.
template<typename InputIt>
void insert(InputIt I, InputIt E) {
@@ -218,7 +216,6 @@ public:
return FindAndConstruct(Key).second;
}
-#if LLVM_HAS_RVALUE_REFERENCES
value_type& FindAndConstruct(KeyT &&Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
@@ -230,7 +227,6 @@ public:
ValueT &operator[](KeyT &&Key) {
return FindAndConstruct(std::move(Key)).second;
}
-#endif
/// isPointerIntoBucketsArray - Return true if the specified pointer points
/// somewhere into the DenseMap's array of buckets (i.e. either to a key or
@@ -289,8 +285,8 @@ protected:
bool FoundVal = LookupBucketFor(B->first, DestBucket);
(void)FoundVal; // silence warning.
assert(!FoundVal && "Key already in new map?");
- DestBucket->first = llvm_move(B->first);
- new (&DestBucket->second) ValueT(llvm_move(B->second));
+ DestBucket->first = std::move(B->first);
+ new (&DestBucket->second) ValueT(std::move(B->second));
incrementNumEntries();
// Free the value.
@@ -403,7 +399,6 @@ private:
return TheBucket;
}
-#if LLVM_HAS_RVALUE_REFERENCES
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
BucketT *TheBucket) {
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
@@ -420,7 +415,6 @@ private:
new (&TheBucket->second) ValueT(std::move(Value));
return TheBucket;
}
-#endif
BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
// If the load of the hash table is more than 3/4, or if fewer than 1/8 of
@@ -555,12 +549,10 @@ public:
copyFrom(other);
}
-#if LLVM_HAS_RVALUE_REFERENCES
DenseMap(DenseMap &&other) : BaseT() {
init(0);
swap(other);
}
-#endif
template<typename InputIt>
DenseMap(const InputIt &I, const InputIt &E) {
@@ -585,7 +577,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
DenseMap& operator=(DenseMap &&other) {
this->destroyAll();
operator delete(Buckets);
@@ -593,7 +584,6 @@ public:
swap(other);
return *this;
}
-#endif
void copyFrom(const DenseMap& other) {
this->destroyAll();
@@ -719,12 +709,10 @@ public:
copyFrom(other);
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap(SmallDenseMap &&other) : BaseT() {
init(0);
swap(other);
}
-#endif
template<typename InputIt>
SmallDenseMap(const InputIt &I, const InputIt &E) {
@@ -765,10 +753,10 @@ public:
// Swap separately and handle any assymetry.
std::swap(LHSB->first, RHSB->first);
if (hasLHSValue) {
- new (&RHSB->second) ValueT(llvm_move(LHSB->second));
+ new (&RHSB->second) ValueT(std::move(LHSB->second));
LHSB->second.~ValueT();
} else if (hasRHSValue) {
- new (&LHSB->second) ValueT(llvm_move(RHSB->second));
+ new (&LHSB->second) ValueT(std::move(RHSB->second));
RHSB->second.~ValueT();
}
}
@@ -784,7 +772,7 @@ public:
SmallDenseMap &LargeSide = Small ? RHS : *this;
// First stash the large side's rep and move the small side across.
- LargeRep TmpRep = llvm_move(*LargeSide.getLargeRep());
+ LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
LargeSide.getLargeRep()->~LargeRep();
LargeSide.Small = true;
// This is similar to the standard move-from-old-buckets, but the bucket
@@ -794,11 +782,11 @@ public:
for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
BucketT *NewB = &LargeSide.getInlineBuckets()[i],
*OldB = &SmallSide.getInlineBuckets()[i];
- new (&NewB->first) KeyT(llvm_move(OldB->first));
+ new (&NewB->first) KeyT(std::move(OldB->first));
OldB->first.~KeyT();
if (!KeyInfoT::isEqual(NewB->first, EmptyKey) &&
!KeyInfoT::isEqual(NewB->first, TombstoneKey)) {
- new (&NewB->second) ValueT(llvm_move(OldB->second));
+ new (&NewB->second) ValueT(std::move(OldB->second));
OldB->second.~ValueT();
}
}
@@ -806,7 +794,7 @@ public:
// The hard part of moving the small buckets across is done, just move
// the TmpRep into its new home.
SmallSide.Small = false;
- new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep));
+ new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
}
SmallDenseMap& operator=(const SmallDenseMap& other) {
@@ -814,7 +802,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap& operator=(SmallDenseMap &&other) {
this->destroyAll();
deallocateBuckets();
@@ -822,7 +809,6 @@ public:
swap(other);
return *this;
}
-#endif
void copyFrom(const SmallDenseMap& other) {
this->destroyAll();
@@ -830,7 +816,7 @@ public:
Small = true;
if (other.getNumBuckets() > InlineBuckets) {
Small = false;
- allocateBuckets(other.getNumBuckets());
+ new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
}
this->BaseT::copyFrom(other);
}
@@ -866,8 +852,8 @@ public:
!KeyInfoT::isEqual(P->first, TombstoneKey)) {
assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
"Too many inline buckets!");
- new (&TmpEnd->first) KeyT(llvm_move(P->first));
- new (&TmpEnd->second) ValueT(llvm_move(P->second));
+ new (&TmpEnd->first) KeyT(std::move(P->first));
+ new (&TmpEnd->second) ValueT(std::move(P->second));
++TmpEnd;
P->second.~ValueT();
}
@@ -882,7 +868,7 @@ public:
return;
}
- LargeRep OldRep = llvm_move(*getLargeRep());
+ LargeRep OldRep = std::move(*getLargeRep());
getLargeRep()->~LargeRep();
if (AtLeast <= InlineBuckets) {
Small = true;
@@ -991,7 +977,8 @@ class DenseMapIterator {
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
public:
typedef ptrdiff_t difference_type;
- typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
+ typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
+ value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef std::forward_iterator_tag iterator_category;
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index d699ad5..1d8c39c 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -27,7 +27,9 @@ class DenseSet {
typedef DenseMap<ValueT, char, ValueInfoT> MapTy;
MapTy TheMap;
public:
- DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
+ typedef ValueT key_type;
+ typedef ValueT value_type;
+
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
@@ -54,11 +56,6 @@ public:
TheMap.swap(RHS.TheMap);
}
- DenseSet &operator=(const DenseSet &RHS) {
- TheMap = RHS.TheMap;
- return *this;
- }
-
// Iterators.
class Iterator {
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
index 1d81772..2256ee7 100644
--- a/include/llvm/ADT/EquivalenceClasses.h
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -249,7 +249,6 @@ public:
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()!");
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 1b2c94c..188010d 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -18,12 +18,12 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.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
@@ -278,6 +278,8 @@ public:
bool operator==(FoldingSetNodeIDRef) const;
+ bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); }
+
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(FoldingSetNodeIDRef) const;
@@ -331,6 +333,9 @@ public:
bool operator==(const FoldingSetNodeID &RHS) const;
bool operator==(const FoldingSetNodeIDRef RHS) const;
+ bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); }
+ bool operator!=(const FoldingSetNodeIDRef RHS) const { return !(*this ==RHS);}
+
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(const FoldingSetNodeID &RHS) const;
@@ -391,20 +396,20 @@ 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 {
+ void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
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 {
+ bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) const override {
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 {
+ unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
}
@@ -468,20 +473,19 @@ private:
/// 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 {
+ void GetNodeProfile(FoldingSetImpl::Node *N,
+ FoldingSetNodeID &ID) const override {
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 {
+ bool NodeEquals(FoldingSetImpl::Node *N, const FoldingSetNodeID &ID,
+ unsigned IDHash, FoldingSetNodeID &TempID) const override {
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 {
+ unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
+ FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
}
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index e434417..4bffd8e 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -109,7 +109,8 @@ public:
/// 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);
+typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
+hash_value(T value);
/// \brief Compute a hash_code for a pointer's address.
///
@@ -352,24 +353,24 @@ inline size_t get_execution_seed() {
// 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)> {};
+ : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
+ std::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>))> {};
+ : std::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
+typename std::enable_if<is_hashable_data<T>::value, T>::type
get_hashable_data(const T &value) {
return value;
}
@@ -377,7 +378,7 @@ get_hashable_data(const T &value) {
/// 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
+typename std::enable_if<!is_hashable_data<T>::value, size_t>::type
get_hashable_data(const T &value) {
using ::llvm::hash_value;
return hash_value(value);
@@ -451,7 +452,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
/// 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
+typename std::enable_if<is_hashable_data<ValueT>::value, 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);
@@ -734,7 +735,7 @@ inline hash_code hash_integer_value(uint64_t value) {
// 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
+typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
hash_value(T value) {
return ::llvm::hashing::detail::hash_integer_value(value);
}
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index b8b8861..729e37f 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -23,6 +23,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include <atomic>
#include <memory>
namespace llvm {
@@ -88,6 +89,31 @@ namespace llvm {
static void retain(T *obj) { obj->Retain(); }
static void release(T *obj) { obj->Release(); }
};
+
+/// \brief A thread-safe version of \c llvm::RefCountedBase.
+///
+/// A generic base class for objects that wish to have their lifetimes managed
+/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to
+/// obtain such functionality, and are typically handled with
+/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the
+/// management of reference counts.
+template <class Derived>
+class ThreadSafeRefCountedBase {
+ mutable std::atomic<int> RefCount;
+
+protected:
+ ThreadSafeRefCountedBase() : RefCount(0) {}
+
+public:
+ void Retain() const { ++RefCount; }
+
+ void Release() const {
+ int NewRefCount = --RefCount;
+ assert(NewRefCount >= 0 && "Reference count was already zero.");
+ if (NewRefCount == 0)
+ delete static_cast<const Derived*>(this);
+ }
+};
//===----------------------------------------------------------------------===//
/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
@@ -109,7 +135,7 @@ namespace llvm {
template <typename T>
class IntrusiveRefCntPtr {
T* Obj;
- typedef IntrusiveRefCntPtr this_type;
+
public:
typedef T element_type;
@@ -123,7 +149,6 @@ namespace llvm {
retain();
}
-#if LLVM_HAS_RVALUE_REFERENCES
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
S.Obj = 0;
}
@@ -132,7 +157,6 @@ namespace llvm {
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) {
S.Obj = 0;
}
-#endif
template <class X>
IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index f6fcb08..7fd1570 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===//
+//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,9 +17,7 @@
#ifndef LLVM_ADT_MAPVECTOR_H
#define LLVM_ADT_MAPVECTOR_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
#include <vector>
namespace llvm {
@@ -97,7 +95,7 @@ public:
if (Result.second) {
Vector.push_back(std::make_pair(KV.first, KV.second));
I = Vector.size() - 1;
- return std::make_pair(llvm::prior(end()), true);
+ return std::make_pair(std::prev(end()), true);
}
return std::make_pair(begin() + I, false);
}
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 194e53f..ae8344d 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -17,13 +17,10 @@
#define LLVM_ADT_OPTIONAL_H
#include "llvm/ADT/None.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
-
-#if LLVM_HAS_RVALUE_REFERENCES
#include <utility>
-#endif
namespace llvm {
@@ -42,7 +39,6 @@ public:
new (storage.buffer) T(*O);
}
-#if LLVM_HAS_RVALUE_REFERENCES
Optional(T &&y) : hasVal(true) {
new (storage.buffer) T(std::forward<T>(y));
}
@@ -70,7 +66,6 @@ public:
}
return *this;
}
-#endif
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
index 6b9e42e..034bcfd 100644
--- a/include/llvm/ADT/OwningPtr.h
+++ b/include/llvm/ADT/OwningPtr.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
+#include <memory>
namespace llvm {
@@ -32,13 +33,22 @@ class OwningPtr {
public:
explicit OwningPtr(T *P = 0) : Ptr(P) {}
-#if LLVM_HAS_RVALUE_REFERENCES
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
OwningPtr &operator=(OwningPtr &&Other) {
reset(Other.take());
return *this;
}
+
+ OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {}
+
+ OwningPtr &operator=(std::unique_ptr<T> Other) {
+ reset(Other.release());
+ return *this;
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
#endif
~OwningPtr() {
@@ -63,6 +73,10 @@ public:
return Tmp;
}
+ T *release() { return take(); }
+
+ std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
+
T &operator*() const {
assert(Ptr && "Cannot dereference null pointer");
return *Ptr;
@@ -96,14 +110,12 @@ class OwningArrayPtr {
public:
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
-#if LLVM_HAS_RVALUE_REFERENCES
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
reset(Other.take());
return *this;
}
-#endif
~OwningArrayPtr() {
delete [] Ptr;
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index 0cfd470..45a40db 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
+#include <limits>
namespace llvm {
@@ -41,7 +42,12 @@ template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
class PointerIntPair {
intptr_t Value;
- enum LLVM_ENUM_INT_TYPE(uintptr_t) {
+ static_assert(PtrTraits::NumLowBitsAvailable <
+ std::numeric_limits<uintptr_t>::digits,
+ "cannot use a pointer type that has all bits free");
+ static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
+ "PointerIntPair with integer size too large for pointer");
+ enum : uintptr_t {
/// PointerBitMask - The bits that come from the pointer.
PointerBitMask =
~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
@@ -59,8 +65,6 @@ class PointerIntPair {
public:
PointerIntPair() : Value(0) {}
PointerIntPair(PointerTy PtrVal, IntType IntVal) {
- assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
- "PointerIntPair formed with integer size too large for pointer");
setPointerAndInt(PtrVal, IntVal);
}
explicit PointerIntPair(PointerTy PtrVal) {
@@ -79,7 +83,7 @@ public:
void setPointer(PointerTy PtrVal) {
intptr_t PtrWord
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
// Preserve all low bits, just update the pointer.
Value = PtrWord | (Value & ~PointerBitMask);
@@ -87,7 +91,7 @@ public:
void setInt(IntType IntVal) {
intptr_t IntWord = static_cast<intptr_t>(IntVal);
- assert(IntWord < (1 << IntBits) && "Integer too large for field");
+ assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
// Preserve all bits other than the ones we are updating.
Value &= ~ShiftedIntMask; // Remove integer field.
@@ -97,7 +101,7 @@ public:
void initWithPointer(PointerTy PtrVal) {
intptr_t PtrWord
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
Value = PtrWord;
}
@@ -105,10 +109,10 @@ public:
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
intptr_t PtrWord
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
intptr_t IntWord = static_cast<intptr_t>(IntVal);
- assert(IntWord < (1 << IntBits) && "Integer too large for field");
+ assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
Value = PtrWord | (IntWord << IntShift);
}
@@ -158,13 +162,13 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
- Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
- return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
+ Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
+ return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
}
static Ty getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
- return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
+ return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
}
static unsigned getHashValue(Ty V) {
uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index 05d362f..8cbe8d1 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -15,8 +15,8 @@
#ifndef LLVM_ADT_POINTERUNION_H
#define LLVM_ADT_POINTERUNION_H
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
index 8ce4fd5..58ac149 100644
--- a/include/llvm/ADT/SCCIterator.h
+++ b/include/llvm/ADT/SCCIterator.h
@@ -6,16 +6,18 @@
// 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.)
-//
+/// \file
+///
+/// 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
@@ -27,90 +29,111 @@
namespace llvm {
-//===----------------------------------------------------------------------===//
+/// \brief Enumerate the SCCs of a directed graph in reverse topological order
+/// of the SCC DAG.
///
-/// scc_iterator - Enumerate the SCCs of a directed graph, in
-/// reverse topological order of the SCC DAG.
-///
-template<class GraphT, class GT = GraphTraits<GraphT> >
+/// This is implemented using Tarjan's DFS algorithm using an internal stack to
+/// build up a vector of nodes in a particular SCC. Note that it is a forward
+/// iterator and thus you cannot backtrack or re-visit nodes.
+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;
+ : 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::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;
+ // Element of VisitStack during DFS.
+ struct StackElement {
+ NodeType *Node; ///< The current node pointer.
+ ChildItTy NextChild; ///< The next child, modified inplace during DFS.
+ unsigned MinVisited; ///< Minimum uplink value of all children of Node.
+
+ StackElement(NodeType *Node, const ChildItTy &Child, unsigned Min)
+ : Node(Node), NextChild(Child), MinVisited(Min) {}
+
+ bool operator==(const StackElement &Other) const {
+ return Node == Other.Node &&
+ NextChild == Other.NextChild &&
+ MinVisited == Other.MinVisited;
+ }
+ };
+
// 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.
+ // Stack holding nodes of the SCC.
std::vector<NodeType *> SCCNodeStack;
- // CurrentSCC - The current SCC, retrieved using operator*().
+ // 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;
+ // DFS stack, Used to maintain the ordering. The top contains the current
+ // node, the next child to visit, and the minimum uplink value of all child
+ std::vector<StackElement> VisitStack;
// A single "visit" within the non-recursive DFS traversal.
void DFSVisitOne(NodeType *N) {
- ++visitNum; // Global counter for the visit order
+ ++visitNum;
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";
+ VisitStack.push_back(StackElement(N, GT::child_begin(N), visitNum));
+#if 0 // Enable if needed when debugging.
+ dbgs() << "TarjanSCC: Node " << N <<
+ " : visitNum = " << visitNum << "\n";
+#endif
}
// The stack-based DFS traversal; defined below.
void DFSVisitChildren() {
assert(!VisitStack.empty());
- while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ while (VisitStack.back().NextChild !=
+ GT::child_end(VisitStack.back().Node)) {
// TOS has at least one more child so continue DFS
- NodeType *childN = *VisitStack.back().second++;
- if (!nodeVisitNumbers.count(childN)) {
+ NodeType *childN = *VisitStack.back().NextChild++;
+ typename DenseMap<NodeType *, unsigned>::iterator Visited =
+ nodeVisitNumbers.find(childN);
+ if (Visited == nodeVisitNumbers.end()) {
// this node has never been seen.
DFSVisitOne(childN);
continue;
}
- unsigned childNum = nodeVisitNumbers[childN];
- if (MinVisitNumStack.back() > childNum)
- MinVisitNumStack.back() = childNum;
+ unsigned childNum = Visited->second;
+ if (VisitStack.back().MinVisited > childNum)
+ VisitStack.back().MinVisited = childNum;
}
}
// Compute the next SCC using the DFS traversal.
void GetNextSCC() {
- assert(VisitStack.size() == MinVisitNumStack.size());
- CurrentSCC.clear(); // Prepare to compute the next SCC
+ 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();
+
+ // Pop the leaf on top of the VisitStack.
+ NodeType *visitingN = VisitStack.back().Node;
+ unsigned minVisitNum = VisitStack.back().MinVisited;
+ assert(VisitStack.back().NextChild == GT::child_end(visitingN));
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";
+ // Propagate MinVisitNum to parent so we can detect the SCC starting node.
+ if (!VisitStack.empty() && VisitStack.back().MinVisited > minVisitNum)
+ VisitStack.back().MinVisited = minVisitNum;
+
+#if 0 // Enable if needed when debugging.
+ dbgs() << "TarjanSCC: Popped node " << visitingN <<
+ " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+ nodeVisitNumbers[visitingN] << "\n";
+#endif
if (minVisitNum != nodeVisitNumbers[visitingN])
continue;
@@ -132,36 +155,38 @@ class scc_iterator
DFSVisitOne(entryN);
GetNextSCC();
}
- inline scc_iterator() { /* End is when DFS stack is empty */ }
-public:
- typedef scc_iterator<GraphT, GT> _Self;
+ // End is when the DFS stack is empty.
+ inline scc_iterator() {}
- // Provide static "constructors"...
- static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
- static inline _Self end (const GraphT &) { return _Self(); }
+public:
+ static inline scc_iterator begin(const GraphT &G) {
+ return scc_iterator(GT::getEntryNode(G));
+ }
+ static inline scc_iterator end(const GraphT &) { return scc_iterator(); }
- // Direct loop termination test: I.isAtEnd() is more efficient than I == end()
+ /// \brief Direct loop termination test which is more efficient than
+ /// comparison with \c end().
inline bool isAtEnd() const {
assert(!CurrentSCC.empty() || VisitStack.empty());
return CurrentSCC.empty();
}
- inline bool operator==(const _Self& x) const {
+ inline bool operator==(const scc_iterator &x) const {
return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ inline bool operator!=(const scc_iterator &x) const { return !operator==(x); }
- // Iterator traversal: forward iteration only
- inline _Self& operator++() { // Preincrement
+ inline scc_iterator &operator++() {
GetNextSCC();
return *this;
}
- inline _Self operator++(int) { // Postincrement
- _Self tmp = *this; ++*this; return tmp;
+ inline scc_iterator operator++(int) {
+ scc_iterator 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;
@@ -171,21 +196,24 @@ public:
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.
+ /// \brief Test if the current SCC has a loop.
+ ///
+ /// If the SCC 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;
+ 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)
+ 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.
+ /// This informs the \c scc_iterator that the specified \c Old node
+ /// has been deleted, and \c 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];
@@ -193,25 +221,23 @@ public:
}
};
-
-// Global constructor for the SCC iterator.
-template <class T>
-scc_iterator<T> scc_begin(const T &G) {
+/// \brief Construct the begin iterator for a deduced graph type T.
+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) {
+/// \brief Construct the end iterator for a deduced graph type T.
+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) {
+/// \brief Construct the begin iterator for a deduced graph type T's Inverse<T>.
+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) {
+/// \brief Construct the end iterator for a deduced graph type T's Inverse<T>.
+template <class T> scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
return scc_iterator<Inverse<T> >::end(G);
}
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index 3aa8183..ab6884f 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -17,10 +17,12 @@
#ifndef LLVM_ADT_STLEXTRAS_H
#define LLVM_ADT_STLEXTRAS_H
+#include "llvm/Support/Compiler.h"
#include <cstddef> // for std::size_t
#include <cstdlib> // for qsort
#include <functional>
#include <iterator>
+#include <memory>
#include <utility> // for std::pair
namespace llvm {
@@ -95,8 +97,6 @@ public:
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
@@ -141,82 +141,10 @@ 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);
-}
-
/// \brief Function object to check whether the first component of a std::pair
/// compares less than the first component of another std::pair.
struct less_first {
@@ -327,6 +255,163 @@ void DeleteContainerSeconds(Container &C) {
C.clear();
}
+//===----------------------------------------------------------------------===//
+// Extra additions to <memory>
+//===----------------------------------------------------------------------===//
+
+#if LLVM_HAS_VARIADIC_TEMPLATES
+
+// Implement make_unique according to N3656.
+
+/// \brief Constructs a `new T()` with the given args and returns a
+/// `unique_ptr<T>` which owns the object.
+///
+/// Example:
+///
+/// auto p = make_unique<int>();
+/// auto p = make_unique<std::tuple<int, int>>(0, 1);
+template <class T, class... Args>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Args &&... args) {
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+/// \brief Constructs a `new T[n]` with the given args and returns a
+/// `unique_ptr<T[]>` which owns the object.
+///
+/// \param n size of the new array.
+///
+/// Example:
+///
+/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
+template <class T>
+typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
+ std::unique_ptr<T>>::type
+make_unique(size_t n) {
+ return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+/// This function isn't used and is only here to provide better compile errors.
+template <class T, class... Args>
+typename std::enable_if<std::extent<T>::value != 0>::type
+make_unique(Args &&...) LLVM_DELETED_FUNCTION;
+
+#else
+
+template <class T>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique() {
+ return std::unique_ptr<T>(new T());
+}
+
+template <class T, class Arg1>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1) {
+ return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1)));
+}
+
+template <class T, class Arg1, class Arg2>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3) {
+ return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1),
+ std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7, class Arg8>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7), std::forward<Arg8>(arg8)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7, class Arg8, class Arg9>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
+ std::forward<Arg9>(arg9)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7, class Arg8, class Arg9, class Arg10>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9, Arg10 &&arg10) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
+ std::forward<Arg9>(arg9), std::forward<Arg10>(arg10)));
+}
+
+template <class T>
+typename std::enable_if<std::is_array<T>::value &&std::extent<T>::value == 0,
+ std::unique_ptr<T>>::type
+make_unique(size_t n) {
+ return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+#endif
+
} // End llvm namespace
#endif
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
index 5eda37c..1e7d237 100644
--- a/include/llvm/ADT/SetVector.h
+++ b/include/llvm/ADT/SetVector.h
@@ -195,11 +195,10 @@ private:
set_type &set_;
public:
- typedef typename UnaryPredicate::argument_type argument_type;
-
TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
- bool operator()(argument_type Arg) {
+ template <typename ArgumentT>
+ bool operator()(const ArgumentT &Arg) {
if (P(Arg)) {
set_.erase(Arg);
return true;
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index 86949b2..e965bc4 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -153,11 +153,9 @@ public:
switchToLarge(new BitVector(*RHS.getPointer()));
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
RHS.X = 1;
}
-#endif
~SmallBitVector() {
if (!isSmall())
@@ -506,7 +504,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
const SmallBitVector &operator=(SmallBitVector &&RHS) {
if (this != &RHS) {
clear();
@@ -514,7 +511,6 @@ public:
}
return *this;
}
-#endif
void swap(SmallBitVector &RHS) {
std::swap(X, RHS.X);
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index bd0d883..67104f3 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines the SmallPtrSet class. See the doxygen comment for
-// SmallPtrSetImpl for more details on the algorithm used.
+// SmallPtrSetImplBase for more details on the algorithm used.
//
//===----------------------------------------------------------------------===//
@@ -27,7 +27,7 @@ namespace llvm {
class SmallPtrSetIteratorImpl;
-/// SmallPtrSetImpl - This is the common code shared among all the
+/// SmallPtrSetImplBase - 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.
///
@@ -45,7 +45,7 @@ class SmallPtrSetIteratorImpl;
/// (-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 {
+class SmallPtrSetImplBase {
friend class SmallPtrSetIteratorImpl;
protected:
/// SmallArray - Points to a fixed size set of buckets, used in 'small mode'.
@@ -60,15 +60,17 @@ protected:
unsigned NumElements;
unsigned NumTombstones;
- // Helper to copy construct a SmallPtrSet.
- SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that);
- explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) :
+ // Helpers to copy and move construct a SmallPtrSet.
+ SmallPtrSetImplBase(const void **SmallStorage, const SmallPtrSetImplBase &that);
+ SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
+ SmallPtrSetImplBase &&that);
+ explicit SmallPtrSetImplBase(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!");
clear();
}
- ~SmallPtrSetImpl();
+ ~SmallPtrSetImplBase();
public:
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; }
@@ -128,13 +130,14 @@ private:
/// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(unsigned NewSize);
- void operator=(const SmallPtrSetImpl &RHS) LLVM_DELETED_FUNCTION;
+ void operator=(const SmallPtrSetImplBase &RHS) LLVM_DELETED_FUNCTION;
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 swap(SmallPtrSetImplBase &RHS);
- void CopyFrom(const SmallPtrSetImpl &RHS);
+ void CopyFrom(const SmallPtrSetImplBase &RHS);
+ void MoveFrom(unsigned SmallSize, SmallPtrSetImplBase &&RHS);
};
/// SmallPtrSetIteratorImpl - This is the common base class shared between all
@@ -163,8 +166,8 @@ protected:
void AdvanceIfNotValid() {
assert(Bucket <= End);
while (Bucket != End &&
- (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
- *Bucket == SmallPtrSetImpl::getTombstoneMarker()))
+ (*Bucket == SmallPtrSetImplBase::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImplBase::getTombstoneMarker()))
++Bucket;
}
};
@@ -228,26 +231,25 @@ struct RoundUpToPowerOfTwo {
};
-/// 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'.
- const void *SmallStorage[SmallSizePowTwo];
+/// \brief A templated base class for \c SmallPtrSet which provides the
+/// typesafe interface that is common across all small sizes.
+///
+/// This is particularly useful for passing around between interface boundaries
+/// to avoid encoding a particular small size in the interface boundary.
+template <typename PtrType>
+class SmallPtrSetImpl : public SmallPtrSetImplBase {
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);
- }
+protected:
+ // Constructors that forward to the base.
+ SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that)
+ : SmallPtrSetImplBase(SmallStorage, that) {}
+ SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
+ SmallPtrSetImpl &&that)
+ : SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {}
+ explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize)
+ : SmallPtrSetImplBase(SmallStorage, SmallSize) {}
+public:
/// insert - This returns true if the pointer was new to the set, false if it
/// was already in the set.
bool insert(PtrType Ptr) {
@@ -260,9 +262,9 @@ public:
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));
+ /// count - Return 1 if the specified pointer is in the set, 0 otherwise.
+ unsigned count(PtrType Ptr) const {
+ return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
}
template <typename IterT>
@@ -279,18 +281,48 @@ public:
inline iterator end() const {
return iterator(CurArray+CurArraySize, 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>&
+/// 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
+/// SmallPtrSetImplBase for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
+ typedef SmallPtrSetImpl<PtrType> BaseT;
+
+ // 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'.
+ const void *SmallStorage[SmallSizePowTwo];
+public:
+ SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {}
+ SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {}
+ SmallPtrSet(SmallPtrSet &&that)
+ : BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {}
+
+ template<typename It>
+ SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) {
+ this->insert(I, E);
+ }
+
+ SmallPtrSet<PtrType, SmallSize> &
operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
- CopyFrom(RHS);
+ if (&RHS != this)
+ this->CopyFrom(RHS);
+ return *this;
+ }
+
+ SmallPtrSet<PtrType, SmallSize>&
+ operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
+ if (&RHS != this)
+ this->MoveFrom(SmallSizePowTwo, std::move(RHS));
return *this;
}
/// swap - Swaps the elements of two sets.
void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
- SmallPtrSetImpl::swap(RHS);
+ SmallPtrSetImplBase::swap(RHS);
}
};
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index 5dfe924..6f36234 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -39,16 +39,19 @@ class SmallSet {
public:
SmallSet() {}
- bool empty() const { return Vector.empty() && Set.empty(); }
+ bool LLVM_ATTRIBUTE_UNUSED_RESULT 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 {
+ /// count - Return 1 if the element is in the set, 0 otherwise.
+ unsigned count(const T &V) const {
if (isSmall()) {
// Since the collection is small, just do a linear search.
- return vfind(V) != Vector.end();
+ return vfind(V) == Vector.end() ? 0 : 1;
} else {
return Set.count(V);
}
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
index 2cfb5b9..e569f54 100644
--- a/include/llvm/ADT/SmallString.h
+++ b/include/llvm/ADT/SmallString.h
@@ -34,9 +34,6 @@ public:
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.
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 505aa8d..0a4140e 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ADT_SMALLVECTOR_H
#define LLVM_ADT_SMALLVECTOR_H
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
@@ -183,13 +184,9 @@ protected:
/// std::move, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
*Dest = ::std::move(*I);
return Dest;
-#else
- return ::std::copy(I, E, Dest);
-#endif
}
/// move_backward - Use move-assignment to move the range
@@ -198,25 +195,17 @@ protected:
/// std::move_backward, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move_backward(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
while (I != E)
*--Dest = ::std::move(*--E);
return Dest;
-#else
- return ::std::copy_backward(I, E, Dest);
-#endif
}
/// uninitialized_move - Move the range [I, E) into the uninitialized
/// memory starting with "Dest", constructing elements as needed.
template<typename It1, typename It2>
static void uninitialized_move(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
::new ((void*) &*Dest) T(::std::move(*I));
-#else
- ::std::uninitialized_copy(I, E, Dest);
-#endif
}
/// uninitialized_copy - Copy the range [I, E) onto the uninitialized
@@ -244,7 +233,6 @@ public:
goto Retry;
}
-#if LLVM_HAS_RVALUE_REFERENCES
void push_back(T &&Elt) {
if (this->EndX < this->CapacityX) {
Retry:
@@ -255,8 +243,7 @@ public:
this->grow();
goto Retry;
}
-#endif
-
+
void pop_back() {
this->setEnd(this->end()-1);
this->end()->~T();
@@ -428,11 +415,7 @@ public:
}
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
-#if LLVM_HAS_RVALUE_REFERENCES
T Result = ::std::move(this->back());
-#else
- T Result = this->back();
-#endif
this->pop_back();
return Result;
}
@@ -501,7 +484,6 @@ public:
return(N);
}
-#if LLVM_HAS_RVALUE_REFERENCES
iterator insert(iterator I, T &&Elt) {
if (I == this->end()) { // Important special case for empty vector.
this->push_back(::std::move(Elt));
@@ -532,7 +514,6 @@ public:
I = this->begin()+EltNo;
goto Retry;
}
-#endif
iterator insert(iterator I, const T &Elt) {
if (I == this->end()) { // Important special case for empty vector.
@@ -673,9 +654,7 @@ public:
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
-#if LLVM_HAS_RVALUE_REFERENCES
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
-#endif
bool operator==(const SmallVectorImpl &RHS) const {
if (this->size() != RHS.size()) return false;
@@ -793,7 +772,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
template <typename T>
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
// Avoid self-assignment.
@@ -855,7 +833,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
RHS.clear();
return *this;
}
-#endif
/// Storage for the SmallVector elements which aren't contained in
/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
@@ -894,6 +871,12 @@ public:
this->append(S, E);
}
+ template <typename RangeTy>
+ explicit SmallVector(const llvm::iterator_range<RangeTy> R)
+ : SmallVectorImpl<T>(N) {
+ this->append(R.begin(), R.end());
+ }
+
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
@@ -904,7 +887,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
@@ -914,8 +896,6 @@ public:
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
}
-#endif
-
};
template<typename T, unsigned N>
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 7a10f85..706f248 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -382,7 +382,7 @@ class SparseBitVector {
AtEnd = true;
return;
}
- // Set up for next non zero word in bitmap.
+ // Set up for next non-zero word in bitmap.
BitNumber = Iter->index() * ElementSize;
NextSetBitNumber = Iter->find_first();
BitNumber += NextSetBitNumber;
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
index 7f2a6f7..797a898 100644
--- a/include/llvm/ADT/SparseMultiSet.h
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -76,6 +76,10 @@ template<typename ValueT,
typename KeyFunctorT = llvm::identity<unsigned>,
typename SparseT = uint8_t>
class SparseMultiSet {
+ static_assert(std::numeric_limits<SparseT>::is_integer &&
+ !std::numeric_limits<SparseT>::is_signed,
+ "SparseT must be an unsigned integer type");
+
/// The actual data that's stored, as a doubly-linked list implemented via
/// indices into the DenseVector. The doubly linked list is implemented
/// circular in Prev indices, and INVALID-terminated in Next indices. This
@@ -245,16 +249,6 @@ public:
typedef typename super::pointer pointer;
typedef typename super::reference reference;
- iterator_base(const iterator_base &RHS)
- : SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { }
-
- const iterator_base &operator=(const iterator_base &RHS) {
- SMS = RHS.SMS;
- Idx = RHS.Idx;
- SparseIdx = RHS.SparseIdx;
- return *this;
- }
-
reference operator*() const {
assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
"Dereferencing iterator of invalid key or index");
@@ -354,9 +348,6 @@ public:
///
iterator findIndex(unsigned Idx) {
assert(Idx < 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[Idx], e = Dense.size(); i < e; i += Stride) {
const unsigned FoundIdx = sparseIndex(Dense[i]);
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index 267a340..b46ccc9 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -118,6 +118,10 @@ template<typename ValueT,
typename KeyFunctorT = llvm::identity<unsigned>,
typename SparseT = uint8_t>
class SparseSet {
+ static_assert(std::numeric_limits<SparseT>::is_integer &&
+ !std::numeric_limits<SparseT>::is_signed,
+ "SparseT must be an unsigned integer type");
+
typedef typename KeyFunctorT::argument_type KeyT;
typedef SmallVector<ValueT, 8> DenseT;
DenseT Dense;
@@ -198,9 +202,6 @@ public:
///
iterator findIndex(unsigned Idx) {
assert(Idx < 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[Idx], e = size(); i < e; i += Stride) {
const unsigned FoundIdx = ValIndexOf(Dense[i]);
@@ -227,10 +228,11 @@ public:
return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key));
}
- /// count - Returns true if this set contains an element identified by Key.
+ /// count - Returns 1 if this set contains an element identified by Key,
+ /// 0 otherwise.
///
- bool count(const KeyT &Key) const {
- return find(Key) != end();
+ unsigned count(const KeyT &Key) const {
+ return find(Key) == end() ? 0 : 1;
}
/// insert - Attempts to insert a new element.
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 56dbb5b..a0b3fe7 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -14,9 +14,9 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
-#include <iterator>
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
+#include <iterator>
namespace llvm {
template<typename T> class SmallVectorImpl;
@@ -28,6 +28,11 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) {
return X < 10 ? '0' + X : HexChar + X - 10;
}
+/// Construct a string ref from a boolean.
+static inline StringRef toStringRef(bool B) {
+ return StringRef(B ? "true" : "false");
+}
+
/// Interpret the given character \p C as a hexadecimal digit and return its
/// value.
///
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 0838ebe..4e74cf6 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -26,19 +26,6 @@ namespace llvm {
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;
@@ -149,10 +136,8 @@ public:
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
+ // 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>();
@@ -161,15 +146,12 @@ public:
static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
// Default construct the value.
- new (NewItem) StringMapEntry(KeyLength);
+ new (NewItem) StringMapEntry(KeyLength, InitVal);
// 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;
}
@@ -313,6 +295,7 @@ public:
return GetOrCreateValue(Key).getValue();
}
+ /// count - Return 1 if the element is in the map, 0 otherwise.
size_type count(StringRef Key) const {
return find(Key) == end() ? 0 : 1;
}
@@ -404,7 +387,17 @@ public:
}
~StringMap() {
- clear();
+ // Delete all the elements in the map, but don't reset the elements
+ // to default values. This is a copy of clear(), but avoids unnecessary
+ // work not required in the destructor.
+ if (!empty()) {
+ for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+ StringMapEntryBase *Bucket = TheTable[I];
+ if (Bucket && Bucket != getTombstoneVal()) {
+ static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+ }
+ }
+ }
free(TheTable);
}
};
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index ec0c284..0514d7b 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -10,7 +10,7 @@
#ifndef LLVM_ADT_STRINGREF_H
#define LLVM_ADT_STRINGREF_H
-#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@@ -124,6 +124,13 @@ namespace llvm {
return Data[Length-1];
}
+ // copy - Allocate copy in BumpPtrAllocator and return StringRef to it.
+ StringRef copy(BumpPtrAllocator &Allocator) {
+ char *S = Allocator.Allocate<char>(Length);
+ std::copy(begin(), end(), S);
+ return StringRef(S, Length);
+ }
+
/// 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 {
@@ -333,7 +340,7 @@ namespace llvm {
/// 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
+ typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
long long LLVal;
if (getAsSignedInteger(*this, Radix, LLVal) ||
@@ -344,7 +351,7 @@ namespace llvm {
}
template <typename T>
- typename enable_if_c<!std::numeric_limits<T>::is_signed, bool>::type
+ typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
unsigned long long ULLVal;
if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
@@ -553,11 +560,6 @@ namespace llvm {
// StringRefs can be treated like a POD type.
template <typename T> struct isPodLike;
template <> struct isPodLike<StringRef> { static const bool value = true; };
-
- /// Construct a string ref from a boolean.
- inline StringRef toStringRef(bool B) {
- return StringRef(B ? "true" : "false");
- }
}
#endif
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index cc0e7b6..1df8d66 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -12,9 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -70,7 +68,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
RHS.Val = (EltTy)0;
}
@@ -98,7 +95,6 @@ public:
RHS.Val = (EltTy)0;
return *this;
}
-#endif
// implicit conversion operator to ArrayRef.
operator ArrayRef<EltTy>() const {
@@ -250,7 +246,7 @@ public:
assert(I <= this->end() && "Inserting past the end of the vector.");
if (I == end()) {
push_back(Elt);
- return llvm::prior(end());
+ return std::prev(end());
}
assert(!Val.isNull() && "Null value with non-end insert iterator.");
if (EltTy V = Val.template dyn_cast<EltTy>()) {
@@ -273,7 +269,7 @@ public:
// If we have a single value, convert to a vector.
ptrdiff_t Offset = I - begin();
if (Val.isNull()) {
- if (llvm::next(From) == To) {
+ if (std::next(From) == To) {
Val = *From;
return begin();
}
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 84e0b29..185003d 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -46,32 +46,36 @@ public:
enum ArchType {
UnknownArch,
- arm, // ARM: arm, armv.*, xscale
- aarch64, // AArch64: aarch64
- 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
- ppc64le, // PPC64LE: powerpc64le
- r600, // R600: AMD GPUs HD2XXX - HD6XXX
- sparc, // Sparc: sparc
- sparcv9, // Sparcv9: Sparcv9
- systemz, // SystemZ: s390x
- 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
- nvptx, // NVPTX: 32-bit
- nvptx64, // NVPTX: 64-bit
- le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
- amdil, // amdil: amd IL
- spir, // SPIR: standard portable IR for OpenCL 32-bit version
- spir64 // SPIR: standard portable IR for OpenCL 64-bit version
+ arm, // ARM (little endian): arm, armv.*, xscale
+ armeb, // ARM (big endian): armeb
+ arm64, // ARM: arm64
+ aarch64, // AArch64 (little endian): aarch64
+ aarch64_be, // AArch64 (big endian): aarch64_be
+ 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
+ ppc64le, // PPC64LE: powerpc64le
+ r600, // R600: AMD GPUs HD2XXX - HD6XXX
+ sparc, // Sparc: sparc
+ sparcv9, // Sparcv9: Sparcv9
+ systemz, // SystemZ: s390x
+ tce, // TCE (http://tce.cs.tut.fi/): tce
+ thumb, // Thumb (little endian): thumb, thumbv.*
+ thumbeb, // Thumb (big endian): thumbeb
+ x86, // X86: i[3-9]86
+ x86_64, // X86-64: amd64, x86_64
+ xcore, // XCore: xcore
+ nvptx, // NVPTX: 32-bit
+ nvptx64, // NVPTX: 64-bit
+ le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
+ amdil, // amdil: amd IL
+ spir, // SPIR: standard portable IR for OpenCL 32-bit version
+ spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
enum VendorType {
UnknownVendor,
@@ -120,10 +124,21 @@ public:
GNUEABI,
GNUEABIHF,
GNUX32,
+ CODE16,
EABI,
- MachO,
+ EABIHF,
Android,
- ELF
+
+ MSVC,
+ Itanium,
+ Cygnus,
+ };
+ enum ObjectFormatType {
+ UnknownObjectFormat,
+
+ COFF,
+ ELF,
+ MachO,
};
private:
@@ -141,13 +156,16 @@ private:
/// The parsed Environment type.
EnvironmentType Environment;
+ /// The object format type.
+ ObjectFormatType ObjectFormat;
+
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() {}
+ Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
explicit Triple(const Twine &Str);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
@@ -186,6 +204,9 @@ public:
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const { return Environment; }
+ /// getFormat - Get the object format for this triple.
+ ObjectFormatType getObjectFormat() const { return ObjectFormat; }
+
/// getOSVersion - Parse the version number from the OS name component of the
/// triple, if present.
///
@@ -314,9 +335,29 @@ public:
return isMacOSX() || isiOS();
}
+ bool isWindowsMSVCEnvironment() const {
+ return getOS() == Triple::Win32 &&
+ (getEnvironment() == Triple::UnknownEnvironment ||
+ getEnvironment() == Triple::MSVC);
+ }
+
+ bool isKnownWindowsMSVCEnvironment() const {
+ return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC;
+ }
+
+ bool isWindowsCygwinEnvironment() const {
+ return getOS() == Triple::Cygwin ||
+ (getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus);
+ }
+
+ bool isWindowsGNUEnvironment() const {
+ return getOS() == Triple::MinGW32 ||
+ (getOS() == Triple::Win32 && getEnvironment() == Triple::GNU);
+ }
+
/// \brief Tests for either Cygwin or MinGW OS
bool isOSCygMing() const {
- return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32;
+ return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
}
/// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
@@ -341,18 +382,17 @@ public:
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
- return !isOSDarwin() && !isOSWindows();
+ return getObjectFormat() == Triple::ELF;
}
/// \brief Tests whether the OS uses the COFF binary format.
bool isOSBinFormatCOFF() const {
- return isOSWindows();
+ return getObjectFormat() == Triple::COFF;
}
/// \brief Tests whether the environment is MachO.
- // FIXME: Should this be an OSBinFormat predicate?
- bool isEnvironmentMachO() const {
- return getEnvironment() == Triple::MachO || isOSDarwin();
+ bool isOSBinFormatMachO() const {
+ return getObjectFormat() == Triple::MachO;
}
/// @}
@@ -375,6 +415,9 @@ public:
/// to a known type.
void setEnvironment(EnvironmentType Kind);
+ /// setObjectFormat - Set the object file format
+ void setObjectFormat(ObjectFormatType Kind);
+
/// setTriple - Set all components to the new triple \p Str.
void setTriple(const Twine &Str);
diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h
new file mode 100644
index 0000000..4f2f321
--- /dev/null
+++ b/include/llvm/ADT/iterator_range.h
@@ -0,0 +1,45 @@
+//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This provides a very simple, boring adaptor for a begin and end iterator
+/// into a range type. This should be used to build range views that work well
+/// with range based for loops and range based constructors.
+///
+/// Note that code here follows more standards-based coding conventions as it
+/// is mirroring proposed interfaces for standardization.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR_RANGE_H
+#define LLVM_ADT_ITERATOR_RANGE_H
+
+#include <utility>
+
+namespace llvm {
+
+/// \brief A range adaptor for a pair of iterators.
+///
+/// This just wraps two iterators into a range-compatible interface. Nothing
+/// fancy at all.
+template <typename IteratorT>
+class iterator_range {
+ IteratorT begin_iterator, end_iterator;
+
+public:
+ iterator_range() {}
+ iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
+ : begin_iterator(std::move(begin_iterator)),
+ end_iterator(std::move(end_iterator)) {}
+
+ IteratorT begin() const { return begin_iterator; }
+ IteratorT end() const { return end_iterator; }
+};
+}
+
+#endif
diff --git a/include/llvm/ADT/polymorphic_ptr.h b/include/llvm/ADT/polymorphic_ptr.h
deleted file mode 100644
index b8d8d71..0000000
--- a/include/llvm/ADT/polymorphic_ptr.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===- llvm/ADT/polymorphic_ptr.h - Smart copyable owned ptr ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file provides a polymorphic_ptr class template. See the class comments
-/// for details about this API, its intended use cases, etc.
-///
-/// The primary motivation here is to work around the necessity of copy
-/// semantics in C++98. This is typically used where any actual copies are
-/// incidental or unnecessary. As a consequence, it is expected to cease to be
-/// useful and be removed when we can directly rely on move-only types.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_POLYMORPHIC_PTR_H
-#define LLVM_ADT_POLYMORPHIC_PTR_H
-
-#include "llvm/Support/Compiler.h"
-
-namespace llvm {
-
-/// \brief An owning, copyable polymorphic smart pointer.
-///
-/// This pointer exists to provide copyable owned smart pointer. Rather than
-/// shared ownership semantics, it has unique ownership semantics and deep copy
-/// semantics. It is copyable by requiring that the underlying type exposes
-/// a method which can produce a (heap allocated) clone.
-///
-/// Note that in almost all scenarios use of this could be avoided if we could
-/// build move-only containers of a std::unique_ptr, but until then this
-/// provides an effective way to place polymorphic objects in a container.
-template <typename T> class polymorphic_ptr {
- T *ptr;
-
-public:
- polymorphic_ptr(T *ptr = 0) : ptr(ptr) {}
- polymorphic_ptr(const polymorphic_ptr &arg) : ptr(arg ? arg->clone() : 0) {}
-#if LLVM_HAS_RVALUE_REFERENCES
- polymorphic_ptr(polymorphic_ptr &&arg) : ptr(arg.take()) {}
-#endif
- ~polymorphic_ptr() { delete ptr; }
-
- polymorphic_ptr &operator=(polymorphic_ptr arg) {
- swap(arg);
- return *this;
- }
- polymorphic_ptr &operator=(T *arg) {
- if (arg != ptr) {
- delete ptr;
- ptr = arg;
- }
- return *this;
- }
-
- T &operator*() const { return *ptr; }
- T *operator->() const { return ptr; }
- LLVM_EXPLICIT operator bool() const { return ptr != 0; }
- bool operator!() const { return ptr == 0; }
-
- T *get() const { return ptr; }
-
- T *take() {
- T *tmp = ptr;
- ptr = 0;
- return tmp;
- }
-
- void swap(polymorphic_ptr &arg) {
- T *tmp = ptr;
- ptr = arg.ptr;
- arg.ptr = tmp;
- }
-};
-
-template <typename T>
-void swap(polymorphic_ptr<T> &lhs, polymorphic_ptr<T> &rhs) {
- lhs.swap(rhs);
-}
-
-template <typename T, typename U>
-bool operator==(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) {
- return lhs.get() == rhs.get();
-}
-
-template <typename T, typename U>
-bool operator!=(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) {
- return lhs.get() != rhs.get();
-}
-
-template <typename T, typename U>
-bool operator==(const polymorphic_ptr<T> &lhs, U *rhs) {
- return lhs.get() == rhs;
-}
-
-template <typename T, typename U>
-bool operator!=(const polymorphic_ptr<T> &lhs, U *rhs) {
- return lhs.get() != rhs;
-}
-
-template <typename T, typename U>
-bool operator==(T *lhs, const polymorphic_ptr<U> &rhs) {
- return lhs == rhs.get();
-}
-
-template <typename T, typename U>
-bool operator!=(T *lhs, const polymorphic_ptr<U> &rhs) {
- return lhs != rhs.get();
-}
-
-}
-
-#endif
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index efafbbd..a06a562 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -38,7 +38,7 @@
#define LLVM_ANALYSIS_ALIASANALYSIS_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
namespace llvm {
@@ -55,7 +55,7 @@ class DominatorTree;
class AliasAnalysis {
protected:
- const DataLayout *TD;
+ const DataLayout *DL;
const TargetLibraryInfo *TLI;
private:
@@ -75,7 +75,7 @@ protected:
public:
static char ID; // Class identification, replacement for typeinfo
- AliasAnalysis() : TD(0), TLI(0), AA(0) {}
+ AliasAnalysis() : DL(0), TLI(0), AA(0) {}
virtual ~AliasAnalysis(); // We want to be subclassed
/// UnknownSize - This is a special value which can be used with the
@@ -86,7 +86,7 @@ public:
/// getDataLayout - Return a pointer to the current DataLayout object, or
/// null if no DataLayout object is available.
///
- const DataLayout *getDataLayout() const { return TD; }
+ const DataLayout *getDataLayout() const { return DL; }
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
index da00707..72e75ec 100644
--- a/include/llvm/Analysis/AliasSetTracker.h
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -20,7 +20,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include <vector>
namespace llvm {
@@ -282,8 +282,8 @@ class AliasSetTracker {
/// notified whenever a Value is deleted.
class ASTCallbackVH : public CallbackVH {
AliasSetTracker *AST;
- virtual void deleted();
- virtual void allUsesReplacedWith(Value *);
+ void deleted() override;
+ void allUsesReplacedWith(Value *) override;
public:
ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
ASTCallbackVH &operator=(Value *V);
diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h
index 817a441..5488847 100644
--- a/include/llvm/Analysis/BlockFrequencyImpl.h
+++ b/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -48,7 +48,7 @@ class BlockFrequencyImpl {
typedef GraphTraits< Inverse<BlockT *> > GT;
- const uint32_t EntryFreq;
+ static const uint64_t EntryFreq = 1 << 14;
std::string getBlockName(BasicBlock *BB) const {
return BB->getName().str();
@@ -67,7 +67,8 @@ class BlockFrequencyImpl {
void setBlockFreq(BlockT *BB, BlockFrequency Freq) {
Freqs[BB] = Freq;
- DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = ";
+ printBlockFreq(dbgs(), Freq) << "\n");
}
/// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
@@ -81,8 +82,9 @@ class BlockFrequencyImpl {
///
void incBlockFreq(BlockT *BB, BlockFrequency Freq) {
Freqs[BB] += Freq;
- DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
- << " --> " << Freqs[BB] << "\n");
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += ";
+ printBlockFreq(dbgs(), Freq) << " --> ";
+ printBlockFreq(dbgs(), Freqs[BB]) << "\n");
}
// All blocks in postorder.
@@ -157,7 +159,7 @@ class BlockFrequencyImpl {
return;
}
- if(BlockT *Pred = getSingleBlockPred(BB)) {
+ if (BlockT *Pred = getSingleBlockPred(BB)) {
if (BlocksInLoop.count(Pred))
setBlockFreq(BB, getEdgeFreq(Pred, BB));
// TODO: else? irreducible, ignore it for now.
@@ -194,7 +196,8 @@ class BlockFrequencyImpl {
typename LoopExitProbMap::const_iterator I = LoopExitProb.find(BB);
assert(I != LoopExitProb.end() && "Loop header missing from table");
Freqs[BB] /= I->second;
- DEBUG(dbgs() << "Loop header scaled to " << Freqs[BB] << ".\n");
+ DEBUG(dbgs() << "Loop header scaled to ";
+ printBlockFreq(dbgs(), Freqs[BB]) << ".\n");
}
/// doLoop - Propagate block frequency down through the loop.
@@ -256,14 +259,15 @@ class BlockFrequencyImpl {
BranchProbability LEP = BranchProbability(N, D);
LoopExitProb.insert(std::make_pair(Head, LEP));
DEBUG(dbgs() << "LoopExitProb[" << getBlockName(Head) << "] = " << LEP
- << " from 1 - " << BackFreq << " / " << getBlockFreq(Head)
- << ".\n");
+ << " from 1 - ";
+ printBlockFreq(dbgs(), BackFreq) << " / ";
+ printBlockFreq(dbgs(), getBlockFreq(Head)) << ".\n");
}
friend class BlockFrequencyInfo;
friend class MachineBlockFrequencyInfo;
- BlockFrequencyImpl() : EntryFreq(BlockFrequency::getEntryFrequency()) { }
+ BlockFrequencyImpl() { }
void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
Fn = fn;
@@ -312,6 +316,9 @@ class BlockFrequencyImpl {
}
public:
+
+ uint64_t getEntryFreq() { return EntryFreq; }
+
/// 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
@@ -325,14 +332,15 @@ public:
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";
+ OS << " " << getBlockName(BB) << " = ";
+ printBlockFreq(OS, 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";
+ << " = "; printBlockFreq(OS, getEdgeFreq(BB, Succ)) << "\n";
}
}
}
@@ -340,6 +348,30 @@ public:
void dump() const {
print(dbgs());
}
+
+ // Utility method that looks up the block frequency associated with BB and
+ // prints it to OS.
+ raw_ostream &printBlockFreq(raw_ostream &OS,
+ const BlockT *BB) {
+ return printBlockFreq(OS, getBlockFreq(BB));
+ }
+
+ raw_ostream &printBlockFreq(raw_ostream &OS,
+ const BlockFrequency &Freq) const {
+ // Convert fixed-point number to decimal.
+ uint64_t Frequency = Freq.getFrequency();
+ OS << Frequency / EntryFreq << ".";
+ uint64_t Rem = Frequency % EntryFreq;
+ uint64_t Eps = 1;
+ do {
+ Rem *= 10;
+ Eps *= 10;
+ OS << Rem / EntryFreq;
+ Rem = Rem % EntryFreq;
+ } while (Rem >= Eps/2);
+ return OS;
+ }
+
};
}
diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h
index a123d0b..2f701d9 100644
--- a/include/llvm/Analysis/BlockFrequencyInfo.h
+++ b/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -27,8 +27,9 @@ class BlockFrequencyImpl;
/// BlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
/// IR basic block frequencies.
class BlockFrequencyInfo : public FunctionPass {
-
- BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
+ typedef BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo>
+ ImplType;
+ std::unique_ptr<ImplType> BFI;
public:
static char ID;
@@ -37,10 +38,11 @@ public:
~BlockFrequencyInfo();
- void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnFunction(Function &F);
- void print(raw_ostream &O, const Module *M) const;
+ bool runOnFunction(Function &F) override;
+ void releaseMemory() override;
+ void print(raw_ostream &O, const Module *M) const override;
const Function *getFunction() const;
void view() const;
@@ -50,6 +52,17 @@ public:
/// comparison to the other block frequencies. We do this to avoid using of
/// floating points.
BlockFrequency getBlockFreq(const BasicBlock *BB) const;
+
+ // Print the block frequency Freq to OS using the current functions entry
+ // frequency to convert freq into a relative decimal form.
+ raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const;
+
+ // Convenience method that attempts to look up the frequency associated with
+ // BB and print it to OS.
+ raw_ostream &printBlockFreq(raw_ostream &OS, const BasicBlock *BB) const;
+
+ uint64_t getEntryFreq() const;
+
};
}
diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h
index 4ff7121..4a6a280 100644
--- a/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/CFG.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
@@ -44,9 +45,9 @@ public:
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
}
- void getAnalysisUsage(AnalysisUsage &AU) const;
- bool runOnFunction(Function &F);
- void print(raw_ostream &OS, const Module *M = 0) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnFunction(Function &F) override;
+ void print(raw_ostream &OS, const Module *M = 0) const override;
/// \brief Get an edge's probability, relative to other out-edges of the Src.
///
@@ -98,6 +99,9 @@ public:
/// It is guaranteed to fall between 1 and UINT32_MAX.
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
+ uint32_t getEdgeWeight(const BasicBlock *Src,
+ succ_const_iterator Dst) const;
+
/// \brief Set the raw edge weight for a given edge.
///
/// This allows a pass to explicitly set the edge weight for an edge. It can
diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h
index e5683c8..02e3b45 100644
--- a/include/llvm/Analysis/CFG.h
+++ b/include/llvm/Analysis/CFG.h
@@ -16,7 +16,7 @@
#define LLVM_ANALYSIS_CFG_H
#include "llvm/IR/BasicBlock.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/IR/CFG.h"
namespace llvm {
diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h
index 39e90eb..e6d2ed1 100644
--- a/include/llvm/Analysis/CFGPrinter.h
+++ b/include/llvm/Analysis/CFGPrinter.h
@@ -15,11 +15,10 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
-#include "llvm/Assembly/Writer.h"
+#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/Support/CFG.h"
#include "llvm/Support/GraphWriter.h"
namespace llvm {
@@ -40,7 +39,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
std::string Str;
raw_string_ostream OS(Str);
- WriteAsOperand(OS, Node, false);
+ Node->printAsOperand(OS, false);
return OS.str();
}
@@ -51,7 +50,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
raw_string_ostream OS(Str);
if (Node->getName().empty()) {
- WriteAsOperand(OS, Node, false);
+ Node->printAsOperand(OS, false);
OS << ":";
}
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index d00c2ed..9a6a4a7 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -6,46 +6,47 @@
// 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).
-//
+/// \file
+///
+/// This file provides interfaces 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 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
@@ -53,11 +54,11 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/IncludeFile.h"
-#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
@@ -66,171 +67,142 @@ class Function;
class Module;
class CallGraphNode;
-//===----------------------------------------------------------------------===//
-// CallGraph class definition
-//
-class CallGraph : public ModulePass {
- Module *Mod; // The module this call graph represents
+/// \brief The basic data container for the call graph of a \c Module of IR.
+///
+/// This class exposes both the interface to the call graph for a module of IR.
+///
+/// The core call graph itself can also be updated to reflect changes to the IR.
+class CallGraph {
+ Module &M;
typedef std::map<const Function *, CallGraphNode *> FunctionMapTy;
- FunctionMapTy FunctionMap; // Map from a function to its node
- // Root is root of the call graph, or the external node if a 'main' function
- // couldn't be found.
- //
+ /// \brief A map from \c Function* to \c CallGraphNode*.
+ FunctionMapTy FunctionMap;
+
+ /// \brief Root is root of the call graph, or the external node if a 'main'
+ /// function couldn't be found.
CallGraphNode *Root;
- // ExternalCallingNode - This node has edges to all external functions and
- // those internal functions that have their address taken.
+ /// \brief This node has edges to all external functions and those internal
+ /// functions that have their address taken.
CallGraphNode *ExternalCallingNode;
- // CallsExternalNode - This node has edges to it from all functions making
- // indirect calls or calling an external function.
+ /// \brief This node has edges to it from all functions making indirect calls
+ /// or calling an external function.
CallGraphNode *CallsExternalNode;
- /// Replace the function represented by this node by another.
+ /// \brief 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);
- // Add a function to the call graph, and link the node to all of the functions
- // that it calls.
+ /// \brief Add a function to the call graph, and link the node to all of the
+ /// functions that it calls.
void addToCallGraph(Function *F);
public:
- static char ID; // Class identification, replacement for typeinfo
- //===---------------------------------------------------------------------
- // Accessors.
- //
+ CallGraph(Module &M);
+ ~CallGraph();
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+
typedef FunctionMapTy::iterator iterator;
typedef FunctionMapTy::const_iterator const_iterator;
- /// getModule - Return the module the call graph corresponds to.
- ///
- Module &getModule() const { return *Mod; }
+ /// \brief Returns the module the call graph corresponds to.
+ Module &getModule() const { return M; }
- inline iterator begin() { return FunctionMap.begin(); }
- inline iterator end() { return FunctionMap.end(); }
+ 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(); }
+ inline const_iterator end() const { return FunctionMap.end(); }
- // Subscripting operators, return the call graph node for the provided
- // function
+ /// \brief Returns 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;
}
+
+ /// \brief Returns the call graph node for the provided function.
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.
+ /// \brief Returns the \c CallGraphNode which is used to represent
+ /// undetermined calls into the callgraph.
CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; }
- CallGraphNode *getCallsExternalNode() const { return CallsExternalNode; }
- /// Return the root/main method in the module, or some other root node, such
- /// as the externalcallingnode.
- CallGraphNode *getRoot() { return Root; }
- const CallGraphNode *getRoot() const { return Root; }
+ CallGraphNode *getCallsExternalNode() const { return CallsExternalNode; }
//===---------------------------------------------------------------------
// 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.
+ /// \brief 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);
- /// 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.
+ /// \brief Similar to operator[], but this will insert a new CallGraphNode for
+ /// \c F if one does not already exist.
CallGraphNode *getOrInsertFunction(const Function *F);
-
- CallGraph();
- virtual ~CallGraph() { releaseMemory(); }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual bool runOnModule(Module &M);
- virtual void releaseMemory();
-
- void print(raw_ostream &o, const Module *) const;
- void dump() const;
};
-//===----------------------------------------------------------------------===//
-// CallGraphNode class definition.
-//
+/// \brief A node in the call graph for a module.
+///
+/// Typically represents a function in the call graph. There are also special
+/// "null" nodes used to represent theoretical entries in the call graph.
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;
+ /// \brief A pair of the calling instruction (a call or invoke)
+ /// and the call graph node being called.
+ typedef std::pair<WeakVH, CallGraphNode *> CallRecord;
- CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
- void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
-
- 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) {}
+ /// \brief Creates 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.
+ /// \brief Returns 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 iterator end() { return CalledFunctions.end(); }
inline const_iterator begin() const { return CalledFunctions.begin(); }
- inline const_iterator end() const { return CalledFunctions.end(); }
+ 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.
+ /// \brief Returns 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.
- //
+
+ /// \brief Returns 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.
- ///
+ /// \brief Print out this call graph node.
void dump() const;
void print(raw_ostream &OS) const;
@@ -239,29 +211,25 @@ public:
// modified
//
- /// removeAllCalledFunctions - As the name implies, this removes all edges
- /// from this CallGraphNode to any functions it calls.
+ /// \brief 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.
+
+ /// \brief Moves 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.
+ /// \brief Adds a function to the list of functions called by this one.
void addCalledFunction(CallSite CS, CallGraphNode *M) {
- assert(!CS.getInstruction() ||
- !CS.getCalledFunction() ||
+ assert(!CS.getInstruction() || !CS.getCalledFunction() ||
!CS.getCalledFunction()->isIntrinsic());
CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
M->AddRef();
@@ -272,32 +240,152 @@ public:
*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.
+
+ /// \brief 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.
+ /// \brief 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.
+ /// \brief Removes 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.
+
+ /// \brief 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;
+
+private:
+ friend class CallGraph;
+
+ AssertingVH<Function> F;
+
+ std::vector<CallRecord> CalledFunctions;
+
+ /// \brief The number of times that this CallGraphNode occurs in the
+ /// CalledFunctions array of this or other CallGraphNodes.
+ unsigned NumReferences;
+
+ CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
+ void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
+
+ void DropRef() { --NumReferences; }
+ void AddRef() { ++NumReferences; }
+
+ /// \brief A special function that should only be used by the CallGraph class.
+ void allReferencesDropped() { NumReferences = 0; }
+};
+
+/// \brief An analysis pass to compute the \c CallGraph for a \c Module.
+///
+/// This class implements the concept of an analysis pass used by the \c
+/// ModuleAnalysisManager to run an analysis over a module and cache the
+/// resulting data.
+class CallGraphAnalysis {
+public:
+ /// \brief A formulaic typedef to inform clients of the result type.
+ typedef CallGraph Result;
+
+ static void *ID() { return (void *)&PassID; }
+
+ /// \brief Compute the \c CallGraph for the module \c M.
+ ///
+ /// The real work here is done in the \c CallGraph constructor.
+ CallGraph run(Module *M) { return CallGraph(*M); }
+
+private:
+ static char PassID;
+};
+
+/// \brief The \c ModulePass which wraps up a \c CallGraph and the logic to
+/// build it.
+///
+/// This class exposes both the interface to the call graph container and the
+/// module pass which runs over a module of IR and produces the call graph. The
+/// call graph interface is entirelly a wrapper around a \c CallGraph object
+/// which is stored internally for each module.
+class CallGraphWrapperPass : public ModulePass {
+ std::unique_ptr<CallGraph> G;
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+
+ CallGraphWrapperPass();
+ virtual ~CallGraphWrapperPass();
+
+ /// \brief The internal \c CallGraph around which the rest of this interface
+ /// is wrapped.
+ const CallGraph &getCallGraph() const { return *G; }
+ CallGraph &getCallGraph() { return *G; }
+
+ typedef CallGraph::iterator iterator;
+ typedef CallGraph::const_iterator const_iterator;
+
+ /// \brief Returns the module the call graph corresponds to.
+ Module &getModule() const { return G->getModule(); }
+
+ inline iterator begin() { return G->begin(); }
+ inline iterator end() { return G->end(); }
+ inline const_iterator begin() const { return G->begin(); }
+ inline const_iterator end() const { return G->end(); }
+
+ /// \brief Returns the call graph node for the provided function.
+ inline const CallGraphNode *operator[](const Function *F) const {
+ return (*G)[F];
+ }
+
+ /// \brief Returns the call graph node for the provided function.
+ inline CallGraphNode *operator[](const Function *F) { return (*G)[F]; }
+
+ /// \brief Returns the \c CallGraphNode which is used to represent
+ /// undetermined calls into the callgraph.
+ CallGraphNode *getExternalCallingNode() const {
+ return G->getExternalCallingNode();
+ }
+
+ CallGraphNode *getCallsExternalNode() const {
+ return G->getCallsExternalNode();
+ }
+
+ //===---------------------------------------------------------------------
+ // Functions to keep a call graph up to date with a function that has been
+ // modified.
+ //
+
+ /// \brief 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) {
+ return G->removeFunctionFromModule(CGN);
+ }
+
+ /// \brief Similar to operator[], but this will insert a new CallGraphNode for
+ /// \c F if one does not already exist.
+ CallGraphNode *getOrInsertFunction(const Function *F) {
+ return G->getOrInsertFunction(F);
}
+
+ //===---------------------------------------------------------------------
+ // Implementation of the ModulePass interface needed here.
+ //
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnModule(Module &M) override;
+ void releaseMemory() override;
+
+ void print(raw_ostream &o, const Module *) const override;
+ void dump() const;
};
//===----------------------------------------------------------------------===//
@@ -307,11 +395,12 @@ public:
// Provide graph traits for tranversing call graphs using standard graph
// traversals.
-template <> struct GraphTraits<CallGraphNode*> {
+template <> struct GraphTraits<CallGraphNode *> {
typedef CallGraphNode NodeType;
typedef CallGraphNode::CallRecord CGNPairTy;
- typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode*> CGNDerefFun;
+ typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode *>
+ CGNDerefFun;
static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }
@@ -320,55 +409,54 @@ template <> struct GraphTraits<CallGraphNode*> {
static inline ChildIteratorType child_begin(NodeType *N) {
return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
}
- static inline ChildIteratorType child_end (NodeType *N) {
+ static inline ChildIteratorType child_end(NodeType *N) {
return map_iterator(N->end(), CGNDerefFun(CGNDeref));
}
- static CallGraphNode *CGNDeref(CGNPairTy P) {
- return P.second;
- }
-
+ static CallGraphNode *CGNDeref(CGNPairTy P) { return P.second; }
};
-template <> struct GraphTraits<const CallGraphNode*> {
+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(); }
+ 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*> {
+template <>
+struct GraphTraits<CallGraph *> : public GraphTraits<CallGraphNode *> {
static NodeType *getEntryNode(CallGraph *CGN) {
- return CGN->getExternalCallingNode(); // Start at the external node!
+ return CGN->getExternalCallingNode(); // Start at the external node!
}
- typedef std::pair<const Function*, CallGraphNode*> PairTy;
- typedef std::pointer_to_unary_function<PairTy, CallGraphNode&> DerefFun;
+ 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) {
+ static nodes_iterator nodes_end(CallGraph *CG) {
return map_iterator(CG->end(), DerefFun(CGdereference));
}
- static CallGraphNode &CGdereference(PairTy P) {
- return *P.second;
- }
+ static CallGraphNode &CGdereference(PairTy P) { return *P.second; }
};
-template<> struct GraphTraits<const CallGraph*> :
- public GraphTraits<const CallGraphNode*> {
+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(); }
+ static nodes_iterator nodes_end(const CallGraph *CG) { return CG->end(); }
};
} // End llvm namespace
diff --git a/include/llvm/Analysis/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h
index e609dac..667e171 100644
--- a/include/llvm/Analysis/CallGraphSCCPass.h
+++ b/include/llvm/Analysis/CallGraphSCCPass.h
@@ -37,7 +37,8 @@ public:
/// createPrinterPass - Get a pass that prints the Module
/// corresponding to a CallGraph.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
@@ -65,18 +66,17 @@ public:
}
/// Assign pass manager to manager this pass
- virtual void assignPassManager(PMStack &PMS,
- PassManagerType PMT);
+ void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
/// Return what kind of Pass Manager can manage this pass.
- virtual PassManagerType getPotentialPassManagerType() const {
+ PassManagerType getPotentialPassManagerType() const override {
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;
+ void getAnalysisUsage(AnalysisUsage &Info) const override;
};
/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h
index 8edabfe..eccf1f8 100644
--- a/include/llvm/Analysis/CaptureTracking.h
+++ b/include/llvm/Analysis/CaptureTracking.h
@@ -45,12 +45,12 @@ namespace llvm {
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
- virtual bool shouldExplore(Use *U);
+ virtual bool shouldExplore(const Use *U);
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking
/// for more capturing instructions.
- virtual bool captured(Use *U) = 0;
+ virtual bool captured(const Use *U) = 0;
};
/// PointerMayBeCaptured - Visit the value and the values derived from it and
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index 086934d..04b39c1 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -16,7 +16,7 @@
#define LLVM_ANALYSIS_CODEMETRICS_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
namespace llvm {
class BasicBlock;
diff --git a/include/llvm/Analysis/ConstantsScanner.h b/include/llvm/Analysis/ConstantsScanner.h
index cdaf68d..d3d0a44 100644
--- a/include/llvm/Analysis/ConstantsScanner.h
+++ b/include/llvm/Analysis/ConstantsScanner.h
@@ -16,7 +16,7 @@
#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
-#include "llvm/Support/InstIterator.h"
+#include "llvm/IR/InstIterator.h"
namespace llvm {
diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h
index 0fc1c2d..ff3392a 100644
--- a/include/llvm/Analysis/DOTGraphTraitsPass.h
+++ b/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -19,50 +19,62 @@
namespace llvm {
-template <class Analysis, bool Simple>
+/// \brief Default traits class for extracting a graph from an analysis pass.
+///
+/// This assumes that 'GraphT' is 'AnalysisT *' and so just passes it through.
+template <typename AnalysisT, typename GraphT = AnalysisT *>
+struct DefaultAnalysisGraphTraits {
+ static GraphT getGraph(AnalysisT *A) { return A; }
+};
+
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
class DOTGraphTraitsViewer : public FunctionPass {
public:
DOTGraphTraitsViewer(StringRef GraphName, char &ID)
- : FunctionPass(ID), Name(GraphName) {}
+ : FunctionPass(ID), Name(GraphName) {}
- virtual bool runOnFunction(Function &F) {
- Analysis *Graph = &getAnalysis<Analysis>();
- std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ bool runOnFunction(Function &F) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+ std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
- ViewGraph(Graph, Name, Simple, Title);
+ ViewGraph(Graph, Name, IsSimple, Title);
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<Analysis>();
+ AU.addRequired<AnalysisT>();
}
private:
std::string Name;
};
-template <class Analysis, bool Simple>
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
class DOTGraphTraitsPrinter : public FunctionPass {
public:
DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
- : FunctionPass(ID), Name(GraphName) {}
+ : FunctionPass(ID), Name(GraphName) {}
- virtual bool runOnFunction(Function &F) {
- Analysis *Graph = &getAnalysis<Analysis>();
+ bool runOnFunction(Function &F) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
std::string Filename = Name + "." + F.getName().str() + ".dot";
std::string ErrorInfo;
errs() << "Writing '" << Filename << "'...";
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
- std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
+ std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
if (ErrorInfo.empty())
- WriteGraph(File, Graph, Simple, Title);
+ WriteGraph(File, Graph, IsSimple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
@@ -70,57 +82,61 @@ public:
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<Analysis>();
+ AU.addRequired<AnalysisT>();
}
private:
std::string Name;
};
-template <class Analysis, bool Simple>
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
class DOTGraphTraitsModuleViewer : public ModulePass {
public:
DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
- : ModulePass(ID), Name(GraphName) {}
+ : ModulePass(ID), Name(GraphName) {}
- virtual bool runOnModule(Module &M) {
- Analysis *Graph = &getAnalysis<Analysis>();
- std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ bool runOnModule(Module &M) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
+ std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
- ViewGraph(Graph, Name, Simple, Title);
+ ViewGraph(Graph, Name, IsSimple, Title);
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<Analysis>();
+ AU.addRequired<AnalysisT>();
}
private:
std::string Name;
};
-template <class Analysis, bool Simple>
+template <
+ typename AnalysisT, bool IsSimple, typename GraphT = AnalysisT *,
+ typename AnalysisGraphTraitsT = DefaultAnalysisGraphTraits<AnalysisT> >
class DOTGraphTraitsModulePrinter : public ModulePass {
public:
DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
- : ModulePass(ID), Name(GraphName) {}
+ : ModulePass(ID), Name(GraphName) {}
- virtual bool runOnModule(Module &M) {
- Analysis *Graph = &getAnalysis<Analysis>();
+ bool runOnModule(Module &M) override {
+ GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>());
std::string Filename = Name + ".dot";
std::string ErrorInfo;
errs() << "Writing '" << Filename << "'...";
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
- std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo, sys::fs::F_Text);
+ std::string Title = DOTGraphTraits<GraphT>::getGraphName(Graph);
if (ErrorInfo.empty())
- WriteGraph(File, Graph, Simple, Title);
+ WriteGraph(File, Graph, IsSimple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
@@ -128,9 +144,9 @@ public:
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<Analysis>();
+ AU.addRequired<AnalysisT>();
}
private:
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index ea8cecf..a142828 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -227,45 +227,45 @@ namespace llvm {
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
- bool isLoopIndependent() const { return LoopIndependent; }
+ bool isLoopIndependent() const override { return LoopIndependent; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
- bool isConfused() const { return false; }
+ bool isConfused() const override { return false; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
- bool isConsistent() const { return Consistent; }
+ bool isConsistent() const override { return Consistent; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
- unsigned getLevels() const { return Levels; }
+ unsigned getLevels() const override { return Levels; }
/// getDirection - Returns the direction associated with a particular
/// level.
- unsigned getDirection(unsigned Level) const;
+ unsigned getDirection(unsigned Level) const override;
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
- const SCEV *getDistance(unsigned Level) const;
+ const SCEV *getDistance(unsigned Level) const override;
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
- bool isPeelFirst(unsigned Level) const;
+ bool isPeelFirst(unsigned Level) const override;
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
- bool isPeelLast(unsigned Level) const;
+ bool isPeelLast(unsigned Level) const override;
/// isSplitable - Returns true if splitting the loop will break
/// the dependence.
- bool isSplitable(unsigned Level) const;
+ bool isSplitable(unsigned Level) const override;
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
- bool isScalar(unsigned Level) const;
+ bool isScalar(unsigned Level) const override;
private:
unsigned short Levels;
bool LoopIndependent;
@@ -918,10 +918,10 @@ namespace llvm {
initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
- bool runOnFunction(Function &F);
- void releaseMemory();
- void getAnalysisUsage(AnalysisUsage &) const;
- void print(raw_ostream &, const Module * = 0) const;
+ bool runOnFunction(Function &F) override;
+ void releaseMemory() override;
+ void getAnalysisUsage(AnalysisUsage &) const override;
+ void print(raw_ostream &, const Module * = 0) const override;
}; // class DependenceAnalysis
/// createDependenceAnalysisPass - This creates an instance of the
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
index a2e0675..4dcea2d 100644
--- a/include/llvm/Analysis/DominanceFrontier.h
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -18,7 +18,7 @@
#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
-#include "llvm/Analysis/Dominators.h"
+#include "llvm/IR/Dominators.h"
#include <map>
#include <set>
@@ -51,7 +51,7 @@ public:
///
bool isPostDominator() const { return IsPostDominators; }
- virtual void releaseMemory() { Frontiers.clear(); }
+ void releaseMemory() override { Frontiers.clear(); }
// Accessor interface:
typedef DomSetMapType::iterator iterator;
@@ -142,7 +142,7 @@ public:
/// print - Convert to human readable form
///
- virtual void print(raw_ostream &OS, const Module* = 0) const;
+ void print(raw_ostream &OS, const Module* = 0) const override;
/// dump - Dump the dominance frontier to dbgs().
void dump() const;
@@ -167,18 +167,18 @@ public:
return Roots[0];
}
- virtual bool runOnFunction(Function &) {
+ bool runOnFunction(Function &) override {
Frontiers.clear();
- DominatorTree &DT = getAnalysis<DominatorTree>();
+ DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
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 {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<DominatorTree>();
+ AU.addRequired<DominatorTreeWrapperPass>();
}
const DomSetType &calculate(const DominatorTree &DT,
diff --git a/include/llvm/Analysis/FindUsedTypes.h b/include/llvm/Analysis/FindUsedTypes.h
index b22cb88..574c947 100644
--- a/include/llvm/Analysis/FindUsedTypes.h
+++ b/include/llvm/Analysis/FindUsedTypes.h
@@ -39,7 +39,7 @@ public:
/// 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;
+ void print(raw_ostream &o, const Module *M) const override;
private:
/// IncorporateType - Incorporate one type and all of its subtypes into the
@@ -53,10 +53,10 @@ private:
public:
/// run - This incorporates all types used by the specified module
- bool runOnModule(Module &M);
+ bool runOnModule(Module &M) override;
/// getAnalysisUsage - We do not modify anything.
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
};
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index c982801..c6bb494 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -17,7 +17,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
@@ -86,7 +86,7 @@ private:
/// Deleted - Implementation of CallbackVH virtual function to
/// receive notification when the User is deleted.
- virtual void deleted();
+ void deleted() override;
};
template<> struct ilist_traits<IVStrideUse>
@@ -122,18 +122,18 @@ class IVUsers : public LoopPass {
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- DataLayout *TD;
+ const DataLayout *DL;
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;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
- virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
+ bool runOnLoop(Loop *L, LPPassManager &LPM) override;
- virtual void releaseMemory();
+ void releaseMemory() override;
public:
static char ID; // Pass ID, replacement for typeid
@@ -169,7 +169,7 @@ public:
return Processed.count(Inst);
}
- void print(raw_ostream &OS, const Module* = 0) const;
+ void print(raw_ostream &OS, const Module* = 0) const override;
/// dump - This method is used for debugging.
void dump() const;
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index 383f697..aaed716 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -99,7 +99,6 @@ public:
/// \brief Cost analyzer used by inliner.
class InlineCostAnalysis : public CallGraphSCCPass {
- const DataLayout *TD;
const TargetTransformInfo *TTI;
public:
@@ -109,8 +108,8 @@ public:
~InlineCostAnalysis();
// Pass interface implementation.
- void getAnalysisUsage(AnalysisUsage &AU) const;
- bool runOnSCC(CallGraphSCC &SCC);
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnSCC(CallGraphSCC &SCC) override;
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
diff --git a/include/llvm/Analysis/Interval.h b/include/llvm/Analysis/Interval.h
index 5ce1260..01eba3f 100644
--- a/include/llvm/Analysis/Interval.h
+++ b/include/llvm/Analysis/Interval.h
@@ -48,9 +48,6 @@ public:
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.
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
index 22067c4..73aff76 100644
--- a/include/llvm/Analysis/IntervalIterator.h
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -34,8 +34,8 @@
#define LLVM_ANALYSIS_INTERVALITERATOR_H
#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/IR/CFG.h"
#include "llvm/IR/Function.h"
-#include "llvm/Support/CFG.h"
#include <algorithm>
#include <set>
#include <vector>
diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h
index 8cade58..05248bd 100644
--- a/include/llvm/Analysis/IntervalPartition.h
+++ b/include/llvm/Analysis/IntervalPartition.h
@@ -34,7 +34,7 @@ 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, an
-// interval is a (possibly nonexistent) loop with a "tail" of non looping
+// interval is a (possibly nonexistent) loop with a "tail" of non-looping
// nodes following it.
//
class IntervalPartition : public FunctionPass {
@@ -53,7 +53,7 @@ public:
}
// run - Calculate the interval partition for this function
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
// IntervalPartition ctor - Build a reduced interval partition from an
// existing interval graph. This takes an additional boolean parameter to
@@ -62,7 +62,7 @@ public:
IntervalPartition(IntervalPartition &I, bool);
// print - Show contents in human readable format...
- virtual void print(raw_ostream &O, const Module* = 0) const;
+ void print(raw_ostream &O, const Module* = 0) const override;
// getRootInterval() - Return the root interval that contains the starting
// block of the function.
@@ -81,7 +81,7 @@ public:
}
// getAnalysisUsage - Implement the Pass API
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
@@ -89,7 +89,7 @@ public:
const std::vector<Interval*> &getIntervals() const { return Intervals; }
// releaseMemory - Reset state back to before function was analyzed
- void releaseMemory();
+ void releaseMemory() override;
private:
// addIntervalToPartition - Add an interval to the internal list of intervals,
diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h
new file mode 100644
index 0000000..74b0c8e
--- /dev/null
+++ b/include/llvm/Analysis/LazyCallGraph.h
@@ -0,0 +1,337 @@
+//===- LazyCallGraph.h - Analysis of 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.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Implements a lazy call graph analysis and related passes for the new pass
+/// manager.
+///
+/// NB: This is *not* a traditional call graph! It is a graph which models both
+/// the current calls and potential calls. As a consequence there are many
+/// edges in this call graph that do not correspond to a 'call' or 'invoke'
+/// instruction.
+///
+/// The primary use cases of this graph analysis is to facilitate iterating
+/// across the functions of a module in ways that ensure all callees are
+/// visited prior to a caller (given any SCC constraints), or vice versa. As
+/// such is it particularly well suited to organizing CGSCC optimizations such
+/// as inlining, outlining, argument promotion, etc. That is its primary use
+/// case and motivates the design. It may not be appropriate for other
+/// purposes. The use graph of functions or some other conservative analysis of
+/// call instructions may be interesting for optimizations and subsequent
+/// analyses which don't work in the context of an overly specified
+/// potential-call-edge graph.
+///
+/// To understand the specific rules and nature of this call graph analysis,
+/// see the documentation of the \c LazyCallGraph below.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LAZY_CALL_GRAPH
+#define LLVM_ANALYSIS_LAZY_CALL_GRAPH
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Allocator.h"
+#include <iterator>
+
+namespace llvm {
+class ModuleAnalysisManager;
+class PreservedAnalyses;
+class raw_ostream;
+
+/// \brief A lazily constructed view of the call graph of a module.
+///
+/// With the edges of this graph, the motivating constraint that we are
+/// attempting to maintain is that function-local optimization, CGSCC-local
+/// optimizations, and optimizations transforming a pair of functions connected
+/// by an edge in the graph, do not invalidate a bottom-up traversal of the SCC
+/// DAG. That is, no optimizations will delete, remove, or add an edge such
+/// that functions already visited in a bottom-up order of the SCC DAG are no
+/// longer valid to have visited, or such that functions not yet visited in
+/// a bottom-up order of the SCC DAG are not required to have already been
+/// visited.
+///
+/// Within this constraint, the desire is to minimize the merge points of the
+/// SCC DAG. The greater the fanout of the SCC DAG and the fewer merge points
+/// in the SCC DAG, the more independence there is in optimizing within it.
+/// There is a strong desire to enable parallelization of optimizations over
+/// the call graph, and both limited fanout and merge points will (artificially
+/// in some cases) limit the scaling of such an effort.
+///
+/// To this end, graph represents both direct and any potential resolution to
+/// an indirect call edge. Another way to think about it is that it represents
+/// both the direct call edges and any direct call edges that might be formed
+/// through static optimizations. Specifically, it considers taking the address
+/// of a function to be an edge in the call graph because this might be
+/// forwarded to become a direct call by some subsequent function-local
+/// optimization. The result is that the graph closely follows the use-def
+/// edges for functions. Walking "up" the graph can be done by looking at all
+/// of the uses of a function.
+///
+/// The roots of the call graph are the external functions and functions
+/// escaped into global variables. Those functions can be called from outside
+/// of the module or via unknowable means in the IR -- we may not be able to
+/// form even a potential call edge from a function body which may dynamically
+/// load the function and call it.
+///
+/// This analysis still requires updates to remain valid after optimizations
+/// which could potentially change the set of potential callees. The
+/// constraints it operates under only make the traversal order remain valid.
+///
+/// The entire analysis must be re-computed if full interprocedural
+/// optimizations run at any point. For example, globalopt completely
+/// invalidates the information in this analysis.
+///
+/// FIXME: This class is named LazyCallGraph in a lame attempt to distinguish
+/// it from the existing CallGraph. At some point, it is expected that this
+/// will be the only call graph and it will be renamed accordingly.
+class LazyCallGraph {
+public:
+ class Node;
+ typedef SmallVector<PointerUnion<Function *, Node *>, 4> NodeVectorT;
+ typedef SmallVectorImpl<PointerUnion<Function *, Node *>> NodeVectorImplT;
+
+ /// \brief A lazy iterator used for both the entry nodes and child nodes.
+ ///
+ /// When this iterator is dereferenced, if not yet available, a function will
+ /// be scanned for "calls" or uses of functions and its child information
+ /// will be constructed. All of these results are accumulated and cached in
+ /// the graph.
+ class iterator : public std::iterator<std::bidirectional_iterator_tag, Node *,
+ ptrdiff_t, Node *, Node *> {
+ friend class LazyCallGraph;
+ friend class LazyCallGraph::Node;
+ typedef std::iterator<std::bidirectional_iterator_tag, Node *, ptrdiff_t,
+ Node *, Node *> BaseT;
+
+ /// \brief Nonce type to select the constructor for the end iterator.
+ struct IsAtEndT {};
+
+ LazyCallGraph &G;
+ NodeVectorImplT::iterator NI;
+
+ // Build the begin iterator for a node.
+ explicit iterator(LazyCallGraph &G, NodeVectorImplT &Nodes)
+ : G(G), NI(Nodes.begin()) {}
+
+ // Build the end iterator for a node. This is selected purely by overload.
+ iterator(LazyCallGraph &G, NodeVectorImplT &Nodes, IsAtEndT /*Nonce*/)
+ : G(G), NI(Nodes.end()) {}
+
+ public:
+ iterator(const iterator &Arg) : G(Arg.G), NI(Arg.NI) {}
+ iterator(iterator &&Arg) : G(Arg.G), NI(std::move(Arg.NI)) {}
+ iterator &operator=(iterator Arg) {
+ std::swap(Arg, *this);
+ return *this;
+ }
+
+ bool operator==(const iterator &Arg) { return NI == Arg.NI; }
+ bool operator!=(const iterator &Arg) { return !operator==(Arg); }
+
+ reference operator*() const {
+ if (NI->is<Node *>())
+ return NI->get<Node *>();
+
+ Function *F = NI->get<Function *>();
+ Node *ChildN = G.get(*F);
+ *NI = ChildN;
+ return ChildN;
+ }
+ pointer operator->() const { return operator*(); }
+
+ iterator &operator++() {
+ ++NI;
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator prev = *this;
+ ++*this;
+ return prev;
+ }
+
+ iterator &operator--() {
+ --NI;
+ return *this;
+ }
+ iterator operator--(int) {
+ iterator next = *this;
+ --*this;
+ return next;
+ }
+ };
+
+ /// \brief Construct a graph for the given module.
+ ///
+ /// This sets up the graph and computes all of the entry points of the graph.
+ /// No function definitions are scanned until their nodes in the graph are
+ /// requested during traversal.
+ LazyCallGraph(Module &M);
+
+ /// \brief Copy constructor.
+ ///
+ /// This does a deep copy of the graph. It does no verification that the
+ /// graph remains valid for the module. It is also relatively expensive.
+ LazyCallGraph(const LazyCallGraph &G);
+
+ /// \brief Move constructor.
+ ///
+ /// This is a deep move. It leaves G in an undefined but destroyable state.
+ /// Any other operation on G is likely to fail.
+ LazyCallGraph(LazyCallGraph &&G);
+
+ /// \brief Copy and move assignment.
+ LazyCallGraph &operator=(LazyCallGraph RHS) {
+ std::swap(*this, RHS);
+ return *this;
+ }
+
+ iterator begin() { return iterator(*this, EntryNodes); }
+ iterator end() { return iterator(*this, EntryNodes, iterator::IsAtEndT()); }
+
+ /// \brief Lookup a function in the graph which has already been scanned and
+ /// added.
+ Node *lookup(const Function &F) const { return NodeMap.lookup(&F); }
+
+ /// \brief Get a graph node for a given function, scanning it to populate the
+ /// graph data as necessary.
+ Node *get(Function &F) {
+ Node *&N = NodeMap[&F];
+ if (N)
+ return N;
+
+ return insertInto(F, N);
+ }
+
+private:
+ Module &M;
+
+ /// \brief Allocator that holds all the call graph nodes.
+ SpecificBumpPtrAllocator<Node> BPA;
+
+ /// \brief Maps function->node for fast lookup.
+ DenseMap<const Function *, Node *> NodeMap;
+
+ /// \brief The entry nodes to the graph.
+ ///
+ /// These nodes are reachable through "external" means. Put another way, they
+ /// escape at the module scope.
+ NodeVectorT EntryNodes;
+
+ /// \brief Set of the entry nodes to the graph.
+ SmallPtrSet<Function *, 4> EntryNodeSet;
+
+ /// \brief Helper to insert a new function, with an already looked-up entry in
+ /// the NodeMap.
+ Node *insertInto(Function &F, Node *&MappedN);
+
+ /// \brief Helper to copy a node from another graph into this one.
+ Node *copyInto(const Node &OtherN);
+
+ /// \brief Helper to move a node from another graph into this one.
+ Node *moveInto(Node &&OtherN);
+};
+
+/// \brief A node in the call graph.
+///
+/// This represents a single node. It's primary roles are to cache the list of
+/// callees, de-duplicate and provide fast testing of whether a function is
+/// a callee, and facilitate iteration of child nodes in the graph.
+class LazyCallGraph::Node {
+ friend class LazyCallGraph;
+
+ LazyCallGraph &G;
+ Function &F;
+ mutable NodeVectorT Callees;
+ SmallPtrSet<Function *, 4> CalleeSet;
+
+ /// \brief Basic constructor implements the scanning of F into Callees and
+ /// CalleeSet.
+ Node(LazyCallGraph &G, Function &F);
+
+ /// \brief Constructor used when copying a node from one graph to another.
+ Node(LazyCallGraph &G, const Node &OtherN);
+
+ /// \brief Constructor used when moving a node from one graph to another.
+ Node(LazyCallGraph &G, Node &&OtherN);
+
+public:
+ typedef LazyCallGraph::iterator iterator;
+
+ Function &getFunction() const {
+ return F;
+ };
+
+ iterator begin() const { return iterator(G, Callees); }
+ iterator end() const { return iterator(G, Callees, iterator::IsAtEndT()); }
+
+ /// Equality is defined as address equality.
+ bool operator==(const Node &N) const { return this == &N; }
+ bool operator!=(const Node &N) const { return !operator==(N); }
+};
+
+// Provide GraphTraits specializations for call graphs.
+template <> struct GraphTraits<LazyCallGraph::Node *> {
+ typedef LazyCallGraph::Node NodeType;
+ typedef LazyCallGraph::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(NodeType *N) { return N; }
+ static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
+ static ChildIteratorType child_end(NodeType *N) { return N->end(); }
+};
+template <> struct GraphTraits<LazyCallGraph *> {
+ typedef LazyCallGraph::Node NodeType;
+ typedef LazyCallGraph::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(NodeType *N) { return N; }
+ static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
+ static ChildIteratorType child_end(NodeType *N) { return N->end(); }
+};
+
+/// \brief An analysis pass which computes the call graph for a module.
+class LazyCallGraphAnalysis {
+public:
+ /// \brief Inform generic clients of the result type.
+ typedef LazyCallGraph Result;
+
+ static void *ID() { return (void *)&PassID; }
+
+ /// \brief Compute the \c LazyCallGraph for a the module \c M.
+ ///
+ /// This just builds the set of entry points to the call graph. The rest is
+ /// built lazily as it is walked.
+ LazyCallGraph run(Module *M) { return LazyCallGraph(*M); }
+
+private:
+ static char PassID;
+};
+
+/// \brief A pass which prints the call graph to a \c raw_ostream.
+///
+/// This is primarily useful for testing the analysis.
+class LazyCallGraphPrinterPass {
+ raw_ostream &OS;
+
+public:
+ explicit LazyCallGraphPrinterPass(raw_ostream &OS);
+
+ PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM);
+
+ static StringRef name() { return "LazyCallGraphPrinterPass"; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
index 197e94e..a4cb806 100644
--- a/include/llvm/Analysis/LazyValueInfo.h
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -26,7 +26,7 @@ namespace llvm {
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
- class DataLayout *TD;
+ const DataLayout *DL;
class TargetLibraryInfo *TLI;
void *PImpl;
LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
@@ -69,10 +69,10 @@ public:
void eraseBlock(BasicBlock *BB);
// Implementation boilerplate.
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory();
- virtual bool runOnFunction(Function &F);
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void releaseMemory() override;
+ bool runOnFunction(Function &F) override;
};
} // end namespace llvm
diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h
index c01b210..481015e 100644
--- a/include/llvm/Analysis/LibCallAliasAnalysis.h
+++ b/include/llvm/Analysis/LibCallAliasAnalysis.h
@@ -38,17 +38,17 @@ namespace llvm {
~LibCallAliasAnalysis();
ModRefResult getModRefInfo(ImmutableCallSite CS,
- const Location &Loc);
-
+ const Location &Loc) override;
+
ModRefResult getModRefInfo(ImmutableCallSite CS1,
- ImmutableCallSite CS2) {
+ ImmutableCallSite CS2) override {
// 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) {
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ bool runOnFunction(Function &F) override {
InitializeAliasAnalysis(this); // set up super class
return false;
}
@@ -57,7 +57,7 @@ namespace llvm {
/// 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) {
+ void *getAdjustedAnalysisPointer(const void *PI) override {
if (PI == &AliasAnalysis::ID)
return (AliasAnalysis*)this;
return this;
diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h
index f5a9e96..0f0bc23 100644
--- a/include/llvm/Analysis/LibCallSemantics.h
+++ b/include/llvm/Analysis/LibCallSemantics.h
@@ -27,7 +27,7 @@ namespace llvm {
/// 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
+ /// 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,
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 62f5aca..aeeea3c 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -33,8 +33,10 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/Dominators.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/Pass.h"
#include <algorithm>
@@ -53,6 +55,7 @@ class Loop;
class MDNode;
class PHINode;
class raw_ostream;
+template<class N> class DominatorTreeBase;
template<class N, class M> class LoopInfoBase;
template<class N, class M> class LoopBase;
@@ -228,6 +231,18 @@ public:
/// A latch block is a block that contains a branch back to the header.
BlockT *getLoopLatch() const;
+ /// getLoopLatches - Return all loop latch blocks of this loop. A latch block
+ /// is a block that contains a branch back to the header.
+ void getLoopLatches(SmallVectorImpl<BlockT *> &LoopLatches) const {
+ BlockT *H = getHeader();
+ typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
+ for (typename InvBlockTraits::ChildIteratorType I =
+ InvBlockTraits::child_begin(H),
+ E = InvBlockTraits::child_end(H); I != E; ++I)
+ if (contains(*I))
+ LoopLatches.push_back(*I);
+ }
+
//===--------------------------------------------------------------------===//
// APIs for updating loop information after changing the CFG
//
@@ -639,15 +654,15 @@ public:
/// runOnFunction - Calculate the natural loop information.
///
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
- virtual void verifyAnalysis() const;
+ void verifyAnalysis() const override;
- virtual void releaseMemory() { LI.releaseMemory(); }
+ void releaseMemory() override { LI.releaseMemory(); }
- virtual void print(raw_ostream &O, const Module* M = 0) const;
+ void print(raw_ostream &O, const Module* M = 0) const override;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
/// 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
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index c98cb58..dd2dc28 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -15,9 +15,11 @@
#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
#define LLVM_ANALYSIS_LOOPINFOIMPL_H
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/Dominators.h"
namespace llvm {
@@ -322,7 +324,7 @@ void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth) const {
for (unsigned i = 0; i < getBlocks().size(); ++i) {
if (i) OS << ",";
BlockT *BB = getBlocks()[i];
- WriteAsOperand(OS, BB, false);
+ BB->printAsOperand(OS, false);
if (BB == getHeader()) OS << "<header>";
if (BB == getLoopLatch()) OS << "<latch>";
if (isLoopExiting(BB)) OS << "<exiting>";
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
index 5926610..726e286 100644
--- a/include/llvm/Analysis/LoopPass.h
+++ b/include/llvm/Analysis/LoopPass.h
@@ -32,7 +32,8 @@ public:
/// getPrinterPass - Get a pass to print the function corresponding
/// to a Loop.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
// runOnLoop - This method should be implemented by the subclass to perform
// whatever action is necessary for the specified Loop.
@@ -56,14 +57,13 @@ public:
// LPPassManager passes. In such case, pop LPPassManager from the
// stack. This will force assignPassManager() to create new
// LPPassManger as expected.
- void preparePassManager(PMStack &PMS);
+ void preparePassManager(PMStack &PMS) override;
/// Assign pass manager to manage this pass
- virtual void assignPassManager(PMStack &PMS,
- PassManagerType PMT);
+ void assignPassManager(PMStack &PMS, PassManagerType PMT) override;
/// Return what kind of Pass Manager can manage this pass.
- virtual PassManagerType getPotentialPassManagerType() const {
+ PassManagerType getPotentialPassManagerType() const override {
return PMT_LoopPassManager;
}
@@ -81,6 +81,11 @@ public:
/// deleteAnalysisValue - Delete analysis info associated with value V.
virtual void deleteAnalysisValue(Value *V, Loop *L) {}
+
+protected:
+ /// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
+ /// and most transformation passes should skip it.
+ bool skipOptnoneFunction(const Loop *L) const;
};
class LPPassManager : public FunctionPass, public PMDataManager {
@@ -90,21 +95,21 @@ public:
/// 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 runOnFunction(Function &F) override;
/// Pass Manager itself does not invalidate any analysis info.
// LPPassManager needs LoopInfo.
- void getAnalysisUsage(AnalysisUsage &Info) const;
+ void getAnalysisUsage(AnalysisUsage &Info) const override;
- virtual const char *getPassName() const {
+ const char *getPassName() const override {
return "Loop Pass Manager";
}
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
+ PMDataManager *getAsPMDataManager() override { return this; }
+ Pass *getAsPass() override { return this; }
/// Print passes managed by this manager
- void dumpPassStructure(unsigned Offset);
+ void dumpPassStructure(unsigned Offset) override;
LoopPass *getContainedPass(unsigned N) {
assert(N < PassVector.size() && "Pass number out of range!");
@@ -112,7 +117,7 @@ public:
return LP;
}
- virtual PassManagerType getPassManagerType() const {
+ PassManagerType getPassManagerType() const override {
return PMT_LoopPassManager;
}
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index 91224ad..ff4bc22 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -17,12 +17,12 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/TargetFolder.h"
#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Operator.h"
-#include "llvm/InstVisitor.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/TargetFolder.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
class CallInst;
@@ -190,6 +190,8 @@ public:
return knownSize(SizeOffset) && knownOffset(SizeOffset);
}
+ // These are "private", except they can't actually be made private. Only
+ // compute() should be used by external users.
SizeOffsetType visitAllocaInst(AllocaInst &I);
SizeOffsetType visitArgument(Argument &A);
SizeOffsetType visitCallSite(CallSite CS);
@@ -256,6 +258,7 @@ public:
return knownSize(SizeOffset) && knownOffset(SizeOffset);
}
+ // The individual instruction visitors should be treated as private.
SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
SizeOffsetEvalType visitCallSite(CallSite CS);
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 47afd1b..123d435 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -15,13 +15,12 @@
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
class Function;
@@ -323,24 +322,25 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
- DataLayout *TD;
+ const DataLayout *DL;
DominatorTree *DT;
- OwningPtr<PredIteratorCache> PredCache;
+ std::unique_ptr<PredIteratorCache> PredCache;
+
public:
MemoryDependenceAnalysis();
~MemoryDependenceAnalysis();
static char ID;
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
- bool runOnFunction(Function &);
+ bool runOnFunction(Function &) override;
/// Clean up memory in between runs
- void releaseMemory();
+ void releaseMemory() override;
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
/// and Alias Analysis.
///
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
/// getDependency - Return the instruction on which a memory operation
/// depends. See the class comment for more details. It is illegal to call
@@ -415,7 +415,7 @@ namespace llvm {
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
- const DataLayout &TD);
+ const DataLayout &DL);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index d7a3dd8..6d70edd 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -36,8 +36,8 @@ class PHITransAddr {
/// Addr - The actual address we're analyzing.
Value *Addr;
- /// TD - The target data we are playing with if known, otherwise null.
- const DataLayout *TD;
+ /// The DataLayout we are playing with if known, otherwise null.
+ const DataLayout *DL;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
@@ -45,7 +45,7 @@ class PHITransAddr {
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
- PHITransAddr(Value *addr, const DataLayout *td) : Addr(addr), TD(td), TLI(0) {
+ PHITransAddr(Value *addr, const DataLayout *DL) : Addr(addr), DL(DL), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index a5d098e..9494b7d 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -95,27 +95,6 @@ namespace llvm {
//===--------------------------------------------------------------------===//
//
- // 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();
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index 88ebab4..d330755 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -14,7 +14,7 @@
#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
#define LLVM_ANALYSIS_POSTDOMINATORS_H
-#include "llvm/Analysis/Dominators.h"
+#include "llvm/IR/Dominators.h"
namespace llvm {
@@ -32,9 +32,9 @@ struct PostDominatorTree : public FunctionPass {
~PostDominatorTree();
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
@@ -79,11 +79,17 @@ struct PostDominatorTree : public FunctionPass {
return DT->findNearestCommonDominator(A, B);
}
- virtual void releaseMemory() {
+ /// Get all nodes post-dominated by R, including R itself.
+ void getDescendants(BasicBlock *R,
+ SmallVectorImpl<BasicBlock *> &Result) const {
+ DT->getDescendants(R, Result);
+ }
+
+ void releaseMemory() override {
DT->releaseMemory();
}
- virtual void print(raw_ostream &OS, const Module*) const;
+ void print(raw_ostream &OS, const Module*) const override;
};
FunctionPass* createPostDomTree();
diff --git a/include/llvm/Analysis/PtrUseVisitor.h b/include/llvm/Analysis/PtrUseVisitor.h
index 1802fe8..572d5d7 100644
--- a/include/llvm/Analysis/PtrUseVisitor.h
+++ b/include/llvm/Analysis/PtrUseVisitor.h
@@ -26,8 +26,8 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/InstVisitor.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -219,7 +219,7 @@ public:
U = ToVisit.UseAndIsOffsetKnown.getPointer();
IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
if (IsOffsetKnown)
- Offset = llvm_move(ToVisit.Offset);
+ Offset = std::move(ToVisit.Offset);
Instruction *I = cast<Instruction>(U->getUser());
static_cast<DerivedT*>(this)->visit(I);
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index e873195..4d55408 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -28,6 +28,7 @@
#define LLVM_ANALYSIS_REGIONINFO_H
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Support/Allocator.h"
@@ -312,11 +313,11 @@ public:
/// 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
+ /// @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.
+ /// basic block that forms with getEntry() a (non-canonical) region.
/// NULL if such a basic block does not exist.
Region *getExpandedRegion() const;
@@ -495,13 +496,11 @@ public:
//@{
template <bool IsConst>
class block_iterator_wrapper
- : public df_iterator<typename conditional<IsConst,
- const BasicBlock,
- BasicBlock>::type*> {
- typedef df_iterator<typename conditional<IsConst,
- const BasicBlock,
- BasicBlock>::type*>
- super;
+ : public df_iterator<typename std::conditional<IsConst, const BasicBlock,
+ BasicBlock>::type *> {
+ typedef df_iterator<typename std::conditional<IsConst, const BasicBlock,
+ BasicBlock>::type *> super;
+
public:
typedef block_iterator_wrapper<IsConst> Self;
typedef typename super::pointer pointer;
@@ -545,6 +544,21 @@ public:
const_block_iterator block_end() const {
return const_block_iterator();
}
+
+ typedef iterator_range<block_iterator> block_range;
+ typedef iterator_range<const_block_iterator> const_block_range;
+
+ /// @brief Returns a range view of the basic blocks in the region.
+ inline block_range blocks() {
+ return block_range(block_begin(), block_end());
+ }
+
+ /// @brief Returns a range view of the basic blocks in the region.
+ ///
+ /// This is the 'const' version of the range view.
+ inline const_block_range blocks() const {
+ return const_block_range(block_begin(), block_end());
+ }
//@}
/// @name Element Iterators
@@ -632,7 +646,7 @@ class RegionInfo : public FunctionPass {
// Calculate - detecte all regions in function and build the region tree.
void Calculate(Function& F);
- void releaseMemory();
+ void releaseMemory() override;
// updateStatistics - Update statistic about created regions.
void updateStatistics(Region *R);
@@ -649,10 +663,10 @@ public:
/// @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;
+ bool runOnFunction(Function &F) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void print(raw_ostream &OS, const Module *) const override;
+ void verifyAnalysis() const override;
//@}
/// @brief Get the smallest region that contains a BasicBlock.
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
index 8fd4263..ab4d0e0 100644
--- a/include/llvm/Analysis/RegionIterator.h
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -15,7 +15,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/RegionInfo.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/IR/CFG.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h
index 3907ad9..bd51c49 100644
--- a/include/llvm/Analysis/RegionPass.h
+++ b/include/llvm/Analysis/RegionPass.h
@@ -1,4 +1,4 @@
-//===- RegionPass.h - RegionPass class ------------------------------------===//
+//===- RegionPass.h - RegionPass class --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -55,7 +55,8 @@ public:
/// @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;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
@@ -68,12 +69,12 @@ public:
/// @name PassManager API
///
//@{
- void preparePassManager(PMStack &PMS);
+ void preparePassManager(PMStack &PMS) override;
- virtual void assignPassManager(PMStack &PMS,
- PassManagerType PMT = PMT_RegionPassManager);
+ void assignPassManager(PMStack &PMS,
+ PassManagerType PMT = PMT_RegionPassManager) override;
- virtual PassManagerType getPotentialPassManagerType() const {
+ PassManagerType getPotentialPassManagerType() const override {
return PMT_RegionPassManager;
}
//@}
@@ -94,21 +95,21 @@ public:
/// @brief Execute all of the passes scheduled for execution.
///
/// @return True if any of the passes modifies the function.
- bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
/// Pass Manager itself does not invalidate any analysis info.
/// RGPassManager needs RegionInfo.
- void getAnalysisUsage(AnalysisUsage &Info) const;
+ void getAnalysisUsage(AnalysisUsage &Info) const override;
- virtual const char *getPassName() const {
+ const char *getPassName() const override {
return "Region Pass Manager";
}
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
+ PMDataManager *getAsPMDataManager() override { return this; }
+ Pass *getAsPass() override { return this; }
/// @brief Print passes managed by this manager.
- void dumpPassStructure(unsigned Offset);
+ void dumpPassStructure(unsigned Offset) override;
/// @brief Get passes contained by this manager.
Pass *getContainedPass(unsigned N) {
@@ -117,7 +118,7 @@ public:
return FP;
}
- virtual PassManagerType getPassManagerType() const {
+ PassManagerType getPassManagerType() const override {
return PMT_RegionPassManager;
}
};
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index d7f6178..06489d8 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -23,14 +23,14 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
@@ -207,8 +207,8 @@ namespace llvm {
/// notified whenever a Value is deleted.
class SCEVCallbackVH : public CallbackVH {
ScalarEvolution *SE;
- virtual void deleted();
- virtual void allUsesReplacedWith(Value *New);
+ void deleted() override;
+ void allUsesReplacedWith(Value *New) override;
public:
SCEVCallbackVH(Value *V, ScalarEvolution *SE = 0);
};
@@ -225,9 +225,9 @@ namespace llvm {
///
LoopInfo *LI;
- /// TD - The target data information for the target we are targeting.
+ /// The DataLayout information for the target we are targeting.
///
- DataLayout *TD;
+ const DataLayout *DL;
/// TLI - The target library information for the target we are targeting.
///
@@ -253,17 +253,28 @@ namespace llvm {
/// Mark predicate values currently being processed by isImpliedCond.
DenseSet<Value*> PendingLoopPredicates;
- /// 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.
+ /// 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.
+ ///
+ /// If MustExit is true, then the exit must be taken when the BECount
+ /// reaches Exact (and before surpassing Max). If MustExit is false, then
+ /// BECount may exceed Exact or Max if the loop exits via another branch. In
+ /// either case, the loop may exit early via another branch.
+ ///
+ /// MustExit is true for most cases. However, an exit guarded by an
+ /// (in)equality on a nonunit stride may be skipped.
struct ExitLimit {
const SCEV *Exact;
const SCEV *Max;
+ bool MustExit;
- /*implicit*/ ExitLimit(const SCEV *E) : Exact(E), Max(E) {}
+ /*implicit*/ ExitLimit(const SCEV *E)
+ : Exact(E), Max(E), MustExit(true) {}
- ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {}
+ ExitLimit(const SCEV *E, const SCEV *M, bool MustExit)
+ : Exact(E), Max(M), MustExit(MustExit) {}
/// hasAnyInfo - Test whether this ExitLimit contains any computed
/// information, or whether it's all SCEVCouldNotCompute values.
@@ -458,6 +469,13 @@ namespace llvm {
BasicBlock *FBB,
bool IsSubExpr);
+ /// ComputeExitLimitFromSingleExitSwitch - Compute the number of times the
+ /// backedge of the specified loop will execute if its exit condition were a
+ /// switch with a single exiting case to ExitingBB.
+ ExitLimit
+ ComputeExitLimitFromSingleExitSwitch(const Loop *L, SwitchInst *Switch,
+ BasicBlock *ExitingBB, bool IsSubExpr);
+
/// ComputeLoadConstantCompareExitLimit - Given an exit condition
/// of 'icmp op load X, cst', try to see if we can compute the
/// backedge-taken count.
@@ -613,6 +631,7 @@ namespace llvm {
return getMulExpr(Ops, Flags);
}
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getUDivExactExpr(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,
@@ -784,6 +803,13 @@ namespace llvm {
/// disconnect it from a def-use chain linking it to a loop.
void forgetValue(Value *V);
+ /// \brief Called when the client has changed the disposition of values in
+ /// this loop.
+ ///
+ /// We don't have a way to invalidate per-loop dispositions. Clear and
+ /// recompute is simpler.
+ void forgetLoopDispositions(const Loop *L) { LoopDispositions.clear(); }
+
/// 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,
@@ -868,11 +894,11 @@ namespace llvm {
/// 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;
- virtual void verifyAnalysis() const;
+ bool runOnFunction(Function &F) override;
+ void releaseMemory() override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void print(raw_ostream &OS, const Module* = 0) const override;
+ void verifyAnalysis() const override;
private:
/// Compute the backedge taken count knowing the interval difference, the
@@ -880,13 +906,13 @@ namespace llvm {
const SCEV *computeBECount(const SCEV *Delta, const SCEV *Stride,
bool Equality);
- /// Verify if an linear IV with positive stride can overflow when in a
+ /// Verify if an linear IV with positive stride can overflow when in a
/// less-than comparison, knowing the invariant term of the comparison,
/// the stride and the knowledge of NSW/NUW flags on the recurrence.
bool doesIVOverflowOnLT(const SCEV *RHS, const SCEV *Stride,
bool IsSigned, bool NoWrap);
- /// Verify if an linear IV with negative stride can overflow when in a
+ /// Verify if an linear IV with negative stride can overflow when in a
/// greater-than comparison, knowing the invariant term of the comparison,
/// the stride and the knowledge of NSW/NUW flags on the recurrence.
bool doesIVOverflowOnGT(const SCEV *RHS, const SCEV *Stride,
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 4433be0..9162735 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -16,9 +16,9 @@
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
+#include "llvm/Analysis/TargetFolder.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/Support/TargetFolder.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include <set>
namespace llvm {
@@ -94,7 +94,7 @@ namespace llvm {
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)) {
+ Builder(se.getContext(), TargetFolder(se.DL)) {
#ifndef NDEBUG
DebugType = "";
#endif
@@ -260,7 +260,9 @@ namespace llvm {
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
const Loop *L,
Type *ExpandTy,
- Type *IntTy);
+ Type *IntTy,
+ Type *&TruncTy,
+ bool &InvertStep);
Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
Type *ExpandTy, Type *IntTy, bool useSubtract);
};
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 9cd902a..ed8c133 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -410,8 +410,8 @@ namespace llvm {
friend class ScalarEvolution;
// Implement CallbackVH.
- virtual void deleted();
- virtual void allUsesReplacedWith(Value *New);
+ void deleted() override;
+ void allUsesReplacedWith(Value *New) override;
/// SE - The parent ScalarEvolution value. This is used to update
/// the parent's maps when the value associated with a SCEVUnknown
@@ -563,13 +563,14 @@ namespace llvm {
: public SCEVVisitor<SCEVParameterRewriter, const SCEV*> {
public:
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
- ValueToValueMap &Map) {
- SCEVParameterRewriter Rewriter(SE, Map);
+ ValueToValueMap &Map,
+ bool InterpretConsts = false) {
+ SCEVParameterRewriter Rewriter(SE, Map, InterpretConsts);
return Rewriter.visit(Scev);
}
- SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M)
- : SE(S), Map(M) {}
+ SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M, bool C)
+ : SE(S), Map(M), InterpretConsts(C) {}
const SCEV *visitConstant(const SCEVConstant *Constant) {
return Constant;
@@ -632,8 +633,12 @@ namespace llvm {
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
Value *V = Expr->getValue();
- if (Map.count(V))
- return SE.getUnknown(Map[V]);
+ if (Map.count(V)) {
+ Value *NV = Map[V];
+ if (InterpretConsts && isa<ConstantInt>(NV))
+ return SE.getConstant(cast<ConstantInt>(NV));
+ return SE.getUnknown(NV);
+ }
return Expr;
}
@@ -644,6 +649,7 @@ namespace llvm {
private:
ScalarEvolution &SE;
ValueToValueMap &Map;
+ bool InterpretConsts;
};
typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT;
diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h
index 5c1978d..8a7fc7c 100644
--- a/include/llvm/Support/TargetFolder.h
+++ b/include/llvm/Analysis/TargetFolder.h
@@ -1,4 +1,4 @@
-//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====//
+//====- TargetFolder.h - Constant folding helper ---------------*- C++ -*-====//
//
// The LLVM Compiler Infrastructure
//
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_TARGETFOLDER_H
-#define LLVM_SUPPORT_TARGETFOLDER_H
+#ifndef LLVM_ANALYSIS_TARGETFOLDER_H
+#define LLVM_ANALYSIS_TARGETFOLDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/ConstantFolding.h"
@@ -30,18 +30,18 @@ class DataLayout;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
- const DataLayout *TD;
+ const DataLayout *DL;
/// 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))
+ if (Constant *CF = ConstantFoldConstantExpression(CE, DL))
return CF;
return C;
}
public:
- explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {}
+ explicit TargetFolder(const DataLayout *DL) : DL(DL) {}
//===--------------------------------------------------------------------===//
// Binary Operators
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index 4f47562..2ac6ffa 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -59,11 +59,6 @@ protected:
/// group's stack.
void pushTTIStack(Pass *P);
- /// All pass subclasses must in their finalizePass routine call popTTIStack
- /// to update the pointers tracking the previous TTI instance in the analysis
- /// group's stack, and the top of the analysis group's stack.
- void popTTIStack();
-
/// All pass subclasses must call TargetTransformInfo::getAnalysisUsage.
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
@@ -203,11 +198,23 @@ public:
/// The cost threshold for the unrolled loop when optimizing for size (set
/// to UINT_MAX to disable).
unsigned OptSizeThreshold;
+ /// The cost threshold for the unrolled loop, like Threshold, but used
+ /// for partial/runtime unrolling (set to UINT_MAX to disable).
+ unsigned PartialThreshold;
+ /// The cost threshold for the unrolled loop when optimizing for size, like
+ /// OptSizeThreshold, but used for partial/runtime unrolling (set to UINT_MAX
+ /// to disable).
+ unsigned PartialOptSizeThreshold;
/// A forced unrolling factor (the number of concatenated bodies of the
/// original loop in the unrolled loop body). When set to 0, the unrolling
/// transformation will select an unrolling factor based on the current cost
/// threshold and other factors.
unsigned Count;
+ // Set the maximum unrolling factor. The unrolling factor may be selected
+ // using the appropriate cost threshold, but may not exceed this number
+ // (set to UINT_MAX to disable). This does not apply in cases where the
+ // loop is being fully unrolled.
+ unsigned MaxCount;
/// Allow partial unrolling (unrolling of loops to expand the size of the
/// loop body, not only to eliminate small constant-trip-count loops).
bool Partial;
@@ -241,20 +248,19 @@ public:
PSK_FastHardware
};
- /// isLegalAddImmediate - Return true if the specified immediate is legal
- /// add immediate, that is the target has add instructions which can add
- /// a register with the immediate without having to materialize the
- /// immediate into a register.
+ /// \brief Return true if the specified immediate is legal add immediate, that
+ /// is the target has add instructions which can add a register with the
+ /// immediate without having to materialize the immediate into a register.
virtual bool isLegalAddImmediate(int64_t Imm) const;
- /// isLegalICmpImmediate - Return true if the specified immediate is legal
- /// icmp immediate, that is the target has icmp instructions which can compare
- /// a register against the immediate without having to materialize the
- /// immediate into a register.
+ /// \brief Return true if the specified immediate is legal icmp immediate,
+ /// that is the target has icmp instructions which can compare a register
+ /// against the immediate without having to materialize the immediate into a
+ /// register.
virtual bool isLegalICmpImmediate(int64_t Imm) const;
- /// isLegalAddressingMode - Return true if the addressing mode represented by
- /// AM is legal for this target, for a load/store of the specified type.
+ /// \brief 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.
@@ -272,35 +278,41 @@ public:
int64_t BaseOffset, bool HasBaseReg,
int64_t Scale) const;
- /// isTruncateFree - Return true if it's free to truncate a value of
- /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
- /// register EAX to i16 by referencing its sub-register AX.
+ /// \brief Return true if it's free to truncate a value of type Ty1 to type
+ /// Ty2. e.g. On x86 it's free to truncate a i32 value in register EAX to i16
+ /// by referencing its sub-register AX.
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
- /// Is this type legal.
+ /// \brief Return true if this type is legal.
virtual bool isTypeLegal(Type *Ty) const;
- /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
+ /// \brief Returns the target's jmp_buf alignment in bytes.
virtual unsigned getJumpBufAlignment() const;
- /// getJumpBufSize - returns the target's jmp_buf size in bytes.
+ /// \brief Returns the target's jmp_buf size in bytes.
virtual unsigned getJumpBufSize() const;
- /// shouldBuildLookupTables - Return true if switches should be turned into
- /// lookup tables for the target.
+ /// \brief Return true if switches should be turned into lookup tables for the
+ /// target.
virtual bool shouldBuildLookupTables() const;
- /// getPopcntSupport - Return hardware support for population count.
+ /// \brief Return hardware support for population count.
virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
- /// haveFastSqrt -- Return true if the hardware has a fast square-root
- /// instruction.
+ /// \brief Return true if the hardware has a fast square-root instruction.
virtual bool haveFastSqrt(Type *Ty) const;
- /// getIntImmCost - Return the expected cost of materializing the given
- /// integer immediate of the specified type.
+ /// \brief Return the expected cost of materializing for the given integer
+ /// immediate of the specified type.
virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
+ /// \brief Return the expected cost of materialization for the given integer
+ /// immediate of the specified type for a given instruction. The cost can be
+ /// zero if the immediate can be folded into the specified instruction.
+ virtual unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm,
+ Type *Ty) const;
+ virtual unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx,
+ const APInt &Imm, Type *Ty) const;
/// @}
/// \name Vector Target Information
@@ -316,9 +328,10 @@ public:
/// \brief Additional information about an operand's possible values.
enum OperandValueKind {
- OK_AnyValue, // Operand can have any value.
- OK_UniformValue, // Operand is uniform (splat of a value).
- OK_UniformConstantValue // Operand is uniform constant.
+ OK_AnyValue, // Operand can have any value.
+ OK_UniformValue, // Operand is uniform (splat of a value).
+ OK_UniformConstantValue, // Operand is uniform constant.
+ OK_NonUniformConstantValue // Operand is a non uniform constant value.
};
/// \return The number of scalar or vector registers that the target has.
diff --git a/include/llvm/Analysis/Verifier.h b/include/llvm/Analysis/Verifier.h
deleted file mode 100644
index ce8aeef..0000000
--- a/include/llvm/Analysis/Verifier.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- 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/include/llvm/Assembly/Parser.h b/include/llvm/AsmParser/Parser.h
index b971c53..165c46d 100644
--- a/include/llvm/Assembly/Parser.h
+++ b/include/llvm/AsmParser/Parser.h
@@ -1,4 +1,4 @@
-//===-- llvm/Assembly/Parser.h - Parser for VM assembly files ---*- C++ -*-===//
+//===-- Parser.h - Parser for LLVM IR text assembly files -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ASSEMBLY_PARSER_H
-#define LLVM_ASSEMBLY_PARSER_H
+#ifndef LLVM_ASMPARSER_PARSER_H
+#define LLVM_ASMPARSER_PARSER_H
#include <string>
diff --git a/include/llvm/Assembly/PrintModulePass.h b/include/llvm/Assembly/PrintModulePass.h
deleted file mode 100644
index 02b9bd9..0000000
--- a/include/llvm/Assembly/PrintModulePass.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- 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 BasicBlockPass;
- 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);
-
- /// createPrintBasicBlockPass - Create and return a pass that writes the
- /// BB to the specified raw_ostream.
- BasicBlockPass *createPrintBasicBlockPass(raw_ostream *OS,
- bool DeleteStream=false,
- const std::string &Banner = "");
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Assembly/Writer.h b/include/llvm/Assembly/Writer.h
deleted file mode 100644
index 6b89ae0..0000000
--- a/include/llvm/Assembly/Writer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- 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/include/llvm/Bitcode/BitcodeWriterPass.h b/include/llvm/Bitcode/BitcodeWriterPass.h
new file mode 100644
index 0000000..898cd52
--- /dev/null
+++ b/include/llvm/Bitcode/BitcodeWriterPass.h
@@ -0,0 +1,51 @@
+//===-- BitcodeWriterPass.h - Bitcode writing pass --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides a bitcode writing pass.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODE_WRITER_PASS_H
+#define LLVM_BITCODE_BITCODE_WRITER_PASS_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+class Module;
+class ModulePass;
+class raw_ostream;
+class PreservedAnalyses;
+
+/// \brief Create and return a pass that writes the module to the specified
+/// ostream. Note that this pass is designed for use with the legacy pass
+/// manager.
+ModulePass *createBitcodeWriterPass(raw_ostream &Str);
+
+/// \brief Pass for writing a module of IR out to a bitcode file.
+///
+/// Note that this is intended for use with the new pass manager. To construct
+/// a pass for the legacy pass manager, use the function above.
+class BitcodeWriterPass {
+ raw_ostream &OS;
+
+public:
+ /// \brief Construct a bitcode writer pass around a particular output stream.
+ explicit BitcodeWriterPass(raw_ostream &OS) : OS(OS) {}
+
+ /// \brief Run the bitcode writer pass, and output the module to the selected
+ /// output stream.
+ PreservedAnalyses run(Module *M);
+
+ static StringRef name() { return "BitcodeWriterPass"; }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index dc5e095..fcbf426 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -15,7 +15,6 @@
#ifndef LLVM_BITCODE_BITSTREAMREADER_H
#define LLVM_BITCODE_BITSTREAMREADER_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/StreamableMemoryObject.h"
@@ -44,7 +43,7 @@ public:
std::vector<std::pair<unsigned, std::string> > RecordNames;
};
private:
- OwningPtr<StreamableMemoryObject> BitcodeBytes;
+ std::unique_ptr<StreamableMemoryObject> BitcodeBytes;
std::vector<BlockInfo> BlockInfoRecords;
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index f40a0d1..ef88a88 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -97,7 +97,7 @@ public:
: Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
~BitstreamWriter() {
- assert(CurBit == 0 && "Unflused data remaining");
+ assert(CurBit == 0 && "Unflushed data remaining");
assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
// Free the BlockInfoRecords.
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index b3d2466..7e6831b 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -370,7 +370,8 @@ namespace bitc {
ATTR_KIND_Z_EXT = 34,
ATTR_KIND_BUILTIN = 35,
ATTR_KIND_COLD = 36,
- ATTR_KIND_OPTIMIZE_NONE = 37
+ ATTR_KIND_OPTIMIZE_NONE = 37,
+ ATTR_KIND_IN_ALLOCA = 38
};
} // End bitc namespace
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index 78f40ca..0918e92 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -14,6 +14,7 @@
#ifndef LLVM_BITCODE_READERWRITER_H
#define LLVM_BITCODE_READERWRITER_H
+#include "llvm/Support/ErrorOr.h"
#include <string>
namespace llvm {
@@ -25,14 +26,11 @@ namespace llvm {
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);
+ /// Read the header of the specified bitcode buffer and prepare for lazy
+ /// deserialization of function bodies. If successful, this takes ownership
+ /// of 'buffer. On error, this *does not* take ownership of Buffer.
+ ErrorOr<Module *> getLazyBitcodeModule(MemoryBuffer *Buffer,
+ LLVMContext &Context);
/// getStreamedBitcodeModule - Read the header of the specified stream
/// and prepare for lazy deserialization and streaming of function bodies.
@@ -52,21 +50,16 @@ namespace llvm {
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);
+ /// Read the specified bitcode file, returning the module.
+ /// This method *never* takes ownership of Buffer.
+ ErrorOr<Module *> parseBitcodeFile(MemoryBuffer *Buffer,
+ LLVMContext &Context);
/// 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.
diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt
index 32ffca7..0f5c63d 100644
--- a/include/llvm/CMakeLists.txt
+++ b/include/llvm/CMakeLists.txt
@@ -2,12 +2,13 @@ add_subdirectory(IR)
if( MSVC_IDE OR XCODE )
# Creates a dummy target containing all headers for the benefit of
- # Visual Studio users.
+ # XCode and Visual Studio users.
file(GLOB_RECURSE headers *.h)
add_td_sources(headers)
add_library(llvm_headers_do_not_build EXCLUDE_FROM_ALL
# We need at least one source file:
${LLVM_MAIN_SRC_DIR}/lib/Transforms/Hello/Hello.cpp
${headers})
- set_target_properties(llvm_headers_do_not_build PROPERTIES FOLDER "Misc")
+ set_target_properties(llvm_headers_do_not_build PROPERTIES FOLDER "Misc"
+ EXCLUDE_FROM_DEFAULT_BUILD ON)
endif()
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index b2cc704..5f2bbd6 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -17,19 +17,18 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ISDOpcodes.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/Support/CallSite.h"
namespace llvm {
-
class GlobalVariable;
-class TargetLowering;
class TargetLoweringBase;
class SDNode;
class SDValue;
class SelectionDAG;
+class TargetLowering;
+struct EVT;
/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
/// of insertvalue or extractvalue indices that identify a member, return
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 4bda0f1..d96d810 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -16,13 +16,16 @@
#ifndef LLVM_CODEGEN_ASMPRINTER_H
#define LLVM_CODEGEN_ASMPRINTER_H
+#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
+ class AsmPrinterHandler;
class BlockAddress;
+ class ByteStreamer;
class GCStrategy;
class Constant;
class ConstantArray;
@@ -41,9 +44,11 @@ namespace llvm {
class MCAsmInfo;
class MCCFIInstruction;
class MCContext;
+ class MCInst;
class MCInstrInfo;
class MCSection;
class MCStreamer;
+ class MCSubtargetInfo;
class MCSymbol;
class MDNode;
class DwarfDebug;
@@ -110,20 +115,28 @@ namespace llvm {
/// function.
MachineLoopInfo *LI;
+ struct HandlerInfo {
+ AsmPrinterHandler *Handler;
+ const char *TimerName, *TimerGroupName;
+ HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName,
+ const char *TimerGroupName)
+ : Handler(Handler), TimerName(TimerName),
+ TimerGroupName(TimerGroupName) {}
+ };
+ /// Handlers - a vector of all debug/EH info emitters we should use.
+ /// This vector maintains ownership of the emitters.
+ SmallVector<HandlerInfo, 1> Handlers;
+
/// 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();
- const DwarfDebug *getDwarfDebug() const { return DD; }
+ DwarfDebug *getDwarfDebug() { return DD; }
/// isVerbose - Return true if assembly output should contain comments.
///
@@ -139,12 +152,20 @@ namespace llvm {
/// getDataLayout - Return information about data layout.
const DataLayout &getDataLayout() const;
+ /// getSubtargetInfo - Return information about subtarget.
+ const MCSubtargetInfo &getSubtargetInfo() const;
+
+ void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
+
/// getTargetTriple - Return the target triple string.
StringRef getTargetTriple() const;
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *getCurrentSection() const;
+ void getNameWithPrefix(SmallVectorImpl<char> &Name,
+ const GlobalValue *GV) const;
+
MCSymbol *getSymbol(const GlobalValue *GV) const;
//===------------------------------------------------------------------===//
@@ -153,20 +174,20 @@ namespace llvm {
/// getAnalysisUsage - Record analysis usage.
///
- void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
/// 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);
+ bool doInitialization(Module &M) override;
/// doFinalization - Shut down the asmprinter. If you override this in your
/// pass, you must make sure to call it explicitly.
- bool doFinalization(Module &M);
+ bool doFinalization(Module &M) override;
/// runOnMachineFunction - Emit the specified function out to the
/// OutStreamer.
- virtual bool runOnMachineFunction(MachineFunction &MF) {
+ bool runOnMachineFunction(MachineFunction &MF) override {
SetupMachineFunction(MF);
EmitFunctionHeader();
EmitFunctionBody();
@@ -189,7 +210,7 @@ namespace llvm {
/// function.
void EmitFunctionBody();
- void emitPrologLabel(const MachineInstr &MI);
+ void emitCFIInstruction(const MachineInstr &MI);
enum CFIMoveType {
CFI_M_None,
@@ -200,11 +221,6 @@ namespace llvm {
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
@@ -270,6 +286,9 @@ namespace llvm {
llvm_unreachable("EmitInstruction not implemented");
}
+ /// GetCPISymbol - Return the symbol for the specified constant pool entry.
+ virtual MCSymbol *GetCPISymbol(unsigned CPID) const;
+
virtual void EmitFunctionEntryLabel();
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
@@ -298,27 +317,21 @@ namespace llvm {
/// GetTempSymbol - Return the MCSymbol corresponding to the assembler
/// temporary label with the specified stem and unique ID.
- MCSymbol *GetTempSymbol(StringRef Name, unsigned ID) const;
+ MCSymbol *GetTempSymbol(Twine Name, unsigned ID) const;
/// GetTempSymbol - Return an assembler temporary label with the specified
/// stem.
- MCSymbol *GetTempSymbol(StringRef Name) const;
-
+ MCSymbol *GetTempSymbol(Twine 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;
+ /// Return the MCSymbol for a private symbol with global value name as its
+ /// base, with the specified suffix.
+ MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
+ StringRef Suffix) 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;
@@ -418,7 +431,7 @@ namespace llvm {
virtual unsigned getISAEncoding() { return 0; }
/// EmitDwarfRegOp - Emit dwarf register operation.
- virtual void EmitDwarfRegOp(const MachineLocation &MLoc,
+ virtual void EmitDwarfRegOp(ByteStreamer &BS, const MachineLocation &MLoc,
bool Indirect) const;
//===------------------------------------------------------------------===//
@@ -460,6 +473,15 @@ namespace llvm {
unsigned AsmVariant,
const char *ExtraCode, raw_ostream &OS);
+ /// Let the target do anything it needs to do after emitting inlineasm.
+ /// This callback can be used restore the original mode in case the
+ /// inlineasm contains directives to switch modes.
+ /// \p StartInfo - the original subtarget info before inline asm
+ /// \p EndInfo - the final subtarget info after parsing the inline asm,
+ /// or NULL if the value is unknown.
+ virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
+ const MCSubtargetInfo *EndInfo) const;
+
private:
/// Private state for PrintSpecial()
// Assign a unique ID to this machine instruction.
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index a18f433..50bbb0d 100644
--- a/include/llvm/CodeGen/CallingConvLower.h
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -18,14 +18,14 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/Target/TargetCallingConv.h"
namespace llvm {
- class TargetRegisterInfo;
- class TargetMachine;
- class CCState;
+class CCState;
+class MVT;
+class TargetMachine;
+class TargetRegisterInfo;
/// CCValAssign - Represent assignment of one arg/retval to a location.
class CCValAssign {
@@ -39,6 +39,7 @@ public:
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.
+ FPExt, // The floating-point value is fp-extended in the location.
Indirect // The location contains pointer to the value.
// TODO: a subset of the value is in the location.
};
@@ -347,6 +348,15 @@ public:
return AllocateStack(Size, Align);
}
+ /// Version of AllocateStack with list of extra registers to be shadowed.
+ /// Note that, unlike AllocateReg, this shadows ALL of the shadow registers.
+ unsigned AllocateStack(unsigned Size, unsigned Align,
+ const uint16_t *ShadowRegs, unsigned NumShadowRegs) {
+ for (unsigned i = 0; i < NumShadowRegs; ++i)
+ MarkAllocated(ShadowRegs[i]);
+ 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.
@@ -394,6 +404,11 @@ public:
ByValRegs.clear();
}
+ // Rewind byval registers tracking info.
+ void rewindByValRegsInfo() {
+ InRegsParamsProceed = 0;
+ }
+
ParmContext getCallOrPrologue() const { return CallOrPrologue; }
private:
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index bc8dce3..02a4bb5 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -19,6 +19,7 @@
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include <string>
using namespace llvm;
@@ -85,9 +86,6 @@ FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
"Emit nothing, for performance testing"),
clEnumValEnd));
-cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
- cl::desc("Do not use .loc entries"));
-
cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden,
cl::desc("Do not use .cfi_* directives"));
@@ -210,4 +208,30 @@ cl::opt<std::string> StartAfter("start-after",
cl::value_desc("pass-name"),
cl::init(""));
+// Common utility function tightly tied to the options listed here. Initializes
+// a TargetOptions object with CodeGen flags and returns it.
+static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
+ TargetOptions Options;
+ Options.LessPreciseFPMADOption = EnableFPMAD;
+ Options.NoFramePointerElim = DisableFPElim;
+ Options.AllowFPOpFusion = FuseFPOps;
+ Options.UnsafeFPMath = EnableUnsafeFPMath;
+ Options.NoInfsFPMath = EnableNoInfsFPMath;
+ Options.NoNaNsFPMath = EnableNoNaNsFPMath;
+ Options.HonorSignDependentRoundingFPMathOption =
+ EnableHonorSignDependentRoundingFPMath;
+ Options.UseSoftFloat = GenerateSoftFloatCalls;
+ if (FloatABIForCalls != FloatABI::Default)
+ Options.FloatABIType = FloatABIForCalls;
+ Options.NoZerosInBSS = DontPlaceZerosInBSS;
+ Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
+ Options.DisableTailCalls = DisableTailCalls;
+ Options.StackAlignmentOverride = OverrideStackAlignment;
+ Options.TrapFuncName = TrapFuncName;
+ Options.PositionIndependentExecutable = EnablePIE;
+ Options.EnableSegmentedStacks = SegmentedStacks;
+ Options.UseInitArray = UseInitArray;
+ return Options;
+}
+
#endif
diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h
index e8a4a2d..2899fe1 100644
--- a/include/llvm/CodeGen/EdgeBundles.h
+++ b/include/llvm/CodeGen/EdgeBundles.h
@@ -55,8 +55,8 @@ public:
void view() const;
private:
- virtual bool runOnMachineFunction(MachineFunction&);
- virtual void getAnalysisUsage(AnalysisUsage&) const;
+ bool runOnMachineFunction(MachineFunction&) override;
+ void getAnalysisUsage(AnalysisUsage&) const override;
};
/// Specialize WriteGraph, the standard implementation won't work.
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 1e0ef6b..aeffbd4 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -17,22 +17,22 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/ValueTypes.h"
namespace llvm {
class AllocaInst;
class Constant;
class ConstantFP;
+class DataLayout;
class FunctionLoweringInfo;
class Instruction;
class LoadInst;
+class MVT;
class MachineConstantPool;
+class MachineFrameInfo;
class MachineFunction;
class MachineInstr;
-class MachineFrameInfo;
class MachineRegisterInfo;
-class DataLayout;
class TargetInstrInfo;
class TargetLibraryInfo;
class TargetLowering;
@@ -51,9 +51,9 @@ protected:
MachineRegisterInfo &MRI;
MachineFrameInfo &MFI;
MachineConstantPool &MCP;
- DebugLoc DL;
+ DebugLoc DbgLoc;
const TargetMachine &TM;
- const DataLayout &TD;
+ const DataLayout &DL;
const TargetInstrInfo &TII;
const TargetLowering &TLI;
const TargetRegisterInfo &TRI;
@@ -87,7 +87,7 @@ public:
void startNewBlock();
/// Return current debug location information.
- DebugLoc getCurDebugLoc() const { return DL; }
+ DebugLoc getCurDebugLoc() const { return DbgLoc; }
/// Do "fast" instruction selection for function arguments and append machine
/// instructions to the current block. Return true if it is successful.
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index 50d320f..06e7aaa 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -21,7 +21,6 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -41,6 +40,8 @@ class MachineBasicBlock;
class MachineFunction;
class MachineModuleInfo;
class MachineRegisterInfo;
+class SelectionDAG;
+class MVT;
class TargetLowering;
class Value;
@@ -125,7 +126,7 @@ public:
/// set - Initialize this FunctionLoweringInfo with the given Function
/// and its associated MachineFunction.
///
- void set(const Function &Fn, MachineFunction &MF);
+ void set(const Function &Fn, MachineFunction &MF, SelectionDAG *DAG);
/// clear - Clear out all the function-specific state. This returns this
/// FunctionLoweringInfo to an empty state, ready to be used for a
diff --git a/include/llvm/CodeGen/GCMetadata.h b/include/llvm/CodeGen/GCMetadata.h
index 1070d29..ea94542 100644
--- a/include/llvm/CodeGen/GCMetadata.h
+++ b/include/llvm/CodeGen/GCMetadata.h
@@ -35,8 +35,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/Pass.h"
-#include "llvm/Support/DebugLoc.h"
namespace llvm {
class AsmPrinter;
diff --git a/include/llvm/CodeGen/GCs.h b/include/llvm/CodeGen/GCs.h
index 456d2dc..bb170c8 100644
--- a/include/llvm/CodeGen/GCs.h
+++ b/include/llvm/CodeGen/GCs.h
@@ -17,13 +17,13 @@
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();
@@ -32,7 +32,7 @@ namespace llvm {
/// Creates an erlang-compatible metadata printer.
void linkErlangGCPrinter();
-
+
/// Creates a shadow stack garbage collector. This collector requires no code
/// generator support.
void linkShadowStackGC();
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 48a0523..89b0908 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -603,7 +603,7 @@ namespace ISD {
/// This corresponds to "load atomic" instruction.
ATOMIC_LOAD,
- /// OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val)
+ /// OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val)
/// This corresponds to "store atomic" instruction.
ATOMIC_STORE,
@@ -702,6 +702,8 @@ namespace ISD {
LAST_LOADEXT_TYPE
};
+ NodeType getExtForLoadExtType(LoadExtType);
+
//===--------------------------------------------------------------------===//
/// ISD::CondCode enum - These are ordered carefully to make the bitfields
/// below work out, when considering SETFALSE (something that never exists
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
index 68389dd..9e6ab7d 100644
--- a/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -24,13 +24,13 @@ namespace llvm {
class DataLayout;
class IntrinsicLowering {
- const DataLayout& TD;
+ const DataLayout& DL;
bool Warned;
public:
- explicit IntrinsicLowering(const DataLayout &td) :
- TD(td), Warned(false) {}
+ explicit IntrinsicLowering(const DataLayout &DL) :
+ DL(DL), Warned(false) {}
/// AddPrototypes - This method, if called, causes all of the prototypes
/// that might be needed by an intrinsic lowering implementation to be
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index 9a73214..bb0df2e 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -51,7 +51,7 @@ class Function;
/// occurred, more memory is allocated, and we reemit the code into it.
///
class JITCodeEmitter : public MachineCodeEmitter {
- virtual void anchor();
+ void anchor() override;
public:
virtual ~JITCodeEmitter() {}
@@ -59,15 +59,15 @@ public:
/// about to be code generated. This initializes the BufferBegin/End/Ptr
/// fields.
///
- virtual void startFunction(MachineFunction &F) = 0;
+ void startFunction(MachineFunction &F) override = 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;
-
+ bool finishFunction(MachineFunction &F) override = 0;
+
/// allocIndirectGV - Allocates and fills storage for an indirect
/// GlobalValue, and returns the address.
virtual void *allocIndirectGV(const GlobalValue *GV,
@@ -248,12 +248,12 @@ public:
/// emitLabel - Emits a label
- virtual void emitLabel(MCSymbol *Label) = 0;
+ void emitLabel(MCSymbol *Label) override = 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) {
+ void *allocateSpace(uintptr_t Size, unsigned Alignment) override {
emitAlignment(Alignment);
void *Result;
@@ -278,18 +278,18 @@ public:
/// 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;
-
+ void StartMachineBasicBlock(MachineBasicBlock *MBB) override = 0;
+
/// getCurrentPCValue - This returns the address that the next emitted byte
/// will be output to.
///
- virtual uintptr_t getCurrentPCValue() const {
+ uintptr_t getCurrentPCValue() const override {
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 {
+ uintptr_t getCurrentPCOffset() const override {
return CurBufferPtr-BufferBegin;
}
@@ -298,38 +298,39 @@ public:
/// 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; }
+ bool earlyResolveAddresses() const override { return true; }
/// addRelocation - Whenever a relocatable address is needed, it should be
/// noted with this interface.
- virtual void addRelocation(const MachineRelocation &MR) = 0;
-
+ void addRelocation(const MachineRelocation &MR) override = 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;
+ uintptr_t getConstantPoolEntryAddress(unsigned Index) const override = 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;
-
+ uintptr_t getJumpTableEntryAddress(unsigned Index) const override = 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;
+ uintptr_t
+ getMachineBasicBlockAddress(MachineBasicBlock *MBB) const override = 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;
-
+ uintptr_t getLabelAddress(MCSymbol *Label) const override = 0;
+
/// Specifies the MachineModuleInfo object. This is used for exception handling
/// purposes.
- virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
+ void setModuleInfo(MachineModuleInfo* Info) override = 0;
/// getLabelLocations - Return the label locations map of the label IDs to
/// their address.
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
index d454347..d566da8 100644
--- a/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -47,21 +47,21 @@ namespace llvm {
LatencyPriorityQueue() : Picker(this) {
}
- bool isBottomUp() const { return false; }
+ bool isBottomUp() const override { return false; }
- void initNodes(std::vector<SUnit> &sunits) {
+ void initNodes(std::vector<SUnit> &sunits) override {
SUnits = &sunits;
NumNodesSolelyBlocking.resize(SUnits->size(), 0);
}
- void addNode(const SUnit *SU) {
+ void addNode(const SUnit *SU) override {
NumNodesSolelyBlocking.resize(SUnits->size(), 0);
}
- void updateNode(const SUnit *SU) {
+ void updateNode(const SUnit *SU) override {
}
- void releaseState() {
+ void releaseState() override {
SUnits = 0;
}
@@ -75,21 +75,21 @@ namespace llvm {
return NumNodesSolelyBlocking[NodeNum];
}
- bool empty() const { return Queue.empty(); }
+ bool empty() const override { return Queue.empty(); }
- virtual void push(SUnit *U);
+ void push(SUnit *U) override;
- virtual SUnit *pop();
+ SUnit *pop() override;
- virtual void remove(SUnit *SU);
+ void remove(SUnit *SU) override;
- virtual void dump(ScheduleDAG* DAG) const;
+ void dump(ScheduleDAG* DAG) const override;
// 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);
+ void scheduledNode(SUnit *Node) override;
private:
void AdjustPriorityOfUnscheduledPreds(SUnit *SU);
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index 26563a6..e0593f8 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -21,9 +21,9 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Metadata.h"
-#include "llvm/Support/DebugLoc.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
#include <utility>
namespace llvm {
@@ -44,32 +44,35 @@ typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
///
class LexicalScopes {
public:
- LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { }
- virtual ~LexicalScopes();
+ LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) {}
+ ~LexicalScopes();
- /// initialize - Scan machine function and constuct lexical scope nest.
- virtual void initialize(const MachineFunction &);
+ /// initialize - Scan machine function and constuct lexical scope nest, resets
+ /// the instance if necessary.
+ void initialize(const MachineFunction &);
/// releaseMemory - release memory.
- virtual void releaseMemory();
-
+ void reset();
+
/// empty - Return true if there is any lexical scope information available.
bool empty() { return CurrentFnLexicalScope == NULL; }
- /// isCurrentFunctionScope - Return true if given lexical scope represents
+ /// isCurrentFunctionScope - Return true if given lexical scope represents
/// current function.
- bool isCurrentFunctionScope(const LexicalScope *LS) {
+ bool isCurrentFunctionScope(const LexicalScope *LS) {
return LS == CurrentFnLexicalScope;
}
/// getCurrentFunctionScope - Return lexical scope for the current function.
- LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;}
+ 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);
+ 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.
@@ -104,7 +107,6 @@ public:
void dump();
private:
-
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
/// not available then create new lexical scope.
LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
@@ -123,8 +125,9 @@ private:
void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
DenseMap<const MachineInstr *, LexicalScope *> &M);
void constructScopeNest(LexicalScope *Scope);
- void assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
- DenseMap<const MachineInstr *, LexicalScope *> &M);
+ void
+ assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
+ DenseMap<const MachineInstr *, LexicalScope *> &M);
private:
const MachineFunction *MF;
@@ -133,10 +136,11 @@ private:
/// contained LexicalScope*s.
DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap;
- /// InlinedLexicalScopeMap - Tracks inlined function scopes in current function.
+ /// InlinedLexicalScopeMap - Tracks inlined function scopes in current
+ /// function.
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
- /// AbstractScopeMap - These scopes are not included LexicalScopeMap.
+ /// AbstractScopeMap - These scopes are not included LexicalScopeMap.
/// AbstractScopes owns its LexicalScope*s.
DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
@@ -153,26 +157,23 @@ private:
/// 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) {
+ : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), LastInsn(0),
+ FirstInsn(0), DFSIn(0), DFSOut(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; }
+ 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; }
SmallVectorImpl<LexicalScope *> &getChildren() { return Children; }
- SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
+ SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
/// addChild - Add a child scope.
void addChild(LexicalScope *S) { Children.push_back(S); }
@@ -189,7 +190,7 @@ public:
/// extendInsnRange - Extend the current instruction range covered by
/// this scope.
void extendInsnRange(const MachineInstr *MI) {
- assert (FirstInsn && "MI Range is not open!");
+ assert(FirstInsn && "MI Range is not open!");
LastInsn = MI;
if (Parent)
Parent->extendInsnRange(MI);
@@ -199,7 +200,7 @@ public:
/// 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!");
+ assert(LastInsn && "Last insn missing!");
Ranges.push_back(InsnRange(FirstInsn, LastInsn));
FirstInsn = NULL;
LastInsn = NULL;
@@ -219,28 +220,28 @@ public:
}
// 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; }
+ 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(unsigned Indent = 0) 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.
+ 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.
+ 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.
};
} // end llvm namespace
diff --git a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
index 722b0de..c3046da 100644
--- a/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
+++ b/include/llvm/CodeGen/LinkAllAsmWriterComponents.h
@@ -18,7 +18,6 @@
#include "llvm/CodeGen/GCs.h"
#include <cstdlib>
-#ifndef ANDROID_TARGET_BUILD
namespace {
struct ForceAsmWriterLinking {
ForceAsmWriterLinking() {
@@ -35,6 +34,5 @@ namespace {
}
} ForceAsmWriterLinking; // Force link by creating a global definition.
}
-#endif
#endif // LLVM_CODEGEN_LINKALLASMWRITERCOMPONENTS_H
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 3a9fef6..41d126a 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -173,7 +173,7 @@ namespace llvm {
}
bool operator<(const Segment &Other) const {
- return start < Other.start || (start == Other.start && end < Other.end);
+ return std::tie(start, end) < std::tie(Other.start, Other.end);
}
bool operator==(const Segment &Other) const {
return start == Other.start && end == Other.end;
@@ -552,8 +552,7 @@ namespace llvm {
bool operator<(const LiveInterval& other) const {
const SlotIndex &thisIndex = beginIndex();
const SlotIndex &otherIndex = other.beginIndex();
- return thisIndex < otherIndex ||
- (thisIndex == otherIndex && reg < other.reg);
+ return std::tie(thisIndex, reg) < std::tie(otherIndex, other.reg);
}
void print(raw_ostream &OS) const;
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index d8437f0..5492593 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -45,6 +45,7 @@ namespace llvm {
class TargetInstrInfo;
class TargetRegisterClass;
class VirtRegMap;
+ class MachineBlockFrequencyInfo;
class LiveIntervals : public MachineFunctionPass {
MachineFunction* MF;
@@ -100,7 +101,9 @@ namespace llvm {
virtual ~LiveIntervals();
// Calculate the spill weight to assign to a single instruction.
- static float getSpillWeight(bool isDef, bool isUse, BlockFrequency freq);
+ static float getSpillWeight(bool isDef, bool isUse,
+ const MachineBlockFrequencyInfo *MBFI,
+ const MachineInstr *Instr);
LiveInterval &getInterval(unsigned Reg) {
if (hasInterval(Reg))
@@ -252,14 +255,14 @@ namespace llvm {
VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory();
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void releaseMemory() override;
/// runOnMachineFunction - pass entry point
- virtual bool runOnMachineFunction(MachineFunction&);
+ bool runOnMachineFunction(MachineFunction&) override;
/// print - Implement the dump method.
- virtual void print(raw_ostream &O, const Module* = 0) const;
+ void print(raw_ostream &O, const Module* = 0) const override;
/// 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,
diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h
new file mode 100644
index 0000000..c93eaf5
--- /dev/null
+++ b/include/llvm/CodeGen/LivePhysRegs.h
@@ -0,0 +1,146 @@
+//===- llvm/CodeGen/LivePhysRegs.h - Live Physical Register 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 implements the LivePhysRegs utility for tracking liveness of
+// physical registers. This can be used for ad-hoc liveness tracking after
+// register allocation. You can start with the live-ins/live-outs at the
+// beginning/end of a block and update the information while walking the
+// instructions inside the block. This implementation tracks the liveness on a
+// sub-register granularity.
+//
+// We assume that the high bits of a physical super-register are not preserved
+// unless the instruction has an implicit-use operand reading the super-
+// register.
+//
+// X86 Example:
+// %YMM0<def> = ...
+// %XMM0<def> = ... (Kills %XMM0, all %XMM0s sub-registers, and %YMM0)
+//
+// %YMM0<def> = ...
+// %XMM0<def> = ..., %YMM0<imp-use> (%YMM0 and all its sub-registers are alive)
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVE_PHYS_REGS_H
+#define LLVM_CODEGEN_LIVE_PHYS_REGS_H
+
+#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+
+namespace llvm {
+
+class MachineInstr;
+
+/// \brief A set of live physical registers with functions to track liveness
+/// when walking backward/forward through a basic block.
+class LivePhysRegs {
+ const TargetRegisterInfo *TRI;
+ SparseSet<unsigned> LiveRegs;
+
+ LivePhysRegs(const LivePhysRegs&) LLVM_DELETED_FUNCTION;
+ LivePhysRegs &operator=(const LivePhysRegs&) LLVM_DELETED_FUNCTION;
+public:
+ /// \brief Constructs a new empty LivePhysRegs set.
+ LivePhysRegs() : TRI(0), LiveRegs() {}
+
+ /// \brief Constructs and initialize an empty LivePhysRegs set.
+ LivePhysRegs(const TargetRegisterInfo *TRI) : TRI(TRI) {
+ assert(TRI && "Invalid TargetRegisterInfo pointer.");
+ LiveRegs.setUniverse(TRI->getNumRegs());
+ }
+
+ /// \brief Clear and initialize the LivePhysRegs set.
+ void init(const TargetRegisterInfo *_TRI) {
+ assert(_TRI && "Invalid TargetRegisterInfo pointer.");
+ TRI = _TRI;
+ LiveRegs.clear();
+ LiveRegs.setUniverse(TRI->getNumRegs());
+ }
+
+ /// \brief Clears the LivePhysRegs set.
+ void clear() { LiveRegs.clear(); }
+
+ /// \brief Returns true if the set is empty.
+ bool empty() const { return LiveRegs.empty(); }
+
+ /// \brief Adds a physical register and all its sub-registers to the set.
+ void addReg(unsigned Reg) {
+ assert(TRI && "LivePhysRegs is not initialized.");
+ assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
+ for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
+ SubRegs.isValid(); ++SubRegs)
+ LiveRegs.insert(*SubRegs);
+ }
+
+ /// \brief Removes a physical register, all its sub-registers, and all its
+ /// super-registers from the set.
+ void removeReg(unsigned Reg) {
+ assert(TRI && "LivePhysRegs is not initialized.");
+ assert(Reg <= TRI->getNumRegs() && "Expected a physical register.");
+ for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
+ SubRegs.isValid(); ++SubRegs)
+ LiveRegs.erase(*SubRegs);
+ for (MCSuperRegIterator SuperRegs(Reg, TRI, /*IncludeSelf=*/false);
+ SuperRegs.isValid(); ++SuperRegs)
+ LiveRegs.erase(*SuperRegs);
+ }
+
+ /// \brief Removes physical registers clobbered by the regmask operand @p MO.
+ void removeRegsInMask(const MachineOperand &MO);
+
+ /// \brief Returns true if register @p Reg is contained in the set. This also
+ /// works if only the super register of @p Reg has been defined, because we
+ /// always add also all sub-registers to the set.
+ bool contains(unsigned Reg) const { return LiveRegs.count(Reg); }
+
+ /// \brief Simulates liveness when stepping backwards over an
+ /// instruction(bundle): Remove Defs, add uses. This is the recommended way of
+ /// calculating liveness.
+ void stepBackward(const MachineInstr &MI);
+
+ /// \brief Simulates liveness when stepping forward over an
+ /// instruction(bundle): Remove killed-uses, add defs. This is the not
+ /// recommended way, because it depends on accurate kill flags. If possible
+ /// use stepBackwards() instead of this function.
+ void stepForward(const MachineInstr &MI);
+
+ /// \brief Adds all live-in registers of basic block @p MBB.
+ void addLiveIns(const MachineBasicBlock *MBB) {
+ for (MachineBasicBlock::livein_iterator LI = MBB->livein_begin(),
+ LE = MBB->livein_end(); LI != LE; ++LI)
+ addReg(*LI);
+ }
+
+ /// \brief Adds all live-out registers of basic block @p MBB.
+ void addLiveOuts(const MachineBasicBlock *MBB) {
+ for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
+ SE = MBB->succ_end(); SI != SE; ++SI)
+ addLiveIns(*SI);
+ }
+
+ typedef SparseSet<unsigned>::const_iterator const_iterator;
+ const_iterator begin() const { return LiveRegs.begin(); }
+ const_iterator end() const { return LiveRegs.end(); }
+
+ /// \brief Prints the currently live registers to @p OS.
+ void print(raw_ostream &OS) const;
+
+ /// \brief Dumps the currently live registers to the debug output.
+ void dump() const;
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const LivePhysRegs& LR) {
+ LR.print(OS);
+ return OS;
+}
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_LIVE_PHYS_REGS_H
diff --git a/include/llvm/CodeGen/LiveRangeEdit.h b/include/llvm/CodeGen/LiveRangeEdit.h
index 7edf67c..4ce39e3 100644
--- a/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/include/llvm/CodeGen/LiveRangeEdit.h
@@ -99,7 +99,7 @@ private:
/// MachineRegisterInfo callback to notify when new virtual
/// registers are created.
- void MRI_NoteNewVirtualRegister(unsigned VReg);
+ void MRI_NoteNewVirtualRegister(unsigned VReg) override;
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
diff --git a/include/llvm/CodeGen/LiveRegMatrix.h b/include/llvm/CodeGen/LiveRegMatrix.h
index 7a3e9e8..28b819b 100644
--- a/include/llvm/CodeGen/LiveRegMatrix.h
+++ b/include/llvm/CodeGen/LiveRegMatrix.h
@@ -59,9 +59,9 @@ class LiveRegMatrix : public MachineFunctionPass {
BitVector RegMaskUsable;
// MachineFunctionPass boilerplate.
- virtual void getAnalysisUsage(AnalysisUsage&) const;
- virtual bool runOnMachineFunction(MachineFunction&);
- virtual void releaseMemory();
+ void getAnalysisUsage(AnalysisUsage&) const override;
+ bool runOnMachineFunction(MachineFunction&) override;
+ void releaseMemory() override;
public:
static char ID;
LiveRegMatrix();
diff --git a/include/llvm/CodeGen/LiveRegUnits.h b/include/llvm/CodeGen/LiveRegUnits.h
deleted file mode 100644
index 02b9c55..0000000
--- a/include/llvm/CodeGen/LiveRegUnits.h
+++ /dev/null
@@ -1,88 +0,0 @@
-//===-- llvm/CodeGen/LiveRegUnits.h - Live register unit 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 implements a Set of live register units. This can be used for ad
-// hoc liveness tracking after register allocation. You can start with the
-// live-ins/live-outs at the beginning/end of a block and update the information
-// while walking the instructions inside the block.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_LIVEREGUNITS_H
-#define LLVM_CODEGEN_LIVEREGUNITS_H
-
-#include "llvm/ADT/SparseSet.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include <cassert>
-
-namespace llvm {
-
-class MachineInstr;
-
-/// A set of live register units with functions to track liveness when walking
-/// backward/forward through a basic block.
-class LiveRegUnits {
- SparseSet<unsigned> LiveUnits;
-
- LiveRegUnits(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
- LiveRegUnits &operator=(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
-public:
- /// \brief Constructs a new empty LiveRegUnits set.
- LiveRegUnits() {}
-
- void init(const TargetRegisterInfo *TRI) {
- LiveUnits.clear();
- LiveUnits.setUniverse(TRI->getNumRegs());
- }
-
- void clear() { LiveUnits.clear(); }
-
- bool empty() const { return LiveUnits.empty(); }
-
- /// \brief Adds a register to the set.
- void addReg(unsigned Reg, const MCRegisterInfo &MCRI) {
- for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
- LiveUnits.insert(*RUnits);
- }
-
- /// \brief Removes a register from the set.
- void removeReg(unsigned Reg, const MCRegisterInfo &MCRI) {
- for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
- LiveUnits.erase(*RUnits);
- }
-
- /// \brief Removes registers clobbered by the regmask operand @p Op.
- void removeRegsInMask(const MachineOperand &Op, const MCRegisterInfo &MCRI);
-
- /// \brief Returns true if register @p Reg (or one of its super register) is
- /// contained in the set.
- bool contains(unsigned Reg, const MCRegisterInfo &MCRI) const {
- for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) {
- if (LiveUnits.count(*RUnits))
- return true;
- }
- return false;
- }
-
- /// \brief Simulates liveness when stepping backwards over an
- /// instruction(bundle): Remove Defs, add uses.
- void stepBackward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
-
- /// \brief Simulates liveness when stepping forward over an
- /// instruction(bundle): Remove killed-uses, add defs.
- void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
-
- /// \brief Adds all registers in the live-in list of block @p BB.
- void addLiveIns(const MachineBasicBlock *MBB, const MCRegisterInfo &MCRI);
-};
-
-} // namespace llvm
-
-#endif
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index 92c35f7..ac32a9c 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -85,14 +85,14 @@ namespace llvm {
VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory();
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void releaseMemory() override;
/// runOnMachineFunction - pass entry point
- virtual bool runOnMachineFunction(MachineFunction&);
+ bool runOnMachineFunction(MachineFunction&) override;
/// print - Implement the dump method.
- virtual void print(raw_ostream &O, const Module* = 0) const;
+ void print(raw_ostream &O, const Module* = 0) const override;
};
}
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
index dc735f7..a4a5fcc 100644
--- a/include/llvm/CodeGen/LiveVariables.h
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -177,7 +177,7 @@ private: // Intermediate data structures
void analyzePHINodes(const MachineFunction& Fn);
public:
- virtual bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &MF) override;
/// RegisterDefIsDead - Return true if the specified instruction defines the
/// specified register, but that definition is dead.
@@ -258,10 +258,10 @@ public:
(void)Removed;
return true;
}
-
- void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void releaseMemory() {
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ void releaseMemory() override {
VirtRegInfo.clear();
}
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
index 7717809..5e86e75 100644
--- a/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -363,6 +363,9 @@ public:
///
void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0);
+ /// Set successor weight of a given iterator.
+ void setSuccWeight(succ_iterator I, uint32_t weight);
+
/// removeSuccessor - Remove successor from the successors list of this
/// MachineBasicBlock. The Predecessors list of succ is automatically updated.
///
@@ -500,7 +503,7 @@ public:
///
/// If I points to a bundle of instructions, they are all erased.
iterator erase(iterator I) {
- return erase(I, llvm::next(I));
+ return erase(I, std::next(I));
}
/// Remove an instruction from the instruction list and delete it.
@@ -539,7 +542,7 @@ public:
void splice(iterator Where, MachineBasicBlock *Other, iterator From) {
// The range splice() doesn't allow noop moves, but this one does.
if (Where != From)
- splice(Where, Other, From, llvm::next(From));
+ splice(Where, Other, From, std::next(From));
}
/// Take a block of instructions from MBB 'Other' in the range [From, To),
@@ -608,6 +611,9 @@ public:
void dump() const;
void print(raw_ostream &OS, SlotIndexes* = 0) const;
+ // Printing method used by LoopInfo.
+ void printAsOperand(raw_ostream &OS, bool PrintType = true);
+
/// getNumber - MachineBasicBlocks are uniquely numbered at the function
/// level, unless they're not in a MachineFunction yet, in which case this
/// will return -1.
@@ -655,8 +661,6 @@ private:
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> {
@@ -746,11 +750,11 @@ public:
MachineInstrSpan(MachineBasicBlock::iterator I)
: MBB(*I->getParent()),
I(I),
- B(I == MBB.begin() ? MBB.end() : llvm::prior(I)),
- E(llvm::next(I)) {}
+ B(I == MBB.begin() ? MBB.end() : std::prev(I)),
+ E(std::next(I)) {}
MachineBasicBlock::iterator begin() {
- return B == MBB.end() ? MBB.begin() : llvm::next(B);
+ return B == MBB.end() ? MBB.begin() : std::next(B);
}
MachineBasicBlock::iterator end() { return E; }
bool empty() { return begin() == end(); }
diff --git a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index a9c7bf7..f3ef87c 100644
--- a/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -1,4 +1,4 @@
-//====----- MachineBlockFrequencyInfo.h - MachineBlock Frequency Analysis ----====//
+//====-- MachineBlockFrequencyInfo.h - MBB Frequency Analysis -*- C++ -*--====//
//
// The LLVM Compiler Infrastructure
//
@@ -28,9 +28,9 @@ class BlockFrequencyImpl;
/// MachineBlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
/// machine basic block frequencies.
class MachineBlockFrequencyInfo : public MachineFunctionPass {
-
- BlockFrequencyImpl<MachineBasicBlock, MachineFunction,
- MachineBranchProbabilityInfo> *MBFI;
+ typedef BlockFrequencyImpl<MachineBasicBlock, MachineFunction,
+ MachineBranchProbabilityInfo> ImplType;
+ std::unique_ptr<ImplType> MBFI;
public:
static char ID;
@@ -39,9 +39,11 @@ public:
~MachineBlockFrequencyInfo();
- void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ bool runOnMachineFunction(MachineFunction &F) override;
- bool runOnMachineFunction(MachineFunction &F);
+ void releaseMemory() override;
/// getblockFreq - Return block frequency. Return 0 if we don't have the
/// information. Please note that initial frequency is equal to 1024. It means
@@ -49,6 +51,21 @@ public:
/// the other block frequencies. We do this to avoid using of floating points.
///
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
+
+ const MachineFunction *getFunction() const;
+ void view() const;
+
+ // Print the block frequency Freq to OS using the current functions entry
+ // frequency to convert freq into a relative decimal form.
+ raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const;
+
+ // Convenience method that attempts to look up the frequency associated with
+ // BB and print it to OS.
+ raw_ostream &printBlockFreq(raw_ostream &OS,
+ const MachineBasicBlock *MBB) const;
+
+ uint64_t getEntryFreq() const;
+
};
}
diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
index c59948f..7ba7495 100644
--- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
+++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h
@@ -40,7 +40,7 @@ public:
initializeMachineBranchProbabilityInfoPass(Registry);
}
- void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
@@ -60,7 +60,8 @@ public:
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;
+ bool isEdgeHot(const MachineBasicBlock *Src,
+ const 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.
@@ -72,14 +73,15 @@ public:
// 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;
+ BranchProbability getEdgeProbability(const MachineBasicBlock *Src,
+ const 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;
+ raw_ostream &printEdgeProbability(raw_ostream &OS,
+ const MachineBasicBlock *Src,
+ const MachineBasicBlock *Dst) const;
};
}
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
index 9e41e6e..f729ced 100644
--- a/include/llvm/CodeGen/MachineCodeEmitter.h
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -17,8 +17,8 @@
#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
#define LLVM_CODEGEN_MACHINECODEEMITTER_H
+#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/DebugLoc.h"
#include <string>
namespace llvm {
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index e41d206..f1ae0bf 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -15,11 +15,11 @@
#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
-#include "llvm/Analysis/DominatorInternals.h"
-#include "llvm/Analysis/Dominators.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
namespace llvm {
@@ -48,7 +48,7 @@ public:
DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
@@ -66,7 +66,7 @@ public:
return DT->getRootNode();
}
- virtual bool runOnMachineFunction(MachineFunction &F);
+ bool runOnMachineFunction(MachineFunction &F) override;
inline bool dominates(const MachineDomTreeNode* A,
const MachineDomTreeNode* B) const {
@@ -166,9 +166,9 @@ public:
return DT->isReachableFromEntry(A);
}
- virtual void releaseMemory();
+ void releaseMemory() override;
- virtual void print(raw_ostream &OS, const Module*) const;
+ void print(raw_ostream &OS, const Module*) const override;
};
//===-------------------------------------
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index 022634d..1dedd74 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -101,11 +101,6 @@ class MachineFrameInfo {
// 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;
-
/// Alloca - If this stack object is originated from an Alloca instruction
/// this value saves the original IR allocation. Can be NULL.
const AllocaInst *Alloca;
@@ -115,9 +110,9 @@ class MachineFrameInfo {
bool PreAllocated;
StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
- bool isSS, bool NSP, const AllocaInst *Val)
+ bool isSS, const AllocaInst *Val)
: SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
- isSpillSlot(isSS), MayNeedSP(NSP), Alloca(Val), PreAllocated(false) {}
+ isSpillSlot(isSS), Alloca(Val), PreAllocated(false) {}
};
const TargetMachine &TM;
@@ -145,6 +140,14 @@ class MachineFrameInfo {
/// to builtin \@llvm.returnaddress.
bool ReturnAddressTaken;
+ /// HasStackMap - This boolean keeps track of whether there is a call
+ /// to builtin \@llvm.experimental.stackmap.
+ bool HasStackMap;
+
+ /// HasPatchPoint - This boolean keeps track of whether there is a call
+ /// to builtin \@llvm.experimental.patchpoint.
+ bool HasPatchPoint;
+
/// 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
@@ -223,6 +226,10 @@ class MachineFrameInfo {
/// Whether the "realign-stack" option is on.
bool RealignOption;
+ /// True if the function includes inline assembly that adjusts the stack
+ /// pointer.
+ bool HasInlineAsmWithSPAdjust;
+
const TargetFrameLowering *getFrameLowering() const;
public:
explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
@@ -231,6 +238,8 @@ public:
HasVarSizedObjects = false;
FrameAddressTaken = false;
ReturnAddressTaken = false;
+ HasStackMap = false;
+ HasPatchPoint = false;
AdjustsStack = false;
HasCalls = false;
StackProtectorIdx = -1;
@@ -240,6 +249,7 @@ public:
LocalFrameSize = 0;
LocalFrameMaxAlign = 0;
UseLocalStackAllocationBlock = false;
+ HasInlineAsmWithSPAdjust = false;
}
/// hasStackObjects - Return true if there are any stack objects in this
@@ -276,6 +286,18 @@ public:
bool isReturnAddressTaken() const { return ReturnAddressTaken; }
void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
+ /// hasStackMap - This method may be called any time after instruction
+ /// selection is complete to determine if there is a call to builtin
+ /// \@llvm.experimental.stackmap.
+ bool hasStackMap() const { return HasStackMap; }
+ void setHasStackMap(bool s = true) { HasStackMap = s; }
+
+ /// hasPatchPoint - This method may be called any time after instruction
+ /// selection is complete to determine if there is a call to builtin
+ /// \@llvm.experimental.patchpoint.
+ bool hasPatchPoint() const { return HasPatchPoint; }
+ void setHasPatchPoint(bool s = true) { HasPatchPoint = s; }
+
/// getObjectIndexBegin - Return the minimum frame object index.
///
int getObjectIndexBegin() const { return -NumFixedObjects; }
@@ -380,14 +402,6 @@ public:
return Objects[ObjectIdx+NumFixedObjects].Alloca;
}
- /// 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.
///
@@ -451,6 +465,10 @@ public:
bool hasCalls() const { return HasCalls; }
void setHasCalls(bool V) { HasCalls = V; }
+ /// Returns true if the function contains any stack-adjusting inline assembly.
+ bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
+ void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
+
/// 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
@@ -501,7 +519,7 @@ public:
/// a nonnegative identifier to represent it.
///
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
- bool MayNeedSP = false, const AllocaInst *Alloca = 0);
+ const AllocaInst *Alloca = 0);
/// CreateSpillStackObject - Create a new statically sized stack object that
/// represents a spill slot, returning a nonnegative identifier to represent
@@ -521,7 +539,7 @@ public:
/// variable sized object is created, whether or not the index returned is
/// actually used.
///
- int CreateVariableSizedObject(unsigned Alignment);
+ int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca);
/// getCalleeSavedInfo - Returns a reference to call saved info vector for the
/// current function.
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index c886e25..652d63d 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -20,9 +20,9 @@
#include "llvm/ADT/ilist.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ArrayRecycler.h"
-#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/Recycler.h"
namespace llvm {
@@ -131,8 +131,8 @@ class MachineFunction {
/// about the control flow of such functions.
bool ExposesReturnsTwice;
- /// True if the function includes MS-style inline assembly.
- bool HasMSInlineAsm;
+ /// True if the function includes any inline assembly.
+ bool HasInlineAsm;
MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
@@ -218,15 +218,14 @@ public:
ExposesReturnsTwice = B;
}
- /// Returns true if the function contains any MS-style inline assembly.
- bool hasMSInlineAsm() const {
- return HasMSInlineAsm;
+ /// Returns true if the function contains any inline assembly.
+ bool hasInlineAsm() const {
+ return HasInlineAsm;
}
- /// Set a flag that indicates that the function contains MS-style inline
- /// assembly.
- void setHasMSInlineAsm(bool B) {
- HasMSInlineAsm = B;
+ /// Set a flag that indicates that the function contains inline assembly.
+ void setHasInlineAsm(bool B) {
+ HasInlineAsm = B;
}
/// getInfo - Keep track of various per-function pieces of information for
@@ -427,6 +426,15 @@ public:
OperandRecycler.deallocate(Cap, Array);
}
+ /// \brief Allocate and initialize a register mask with @p NumRegister bits.
+ uint32_t *allocateRegisterMask(unsigned NumRegister) {
+ unsigned Size = (NumRegister + 31) / 32;
+ uint32_t *Mask = Allocator.Allocate<uint32_t>(Size);
+ for (unsigned i = 0; i != Size; ++i)
+ Mask[i] = 0;
+ return Mask;
+ }
+
/// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
/// pointers. This array is owned by the MachineFunction.
MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
index 112f07e..36f1c66 100644
--- a/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -34,16 +34,16 @@ public:
~MachineFunctionAnalysis();
MachineFunction &getMF() const { return *MF; }
-
- virtual const char* getPassName() const {
+
+ const char* getPassName() const override {
return "Machine Function Analysis";
}
private:
- virtual bool doInitialization(Module &M);
- virtual bool runOnFunction(Function &F);
- virtual void releaseMemory();
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ bool doInitialization(Module &M) override;
+ bool runOnFunction(Function &F) override;
+ void releaseMemory() override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
index 04881e5..50a1f6e 100644
--- a/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -44,14 +44,14 @@ protected:
/// For MachineFunctionPasses, calling AU.preservesCFG() indicates that
/// the pass does not modify the MachineBasicBlock CFG.
///
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
private:
/// createPrinterPass - Get a machine function printer pass.
- virtual Pass *createPrinterPass(raw_ostream &O,
- const std::string &Banner) const;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
};
} // End llvm namespace
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index cccab81..f5dc75e 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -22,13 +22,13 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/ArrayRecycler.h"
-#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetOpcodes.h"
-#include <vector>
namespace llvm {
@@ -287,11 +287,25 @@ public:
const_mop_iterator operands_begin() const { return Operands; }
const_mop_iterator operands_end() const { return Operands + NumOperands; }
+ inline iterator_range<mop_iterator> operands() {
+ return iterator_range<mop_iterator>(operands_begin(), operands_end());
+ }
+ inline iterator_range<const_mop_iterator> operands() const {
+ return iterator_range<const_mop_iterator>(operands_begin(), 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; }
+ inline iterator_range<mmo_iterator> memoperands() {
+ return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end());
+ }
+ inline iterator_range<mmo_iterator> memoperands() const {
+ return iterator_range<mmo_iterator>(memoperands_begin(), memoperands_end());
+ }
+
/// hasOneMemOperand - Return true if this instruction has exactly one
/// MachineMemOperand.
bool hasOneMemOperand() const {
@@ -623,19 +637,19 @@ public:
/// bundle remain bundled.
void eraseFromBundle();
+ bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
+ bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
+
/// 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 isLabel() const { return isEHLabel() || isGCLabel(); }
+ bool isCFIInstruction() const {
+ return getOpcode() == TargetOpcode::CFI_INSTRUCTION;
}
- bool isPrologLabel() const {
- return getOpcode() == TargetOpcode::PROLOG_LABEL;
- }
- bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
- bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
+ // True if the instruction represents a position in the function.
+ bool isPosition() const { return isLabel() || isCFIInstruction(); }
+
bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; }
/// A DBG_VALUE is indirect iff the first operand is a register and
/// the second operand is an immediate.
@@ -701,7 +715,7 @@ public:
// Pseudo-instructions that don't produce any real output.
case TargetOpcode::IMPLICIT_DEF:
case TargetOpcode::KILL:
- case TargetOpcode::PROLOG_LABEL:
+ case TargetOpcode::CFI_INSTRUCTION:
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
case TargetOpcode::DBG_VALUE:
@@ -830,6 +844,37 @@ public:
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI) const;
+ /// \brief Applies the constraints (def/use) implied by this MI on \p Reg to
+ /// the given \p CurRC.
+ /// If \p ExploreBundle is set and MI is part of a bundle, all the
+ /// instructions inside the bundle will be taken into account. In other words,
+ /// this method accumulates all the constrains of the operand of this MI and
+ /// the related bundle if MI is a bundle or inside a bundle.
+ ///
+ /// Returns the register class that statisfies both \p CurRC and the
+ /// constraints set by MI. Returns NULL if such a register class does not
+ /// exist.
+ ///
+ /// \pre CurRC must not be NULL.
+ const TargetRegisterClass *getRegClassConstraintEffectForVReg(
+ unsigned Reg, const TargetRegisterClass *CurRC,
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+ bool ExploreBundle = false) const;
+
+ /// \brief Applies the constraints (def/use) implied by the \p OpIdx operand
+ /// to the given \p CurRC.
+ ///
+ /// Returns the register class that statisfies both \p CurRC and the
+ /// constraints set by \p OpIdx MI. Returns NULL if such a register class
+ /// does not exist.
+ ///
+ /// \pre CurRC must not be NULL.
+ /// \pre The operand at \p OpIdx must be a register.
+ const TargetRegisterClass *
+ getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
+ const TargetInstrInfo *TII,
+ const TargetRegisterInfo *TRI) const;
+
/// tieOperands - Add a tie between the register operands at DefIdx and
/// UseIdx. The tie will cause the register allocator to ensure that the two
/// operands are assigned the same physical register.
@@ -1038,6 +1083,13 @@ private:
/// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a
/// bundle.
bool hasPropertyInBundle(unsigned Mask, QueryType Type) const;
+
+ /// \brief Implements the logic of getRegClassConstraintEffectForVReg for the
+ /// this MI and the given operand index \p OpIdx.
+ /// If the related operand does not constrained Reg, this returns CurRC.
+ const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
+ unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC,
+ const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
};
/// MachineInstrExpressionTrait - Special DenseMapInfo traits to compare
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index df01371..d7eb706 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -172,7 +172,12 @@ public:
MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
return *this;
}
-
+
+ const MachineInstrBuilder &addCFIIndex(unsigned CFIIndex) const {
+ MI->addOperand(*MF, MachineOperand::CreateCFIIndex(CFIIndex));
+ return *this;
+ }
+
const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym));
return *this;
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index b058ecb..4fbd46b 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -31,6 +31,7 @@
#define LLVM_CODEGEN_MACHINELOOPINFO_H
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
@@ -119,11 +120,11 @@ public:
/// runOnFunction - Calculate the natural loop information.
///
- virtual bool runOnMachineFunction(MachineFunction &F);
+ bool runOnMachineFunction(MachineFunction &F) override;
- virtual void releaseMemory() { LI.releaseMemory(); }
+ void releaseMemory() override { LI.releaseMemory(); }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
/// 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
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index 00a55b5..f01b8eb 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -134,6 +134,8 @@ public:
/// number.
int64_t getOffset() const { return PtrInfo.Offset; }
+ unsigned getAddrSpace() const { return PtrInfo.getAddrSpace(); }
+
/// getSize - Return the size in bytes of the memory reference.
uint64_t getSize() const { return Size; }
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 460c08c..28f4544 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -35,14 +35,14 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
@@ -168,10 +168,13 @@ class MachineModuleInfo : public ImmutablePass {
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;
+ struct VariableDbgInfo {
+ TrackingVH<MDNode> Var;
+ unsigned Slot;
+ DebugLoc Loc;
+ };
+ typedef SmallVector<VariableDbgInfo, 4> VariableDbgInfoMapTy;
+ VariableDbgInfoMapTy VariableDbgInfos;
MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL.
// Real constructor.
@@ -180,8 +183,8 @@ public:
~MachineModuleInfo();
// Initialization and Finalization
- virtual bool doInitialization(Module &);
- virtual bool doFinalization(Module &);
+ bool doInitialization(Module &) override;
+ bool doFinalization(Module &) override;
/// EndFunction - Discard function meta information.
///
@@ -238,8 +241,10 @@ public:
return FrameInstructions;
}
- void addFrameInst(const MCCFIInstruction &Inst) {
+ unsigned LLVM_ATTRIBUTE_UNUSED_RESULT
+ addFrameInst(const MCCFIInstruction &Inst) {
FrameInstructions.push_back(Inst);
+ return FrameInstructions.size() - 1;
}
/// getCompactUnwindEncoding - Returns the compact unwind encoding for a
@@ -399,10 +404,11 @@ public:
/// 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)));
+ VariableDbgInfo Info = { N, Slot, Loc };
+ VariableDbgInfos.push_back(std::move(Info));
}
- VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfo; }
+ VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; }
}; // End class MachineModuleInfo
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 40f3580..57bdb4c 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -43,21 +43,23 @@ class MCSymbol;
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_TargetIndex, ///< Target-dependent index+offset operand.
- 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)
+ 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_TargetIndex, ///< Target-dependent index+offset operand.
+ 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_RegisterLiveOut, ///< Mask of live-out registers.
+ MO_Metadata, ///< Metadata reference (for debug info)
+ MO_MCSymbol, ///< MCSymbol reference (for debug/eh info)
+ MO_CFIIndex ///< MCCFIInstruction index.
};
private:
@@ -149,13 +151,14 @@ private:
/// 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
+ 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 and MO_RegisterLiveOut.
+ const MDNode *MD; // For MO_Metadata.
+ MCSymbol *Sym; // For MO_MCSymbol.
+ unsigned CFIIndex; // For MO_CFI.
struct { // For MO_Register.
// Register number is in SmallContents.RegNo.
@@ -246,10 +249,12 @@ public:
bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
/// isRegMask - Tests if this is a MO_RegisterMask operand.
bool isRegMask() const { return OpKind == MO_RegisterMask; }
+ /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand.
+ bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; }
/// isMetadata - Tests if this is a MO_Metadata operand.
bool isMetadata() const { return OpKind == MO_Metadata; }
bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
-
+ bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
//===--------------------------------------------------------------------===//
// Accessors for Register Operands
@@ -440,6 +445,11 @@ public:
return Contents.Sym;
}
+ unsigned getCFIIndex() const {
+ assert(isCFIIndex() && "Wrong MachineOperand accessor");
+ return Contents.CFIIndex;
+ }
+
/// getOffset - Return the offset from the symbol in this operand. This always
/// returns 0 for ExternalSymbol operands.
int64_t getOffset() const {
@@ -476,6 +486,12 @@ public:
return Contents.RegMask;
}
+ /// getRegLiveOut - Returns a bit mask of live-out registers.
+ const uint32_t *getRegLiveOut() const {
+ assert(isRegLiveOut() && "Wrong MachineOperand accessor");
+ return Contents.RegMask;
+ }
+
const MDNode *getMetadata() const {
assert(isMetadata() && "Wrong MachineOperand accessor");
return Contents.MD;
@@ -659,6 +675,12 @@ public:
Op.Contents.RegMask = Mask;
return Op;
}
+ static MachineOperand CreateRegLiveOut(const uint32_t *Mask) {
+ assert(Mask && "Missing live-out register mask");
+ MachineOperand Op(MachineOperand::MO_RegisterLiveOut);
+ Op.Contents.RegMask = Mask;
+ return Op;
+ }
static MachineOperand CreateMetadata(const MDNode *Meta) {
MachineOperand Op(MachineOperand::MO_Metadata);
Op.Contents.MD = Meta;
@@ -671,6 +693,12 @@ public:
return Op;
}
+ static MachineOperand CreateCFIIndex(unsigned CFIIndex) {
+ MachineOperand Op(MachineOperand::MO_CFIIndex);
+ Op.Contents.CFIIndex = CFIIndex;
+ return Op;
+ }
+
friend class MachineInstr;
friend class MachineRegisterInfo;
private:
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
index 90ee7f4..cd212ab 100644
--- a/include/llvm/CodeGen/MachinePassRegistry.h
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -142,12 +142,10 @@ public:
// Implement the MachinePassRegistryListener callbacks.
//
- virtual void NotifyAdd(const char *N,
- MachinePassCtor C,
- const char *D) {
+ void NotifyAdd(const char *N, MachinePassCtor C, const char *D) override {
this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
}
- virtual void NotifyRemove(const char *N) {
+ void NotifyRemove(const char *N) override {
this->removeLiteralOption(N);
}
};
diff --git a/include/llvm/CodeGen/MachinePostDominators.h b/include/llvm/CodeGen/MachinePostDominators.h
index ca09aef..a6f9f3d 100644
--- a/include/llvm/CodeGen/MachinePostDominators.h
+++ b/include/llvm/CodeGen/MachinePostDominators.h
@@ -15,7 +15,6 @@
#ifndef LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H
#define LLVM_CODEGEN_MACHINEPOSTDOMINATORS_H
-#include "llvm/Analysis/Dominators.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -78,9 +77,9 @@ public:
return DT->findNearestCommonDominator(A, B);
}
- virtual bool runOnMachineFunction(MachineFunction &MF);
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
- virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const;
+ bool runOnMachineFunction(MachineFunction &MF) override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ void print(llvm::raw_ostream &OS, const Module *M = 0) const override;
};
} //end of namespace llvm
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 58ca907..2285130 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
@@ -200,32 +201,118 @@ public:
/// 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>
+ template<bool Uses, bool Defs, bool SkipDebug,
+ bool ByOperand, bool ByInstr, bool ByBundle>
class defusechain_iterator;
+ template<bool Uses, bool Defs, bool SkipDebug,
+ bool ByOperand, bool ByInstr, bool ByBundle>
+ class defusechain_instr_iterator;
// Make it a friend so it can access getNextOperandForReg().
- template<bool, bool, bool> friend class defusechain_iterator;
+ template<bool, bool, bool, bool, bool, bool>
+ friend class defusechain_iterator;
+ template<bool, bool, bool, bool, bool, bool>
+ friend class defusechain_instr_iterator;
+
+
/// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified
/// register.
- typedef defusechain_iterator<true,true,false> reg_iterator;
+ typedef defusechain_iterator<true,true,false,true,false,false>
+ reg_iterator;
reg_iterator reg_begin(unsigned RegNo) const {
return reg_iterator(getRegUseDefListHead(RegNo));
}
static reg_iterator reg_end() { return reg_iterator(0); }
+ inline iterator_range<reg_iterator> reg_operands(unsigned Reg) const {
+ return iterator_range<reg_iterator>(reg_begin(Reg), reg_end());
+ }
+
+ /// reg_instr_iterator/reg_instr_begin/reg_instr_end - Walk all defs and uses
+ /// of the specified register, stepping by MachineInstr.
+ typedef defusechain_instr_iterator<true,true,false,false,true,false>
+ reg_instr_iterator;
+ reg_instr_iterator reg_instr_begin(unsigned RegNo) const {
+ return reg_instr_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_instr_iterator reg_instr_end() { return reg_instr_iterator(0); }
+
+ inline iterator_range<reg_instr_iterator>
+ reg_instructions(unsigned Reg) const {
+ return iterator_range<reg_instr_iterator>(reg_instr_begin(Reg),
+ reg_instr_end());
+ }
+
+ /// reg_bundle_iterator/reg_bundle_begin/reg_bundle_end - Walk all defs and uses
+ /// of the specified register, stepping by bundle.
+ typedef defusechain_instr_iterator<true,true,false,false,false,true>
+ reg_bundle_iterator;
+ reg_bundle_iterator reg_bundle_begin(unsigned RegNo) const {
+ return reg_bundle_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_bundle_iterator reg_bundle_end() { return reg_bundle_iterator(0); }
+
+ inline iterator_range<reg_bundle_iterator> reg_bundles(unsigned Reg) const {
+ return iterator_range<reg_bundle_iterator>(reg_bundle_begin(Reg),
+ reg_bundle_end());
+ }
+
/// 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;
+ typedef defusechain_iterator<true,true,true,true,false,false>
+ 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); }
+ inline iterator_range<reg_nodbg_iterator>
+ reg_nodbg_operands(unsigned Reg) const {
+ return iterator_range<reg_nodbg_iterator>(reg_nodbg_begin(Reg),
+ reg_nodbg_end());
+ }
+
+ /// reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk
+ /// all defs and uses of the specified register, stepping by MachineInstr,
+ /// skipping those marked as Debug.
+ typedef defusechain_instr_iterator<true,true,true,false,true,false>
+ reg_instr_nodbg_iterator;
+ reg_instr_nodbg_iterator reg_instr_nodbg_begin(unsigned RegNo) const {
+ return reg_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_instr_nodbg_iterator reg_instr_nodbg_end() {
+ return reg_instr_nodbg_iterator(0);
+ }
+
+ inline iterator_range<reg_instr_nodbg_iterator>
+ reg_nodbg_instructions(unsigned Reg) const {
+ return iterator_range<reg_instr_nodbg_iterator>(reg_instr_nodbg_begin(Reg),
+ reg_instr_nodbg_end());
+ }
+
+ /// reg_bundle_nodbg_iterator/reg_bundle_nodbg_begin/reg_bundle_nodbg_end - Walk
+ /// all defs and uses of the specified register, stepping by bundle,
+ /// skipping those marked as Debug.
+ typedef defusechain_instr_iterator<true,true,true,false,false,true>
+ reg_bundle_nodbg_iterator;
+ reg_bundle_nodbg_iterator reg_bundle_nodbg_begin(unsigned RegNo) const {
+ return reg_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static reg_bundle_nodbg_iterator reg_bundle_nodbg_end() {
+ return reg_bundle_nodbg_iterator(0);
+ }
+
+ inline iterator_range<reg_bundle_nodbg_iterator>
+ reg_nodbg_bundles(unsigned Reg) const {
+ return iterator_range<reg_bundle_nodbg_iterator>(reg_bundle_nodbg_begin(Reg),
+ reg_bundle_nodbg_end());
+ }
+
/// reg_nodbg_empty - Return true if the only instructions using or defining
/// Reg are Debug instructions.
bool reg_nodbg_empty(unsigned RegNo) const {
@@ -233,12 +320,46 @@ public:
}
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
- typedef defusechain_iterator<false,true,false> def_iterator;
+ typedef defusechain_iterator<false,true,false,true,false,false>
+ def_iterator;
def_iterator def_begin(unsigned RegNo) const {
return def_iterator(getRegUseDefListHead(RegNo));
}
static def_iterator def_end() { return def_iterator(0); }
+ inline iterator_range<def_iterator> def_operands(unsigned Reg) const {
+ return iterator_range<def_iterator>(def_begin(Reg), def_end());
+ }
+
+ /// def_instr_iterator/def_instr_begin/def_instr_end - Walk all defs of the
+ /// specified register, stepping by MachineInst.
+ typedef defusechain_instr_iterator<false,true,false,false,true,false>
+ def_instr_iterator;
+ def_instr_iterator def_instr_begin(unsigned RegNo) const {
+ return def_instr_iterator(getRegUseDefListHead(RegNo));
+ }
+ static def_instr_iterator def_instr_end() { return def_instr_iterator(0); }
+
+ inline iterator_range<def_instr_iterator>
+ def_instructions(unsigned Reg) const {
+ return iterator_range<def_instr_iterator>(def_instr_begin(Reg),
+ def_instr_end());
+ }
+
+ /// def_bundle_iterator/def_bundle_begin/def_bundle_end - Walk all defs of the
+ /// specified register, stepping by bundle.
+ typedef defusechain_instr_iterator<false,true,false,false,false,true>
+ def_bundle_iterator;
+ def_bundle_iterator def_bundle_begin(unsigned RegNo) const {
+ return def_bundle_iterator(getRegUseDefListHead(RegNo));
+ }
+ static def_bundle_iterator def_bundle_end() { return def_bundle_iterator(0); }
+
+ inline iterator_range<def_bundle_iterator> def_bundles(unsigned Reg) const {
+ return iterator_range<def_bundle_iterator>(def_bundle_begin(Reg),
+ def_bundle_end());
+ }
+
/// 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(); }
@@ -253,12 +374,46 @@ public:
}
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
- typedef defusechain_iterator<true,false,false> use_iterator;
+ typedef defusechain_iterator<true,false,false,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); }
+ inline iterator_range<use_iterator> use_operands(unsigned Reg) const {
+ return iterator_range<use_iterator>(use_begin(Reg), use_end());
+ }
+
+ /// use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the
+ /// specified register, stepping by MachineInstr.
+ typedef defusechain_instr_iterator<true,false,false,false,true,false>
+ use_instr_iterator;
+ use_instr_iterator use_instr_begin(unsigned RegNo) const {
+ return use_instr_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_instr_iterator use_instr_end() { return use_instr_iterator(0); }
+
+ inline iterator_range<use_instr_iterator>
+ use_instructions(unsigned Reg) const {
+ return iterator_range<use_instr_iterator>(use_instr_begin(Reg),
+ use_instr_end());
+ }
+
+ /// use_bundle_iterator/use_bundle_begin/use_bundle_end - Walk all uses of the
+ /// specified register, stepping by bundle.
+ typedef defusechain_instr_iterator<true,false,false,false,false,true>
+ use_bundle_iterator;
+ use_bundle_iterator use_bundle_begin(unsigned RegNo) const {
+ return use_bundle_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_bundle_iterator use_bundle_end() { return use_bundle_iterator(0); }
+
+ inline iterator_range<use_bundle_iterator> use_bundles(unsigned Reg) const {
+ return iterator_range<use_bundle_iterator>(use_bundle_begin(Reg),
+ use_bundle_end());
+ }
+
/// 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(); }
@@ -274,12 +429,55 @@ public:
/// 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;
+ typedef defusechain_iterator<true,false,true,true,false,false>
+ 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); }
+ inline iterator_range<use_nodbg_iterator>
+ use_nodbg_operands(unsigned Reg) const {
+ return iterator_range<use_nodbg_iterator>(use_nodbg_begin(Reg),
+ use_nodbg_end());
+ }
+
+ /// use_instr_nodbg_iterator/use_instr_nodbg_begin/use_instr_nodbg_end - Walk
+ /// all uses of the specified register, stepping by MachineInstr, skipping
+ /// those marked as Debug.
+ typedef defusechain_instr_iterator<true,false,true,false,true,false>
+ use_instr_nodbg_iterator;
+ use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const {
+ return use_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_instr_nodbg_iterator use_instr_nodbg_end() {
+ return use_instr_nodbg_iterator(0);
+ }
+
+ inline iterator_range<use_instr_nodbg_iterator>
+ use_nodbg_instructions(unsigned Reg) const {
+ return iterator_range<use_instr_nodbg_iterator>(use_instr_nodbg_begin(Reg),
+ use_instr_nodbg_end());
+ }
+
+ /// use_bundle_nodbg_iterator/use_bundle_nodbg_begin/use_bundle_nodbg_end - Walk
+ /// all uses of the specified register, stepping by bundle, skipping
+ /// those marked as Debug.
+ typedef defusechain_instr_iterator<true,false,true,false,false,true>
+ use_bundle_nodbg_iterator;
+ use_bundle_nodbg_iterator use_bundle_nodbg_begin(unsigned RegNo) const {
+ return use_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
+ }
+ static use_bundle_nodbg_iterator use_bundle_nodbg_end() {
+ return use_bundle_nodbg_iterator(0);
+ }
+
+ inline iterator_range<use_bundle_nodbg_iterator>
+ use_nodbg_bundles(unsigned Reg) const {
+ return iterator_range<use_bundle_nodbg_iterator>(use_bundle_nodbg_begin(Reg),
+ use_bundle_nodbg_end());
+ }
+
/// use_nodbg_empty - Return true if there are no non-Debug instructions
/// using the specified register.
bool use_nodbg_empty(unsigned RegNo) const {
@@ -401,6 +599,10 @@ public:
return Hint.first ? 0 : Hint.second;
}
+ /// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
+ /// specified register as undefined which causes the DBG_VALUE to be
+ /// deleted during LiveDebugVariables analysis.
+ void markUsesInDebugValueAsUndef(unsigned Reg) const;
//===--------------------------------------------------------------------===//
// Physical Register Use Info
@@ -552,7 +754,8 @@ public:
/// 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>
+ template<bool ReturnUses, bool ReturnDefs, bool SkipDebug,
+ bool ByOperand, bool ByInstr, bool ByBundle>
class defusechain_iterator
: public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
MachineOperand *Op;
@@ -563,10 +766,30 @@ public:
if ((!ReturnUses && op->isUse()) ||
(!ReturnDefs && op->isDef()) ||
(SkipDebug && op->isDebug()))
- ++*this;
+ advance();
}
}
friend class MachineRegisterInfo;
+
+ void advance() {
+ assert(Op && "Cannot increment end iterator!");
+ Op = getNextOperandForReg(Op);
+
+ // All defs come before the uses, so stop def_iterator early.
+ if (!ReturnUses) {
+ if (Op) {
+ if (Op->isUse())
+ Op = 0;
+ else
+ assert(!Op->isDebug() && "Can't have debug defs");
+ }
+ } else {
+ // If this is an operand we don't care about, skip it.
+ while (Op && ((!ReturnDefs && Op->isDef()) ||
+ (SkipDebug && Op->isDebug())))
+ Op = getNextOperandForReg(Op);
+ }
+ }
public:
typedef std::iterator<std::forward_iterator_tag,
MachineInstr, ptrdiff_t>::reference reference;
@@ -589,6 +812,70 @@ public:
// Iterator traversal: forward iteration only
defusechain_iterator &operator++() { // Preincrement
assert(Op && "Cannot increment end iterator!");
+ if (ByOperand)
+ advance();
+ else if (ByInstr) {
+ MachineInstr *P = Op->getParent();
+ do {
+ advance();
+ } while (Op && Op->getParent() == P);
+ } else if (ByBundle) {
+ MachineInstr *P = getBundleStart(Op->getParent());
+ do {
+ advance();
+ } while (Op && getBundleStart(Op->getParent()) == P);
+ }
+
+ return *this;
+ }
+ defusechain_iterator operator++(int) { // Postincrement
+ defusechain_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ /// 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.
+ MachineOperand &operator*() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return *Op;
+ }
+
+ MachineOperand *operator->() const {
+ assert(Op && "Cannot dereference end iterator!");
+ return Op;
+ }
+ };
+
+ /// 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,
+ bool ByOperand, bool ByInstr, bool ByBundle>
+ class defusechain_instr_iterator
+ : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
+ MachineOperand *Op;
+ explicit defusechain_instr_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()))
+ advance();
+ }
+ }
+ friend class MachineRegisterInfo;
+
+ void advance() {
+ assert(Op && "Cannot increment end iterator!");
Op = getNextOperandForReg(Op);
// All defs come before the uses, so stop def_iterator early.
@@ -605,52 +892,59 @@ public:
(SkipDebug && Op->isDebug())))
Op = getNextOperandForReg(Op);
}
+ }
+ 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;
- return *this;
+ defusechain_instr_iterator(const defusechain_instr_iterator &I) : Op(I.Op){}
+ defusechain_instr_iterator() : Op(0) {}
+
+ bool operator==(const defusechain_instr_iterator &x) const {
+ return Op == x.Op;
}
- defusechain_iterator operator++(int) { // Postincrement
- defusechain_iterator tmp = *this; ++*this; return tmp;
+ bool operator!=(const defusechain_instr_iterator &x) const {
+ return !operator==(x);
}
- /// 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;
- }
+ /// atEnd - return true if this iterator is equal to reg_end() on the value.
+ bool atEnd() const { return Op == 0; }
- MachineInstr *skipBundle() {
- if (!Op) return 0;
- MachineInstr *MI = getBundleStart(Op->getParent());
- do ++*this;
- while (Op && getBundleStart(Op->getParent()) == MI);
- return MI;
- }
+ // Iterator traversal: forward iteration only
+ defusechain_instr_iterator &operator++() { // Preincrement
+ assert(Op && "Cannot increment end iterator!");
+ if (ByOperand)
+ advance();
+ else if (ByInstr) {
+ MachineInstr *P = Op->getParent();
+ do {
+ advance();
+ } while (Op && Op->getParent() == P);
+ } else if (ByBundle) {
+ MachineInstr *P = getBundleStart(Op->getParent());
+ do {
+ advance();
+ } while (Op && getBundleStart(Op->getParent()) == P);
+ }
- MachineOperand &getOperand() const {
- assert(Op && "Cannot dereference end iterator!");
- return *Op;
+ return *this;
}
-
- /// 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);
+ defusechain_instr_iterator operator++(int) { // Postincrement
+ defusechain_instr_iterator tmp = *this; ++*this; return tmp;
}
// Retrieve a reference to the current operand.
MachineInstr &operator*() const {
assert(Op && "Cannot dereference end iterator!");
+ if (ByBundle) return *(getBundleStart(Op->getParent()));
return *Op->getParent();
}
MachineInstr *operator->() const {
assert(Op && "Cannot dereference end iterator!");
+ if (ByBundle) return getBundleStart(Op->getParent());
return Op->getParent();
}
};
diff --git a/include/llvm/CodeGen/MachineSSAUpdater.h b/include/llvm/CodeGen/MachineSSAUpdater.h
index edf93d1..8fc367e 100644
--- a/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H
#define LLVM_CODEGEN_MACHINESSAUPDATER_H
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -26,7 +27,6 @@ namespace llvm {
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
@@ -105,7 +105,6 @@ public:
void RewriteUse(MachineOperand &U);
private:
- void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
void operator=(const MachineSSAUpdater&) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 7782895..c54300c 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -23,7 +23,7 @@
// return new CustomMachineScheduler(C);
// }
//
-// The default scheduler, ScheduleDAGMI, builds the DAG and drives list
+// The default scheduler, ScheduleDAGMILive, builds the DAG and drives list
// scheduling while updating the instruction stream, register pressure, and live
// intervals. Most targets don't need to override the DAG builder and list
// schedulier, but subtargets that require custom scheduling heuristics may
@@ -93,6 +93,7 @@ class MachineLoopInfo;
class RegisterClassInfo;
class ScheduleDAGInstrs;
class SchedDFSResult;
+class ScheduleHazardRecognizer;
/// MachineSchedContext provides enough context from the MachineScheduler pass
/// for the target to instantiate a scheduler.
@@ -154,8 +155,8 @@ struct MachineSchedPolicy {
bool OnlyTopDown;
bool OnlyBottomUp;
- MachineSchedPolicy():
- ShouldTrackPressure(false), OnlyTopDown(false), OnlyBottomUp(false) {}
+ MachineSchedPolicy(): ShouldTrackPressure(false), OnlyTopDown(false),
+ OnlyBottomUp(false) {}
};
/// MachineSchedStrategy - Interface to the scheduling algorithm used by
@@ -204,63 +205,6 @@ public:
virtual void releaseBottomNode(SUnit *SU) = 0;
};
-/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
-/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
-/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
-///
-/// This is a convenience class that may be used by implementations of
-/// MachineSchedStrategy.
-class ReadyQueue {
- unsigned ID;
- std::string Name;
- std::vector<SUnit*> Queue;
-
-public:
- ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
-
- unsigned getID() const { return ID; }
-
- StringRef getName() const { return Name; }
-
- // SU is in this queue if it's NodeQueueID is a superset of this ID.
- bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
-
- bool empty() const { return Queue.empty(); }
-
- void clear() { Queue.clear(); }
-
- unsigned size() const { return Queue.size(); }
-
- typedef std::vector<SUnit*>::iterator iterator;
-
- iterator begin() { return Queue.begin(); }
-
- iterator end() { return Queue.end(); }
-
- ArrayRef<SUnit*> elements() { return Queue; }
-
- iterator find(SUnit *SU) {
- return std::find(Queue.begin(), Queue.end(), SU);
- }
-
- void push(SUnit *SU) {
- Queue.push_back(SU);
- SU->NodeQueueId |= ID;
- }
-
- iterator remove(iterator I) {
- (*I)->NodeQueueId &= ~ID;
- *I = Queue.back();
- unsigned idx = I - Queue.begin();
- Queue.pop_back();
- return Queue.begin() + idx;
- }
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- void dump();
-#endif
-};
-
/// Mutate the DAG as a postpass after normal DAG building.
class ScheduleDAGMutation {
virtual void anchor();
@@ -270,19 +214,15 @@ public:
virtual void apply(ScheduleDAGMI *DAG) = 0;
};
-/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that schedules
-/// machine instructions while updating LiveIntervals and tracking regpressure.
+/// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply
+/// schedules machine instructions according to the given MachineSchedStrategy
+/// without much extra book-keeping. This is the common functionality between
+/// PreRA and PostRA MachineScheduler.
class ScheduleDAGMI : public ScheduleDAGInstrs {
protected:
AliasAnalysis *AA;
- RegisterClassInfo *RegClassInfo;
MachineSchedStrategy *SchedImpl;
- /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
- /// will be empty.
- SchedDFSResult *DFSResult;
- BitVector ScheduledTrees;
-
/// Topo - A topological ordering for SUnits which permits fast IsReachable
/// and similar queries.
ScheduleDAGTopologicalSort Topo;
@@ -290,32 +230,11 @@ protected:
/// Ordered list of DAG postprocessing steps.
std::vector<ScheduleDAGMutation*> Mutations;
- MachineBasicBlock::iterator LiveRegionEnd;
-
- // Map each SU to its summary of pressure changes. This array is updated for
- // liveness during bottom-up scheduling. Top-down scheduling may proceed but
- // has no affect on the pressure diffs.
- PressureDiffs SUPressureDiffs;
-
- /// Register pressure in this region computed by initRegPressure.
- bool ShouldTrackPressure;
- IntervalPressure RegPressure;
- RegPressureTracker RPTracker;
-
- /// List of pressure sets that exceed the target's pressure limit before
- /// scheduling, listed in increasing set ID order. Each pressure set is paired
- /// with its max pressure in the currently scheduled regions.
- std::vector<PressureChange> RegionCriticalPSets;
-
/// The top of the unscheduled zone.
MachineBasicBlock::iterator CurrentTop;
- IntervalPressure TopPressure;
- RegPressureTracker TopRPTracker;
/// The bottom of the unscheduled zone.
MachineBasicBlock::iterator CurrentBottom;
- IntervalPressure BotPressure;
- RegPressureTracker BotRPTracker;
/// Record the next node in a scheduled cluster.
const SUnit *NextClusterPred;
@@ -326,15 +245,12 @@ protected:
/// scheduler at the point determined by misched-cutoff.
unsigned NumInstrsScheduled;
#endif
-
public:
- ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
- ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
- AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), DFSResult(0),
- Topo(SUnits, &ExitSU), ShouldTrackPressure(false),
- RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
- CurrentBottom(), BotRPTracker(BotPressure),
- NextClusterPred(NULL), NextClusterSucc(NULL) {
+ ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S, bool IsPostRA):
+ ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, IsPostRA,
+ /*RemoveKillFlags=*/IsPostRA, C->LIS),
+ AA(C->AA), SchedImpl(S), Topo(SUnits, &ExitSU), CurrentTop(),
+ CurrentBottom(), NextClusterPred(NULL), NextClusterSucc(NULL) {
#ifndef NDEBUG
NumInstrsScheduled = 0;
#endif
@@ -342,8 +258,8 @@ public:
virtual ~ScheduleDAGMI();
- /// \brief Return true if register pressure tracking is enabled.
- bool isTrackingPressure() const { return ShouldTrackPressure; }
+ /// Return true if this DAG supports VReg liveness and RegPressure.
+ virtual bool hasVRegLiveness() const { return false; }
/// Add a postprocessing step to the DAG builder.
/// Mutations are applied in the order that they are added after normal DAG
@@ -374,16 +290,105 @@ public:
void enterRegion(MachineBasicBlock *bb,
MachineBasicBlock::iterator begin,
MachineBasicBlock::iterator end,
- unsigned regioninstrs) LLVM_OVERRIDE;
+ unsigned regioninstrs) override;
/// Implement ScheduleDAGInstrs interface for scheduling a sequence of
/// reorderable instructions.
- virtual void schedule();
+ void schedule() override;
/// Change the position of an instruction within the basic block and update
/// live ranges and region boundary iterators.
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
+ const SUnit *getNextClusterPred() const { return NextClusterPred; }
+
+ const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
+
+ void viewGraph(const Twine &Name, const Twine &Title) override;
+ void viewGraph() override;
+
+protected:
+ // Top-Level entry points for the schedule() driver...
+
+ /// Apply each ScheduleDAGMutation step in order. This allows different
+ /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
+ void postprocessDAG();
+
+ /// Release ExitSU predecessors and setup scheduler queues.
+ void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
+
+ /// Update scheduler DAG and queues after scheduling an instruction.
+ void updateQueues(SUnit *SU, bool IsTopNode);
+
+ /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
+ void placeDebugValues();
+
+ /// \brief dump the scheduled Sequence.
+ void dumpSchedule() const;
+
+ // Lesser helpers...
+ bool checkSchedLimit();
+
+ void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
+ SmallVectorImpl<SUnit*> &BotRoots);
+
+ void releaseSucc(SUnit *SU, SDep *SuccEdge);
+ void releaseSuccessors(SUnit *SU);
+ void releasePred(SUnit *SU, SDep *PredEdge);
+ void releasePredecessors(SUnit *SU);
+};
+
+/// ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules
+/// machine instructions while updating LiveIntervals and tracking regpressure.
+class ScheduleDAGMILive : public ScheduleDAGMI {
+protected:
+ RegisterClassInfo *RegClassInfo;
+
+ /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
+ /// will be empty.
+ SchedDFSResult *DFSResult;
+ BitVector ScheduledTrees;
+
+ MachineBasicBlock::iterator LiveRegionEnd;
+
+ // Map each SU to its summary of pressure changes. This array is updated for
+ // liveness during bottom-up scheduling. Top-down scheduling may proceed but
+ // has no affect on the pressure diffs.
+ PressureDiffs SUPressureDiffs;
+
+ /// Register pressure in this region computed by initRegPressure.
+ bool ShouldTrackPressure;
+ IntervalPressure RegPressure;
+ RegPressureTracker RPTracker;
+
+ /// List of pressure sets that exceed the target's pressure limit before
+ /// scheduling, listed in increasing set ID order. Each pressure set is paired
+ /// with its max pressure in the currently scheduled regions.
+ std::vector<PressureChange> RegionCriticalPSets;
+
+ /// The top of the unscheduled zone.
+ IntervalPressure TopPressure;
+ RegPressureTracker TopRPTracker;
+
+ /// The bottom of the unscheduled zone.
+ IntervalPressure BotPressure;
+ RegPressureTracker BotRPTracker;
+
+public:
+ ScheduleDAGMILive(MachineSchedContext *C, MachineSchedStrategy *S):
+ ScheduleDAGMI(C, S, /*IsPostRA=*/false), RegClassInfo(C->RegClassInfo),
+ DFSResult(0), ShouldTrackPressure(false), RPTracker(RegPressure),
+ TopRPTracker(TopPressure), BotRPTracker(BotPressure)
+ {}
+
+ virtual ~ScheduleDAGMILive();
+
+ /// Return true if this DAG supports VReg liveness and RegPressure.
+ bool hasVRegLiveness() const override { return true; }
+
+ /// \brief Return true if register pressure tracking is enabled.
+ bool isTrackingPressure() const { return ShouldTrackPressure; }
+
/// Get current register pressure for the top scheduled instructions.
const IntervalPressure &getTopPressure() const { return TopPressure; }
const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
@@ -403,10 +408,6 @@ public:
return SUPressureDiffs[SU->NodeNum];
}
- const SUnit *getNextClusterPred() const { return NextClusterPred; }
-
- const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
-
/// Compute a DFSResult after DAG building is complete, and before any
/// queue comparisons.
void computeDFSResult();
@@ -416,12 +417,21 @@ public:
BitVector &getScheduledTrees() { return ScheduledTrees; }
+ /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
+ /// region. This covers all instructions in a block, while schedule() may only
+ /// cover a subset.
+ void enterRegion(MachineBasicBlock *bb,
+ MachineBasicBlock::iterator begin,
+ MachineBasicBlock::iterator end,
+ unsigned regioninstrs) override;
+
+ /// Implement ScheduleDAGInstrs interface for scheduling a sequence of
+ /// reorderable instructions.
+ void schedule() override;
+
/// Compute the cyclic critical path through the DAG.
unsigned computeCyclicCriticalPath();
- void viewGraph(const Twine &Name, const Twine &Title) LLVM_OVERRIDE;
- void viewGraph() LLVM_OVERRIDE;
-
protected:
// Top-Level entry points for the schedule() driver...
@@ -431,25 +441,9 @@ protected:
/// bottom of the DAG region without covereing any unscheduled instruction.
void buildDAGWithRegPressure();
- /// Apply each ScheduleDAGMutation step in order. This allows different
- /// instances of ScheduleDAGMI to perform custom DAG postprocessing.
- void postprocessDAG();
-
- /// Release ExitSU predecessors and setup scheduler queues.
- void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
-
/// Move an instruction and update register pressure.
void scheduleMI(SUnit *SU, bool IsTopNode);
- /// Update scheduler DAG and queues after scheduling an instruction.
- void updateQueues(SUnit *SU, bool IsTopNode);
-
- /// Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
- void placeDebugValues();
-
- /// \brief dump the scheduled Sequence.
- void dumpSchedule() const;
-
// Lesser helpers...
void initRegPressure();
@@ -458,16 +452,286 @@ protected:
void updateScheduledPressure(const SUnit *SU,
const std::vector<unsigned> &NewMaxPressure);
+};
- bool checkSchedLimit();
+//===----------------------------------------------------------------------===//
+///
+/// Helpers for implementing custom MachineSchedStrategy classes. These take
+/// care of the book-keeping associated with list scheduling heuristics.
+///
+//===----------------------------------------------------------------------===//
- void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
- SmallVectorImpl<SUnit*> &BotRoots);
+/// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
+/// methods for pushing and removing nodes. ReadyQueue's are uniquely identified
+/// by an ID. SUnit::NodeQueueId is a mask of the ReadyQueues the SUnit is in.
+///
+/// This is a convenience class that may be used by implementations of
+/// MachineSchedStrategy.
+class ReadyQueue {
+ unsigned ID;
+ std::string Name;
+ std::vector<SUnit*> Queue;
- void releaseSucc(SUnit *SU, SDep *SuccEdge);
- void releaseSuccessors(SUnit *SU);
- void releasePred(SUnit *SU, SDep *PredEdge);
- void releasePredecessors(SUnit *SU);
+public:
+ ReadyQueue(unsigned id, const Twine &name): ID(id), Name(name.str()) {}
+
+ unsigned getID() const { return ID; }
+
+ StringRef getName() const { return Name; }
+
+ // SU is in this queue if it's NodeQueueID is a superset of this ID.
+ bool isInQueue(SUnit *SU) const { return (SU->NodeQueueId & ID); }
+
+ bool empty() const { return Queue.empty(); }
+
+ void clear() { Queue.clear(); }
+
+ unsigned size() const { return Queue.size(); }
+
+ typedef std::vector<SUnit*>::iterator iterator;
+
+ iterator begin() { return Queue.begin(); }
+
+ iterator end() { return Queue.end(); }
+
+ ArrayRef<SUnit*> elements() { return Queue; }
+
+ iterator find(SUnit *SU) {
+ return std::find(Queue.begin(), Queue.end(), SU);
+ }
+
+ void push(SUnit *SU) {
+ Queue.push_back(SU);
+ SU->NodeQueueId |= ID;
+ }
+
+ iterator remove(iterator I) {
+ (*I)->NodeQueueId &= ~ID;
+ *I = Queue.back();
+ unsigned idx = I - Queue.begin();
+ Queue.pop_back();
+ return Queue.begin() + idx;
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ void dump();
+#endif
+};
+
+/// Summarize the unscheduled region.
+struct SchedRemainder {
+ // Critical path through the DAG in expected latency.
+ unsigned CriticalPath;
+ unsigned CyclicCritPath;
+
+ // Scaled count of micro-ops left to schedule.
+ unsigned RemIssueCount;
+
+ bool IsAcyclicLatencyLimited;
+
+ // Unscheduled resources
+ SmallVector<unsigned, 16> RemainingCounts;
+
+ void reset() {
+ CriticalPath = 0;
+ CyclicCritPath = 0;
+ RemIssueCount = 0;
+ IsAcyclicLatencyLimited = false;
+ RemainingCounts.clear();
+ }
+
+ SchedRemainder() { reset(); }
+
+ void init(ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel);
+};
+
+/// Each Scheduling boundary is associated with ready queues. It tracks the
+/// current cycle in the direction of movement, and maintains the state
+/// of "hazards" and other interlocks at the current cycle.
+class SchedBoundary {
+public:
+ /// SUnit::NodeQueueId: 0 (none), 1 (top), 2 (bot), 3 (both)
+ enum {
+ TopQID = 1,
+ BotQID = 2,
+ LogMaxQID = 2
+ };
+
+ ScheduleDAGMI *DAG;
+ const TargetSchedModel *SchedModel;
+ SchedRemainder *Rem;
+
+ ReadyQueue Available;
+ ReadyQueue Pending;
+
+ ScheduleHazardRecognizer *HazardRec;
+
+private:
+ /// True if the pending Q should be checked/updated before scheduling another
+ /// instruction.
+ bool CheckPending;
+
+ // For heuristics, keep a list of the nodes that immediately depend on the
+ // most recently scheduled node.
+ SmallPtrSet<const SUnit*, 8> NextSUs;
+
+ /// Number of cycles it takes to issue the instructions scheduled in this
+ /// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
+ /// See getStalls().
+ unsigned CurrCycle;
+
+ /// Micro-ops issued in the current cycle
+ unsigned CurrMOps;
+
+ /// MinReadyCycle - Cycle of the soonest available instruction.
+ unsigned MinReadyCycle;
+
+ // The expected latency of the critical path in this scheduled zone.
+ unsigned ExpectedLatency;
+
+ // The latency of dependence chains leading into this zone.
+ // For each node scheduled bottom-up: DLat = max DLat, N.Depth.
+ // For each cycle scheduled: DLat -= 1.
+ unsigned DependentLatency;
+
+ /// Count the scheduled (issued) micro-ops that can be retired by
+ /// time=CurrCycle assuming the first scheduled instr is retired at time=0.
+ unsigned RetiredMOps;
+
+ // Count scheduled resources that have been executed. Resources are
+ // considered executed if they become ready in the time that it takes to
+ // saturate any resource including the one in question. Counts are scaled
+ // for direct comparison with other resources. Counts can be compared with
+ // MOps * getMicroOpFactor and Latency * getLatencyFactor.
+ SmallVector<unsigned, 16> ExecutedResCounts;
+
+ /// Cache the max count for a single resource.
+ unsigned MaxExecutedResCount;
+
+ // Cache the critical resources ID in this scheduled zone.
+ unsigned ZoneCritResIdx;
+
+ // Is the scheduled region resource limited vs. latency limited.
+ bool IsResourceLimited;
+
+ // Record the highest cycle at which each resource has been reserved by a
+ // scheduled instruction.
+ SmallVector<unsigned, 16> ReservedCycles;
+
+#ifndef NDEBUG
+ // Remember the greatest operand latency as an upper bound on the number of
+ // times we should retry the pending queue because of a hazard.
+ unsigned MaxObservedLatency;
+#endif
+
+public:
+ /// Pending queues extend the ready queues with the same ID and the
+ /// PendingFlag set.
+ SchedBoundary(unsigned ID, const Twine &Name):
+ DAG(0), SchedModel(0), Rem(0), Available(ID, Name+".A"),
+ Pending(ID << LogMaxQID, Name+".P"),
+ HazardRec(0) {
+ reset();
+ }
+
+ ~SchedBoundary();
+
+ void reset();
+
+ void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel,
+ SchedRemainder *rem);
+
+ bool isTop() const {
+ return Available.getID() == TopQID;
+ }
+
+ /// Number of cycles to issue the instructions scheduled in this zone.
+ unsigned getCurrCycle() const { return CurrCycle; }
+
+ /// Micro-ops issued in the current cycle
+ unsigned getCurrMOps() const { return CurrMOps; }
+
+ /// Return true if the given SU is used by the most recently scheduled
+ /// instruction.
+ bool isNextSU(const SUnit *SU) const { return NextSUs.count(SU); }
+
+ // The latency of dependence chains leading into this zone.
+ unsigned getDependentLatency() const { return DependentLatency; }
+
+ /// Get the number of latency cycles "covered" by the scheduled
+ /// instructions. This is the larger of the critical path within the zone
+ /// and the number of cycles required to issue the instructions.
+ unsigned getScheduledLatency() const {
+ return std::max(ExpectedLatency, CurrCycle);
+ }
+
+ unsigned getUnscheduledLatency(SUnit *SU) const {
+ return isTop() ? SU->getHeight() : SU->getDepth();
+ }
+
+ unsigned getResourceCount(unsigned ResIdx) const {
+ return ExecutedResCounts[ResIdx];
+ }
+
+ /// Get the scaled count of scheduled micro-ops and resources, including
+ /// executed resources.
+ unsigned getCriticalCount() const {
+ if (!ZoneCritResIdx)
+ return RetiredMOps * SchedModel->getMicroOpFactor();
+ return getResourceCount(ZoneCritResIdx);
+ }
+
+ /// Get a scaled count for the minimum execution time of the scheduled
+ /// micro-ops that are ready to execute by getExecutedCount. Notice the
+ /// feedback loop.
+ unsigned getExecutedCount() const {
+ return std::max(CurrCycle * SchedModel->getLatencyFactor(),
+ MaxExecutedResCount);
+ }
+
+ unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
+
+ // Is the scheduled region resource limited vs. latency limited.
+ bool isResourceLimited() const { return IsResourceLimited; }
+
+ /// Get the difference between the given SUnit's ready time and the current
+ /// cycle.
+ unsigned getLatencyStallCycles(SUnit *SU);
+
+ unsigned getNextResourceCycle(unsigned PIdx, unsigned Cycles);
+
+ bool checkHazard(SUnit *SU);
+
+ unsigned findMaxLatency(ArrayRef<SUnit*> ReadySUs);
+
+ unsigned getOtherResourceCount(unsigned &OtherCritIdx);
+
+ void releaseNode(SUnit *SU, unsigned ReadyCycle);
+
+ void releaseTopNode(SUnit *SU);
+
+ void releaseBottomNode(SUnit *SU);
+
+ void bumpCycle(unsigned NextCycle);
+
+ void incExecutedResources(unsigned PIdx, unsigned Count);
+
+ unsigned countResource(unsigned PIdx, unsigned Cycles, unsigned ReadyCycle);
+
+ void bumpNode(SUnit *SU);
+
+ void releasePending();
+
+ void removeReady(SUnit *SU);
+
+ /// Call this before applying any other heuristics to the Available queue.
+ /// Updates the Available/Pending Q's if necessary and returns the single
+ /// available instruction, or NULL if there are multiple candidates.
+ SUnit *pickOnlyChoice();
+
+#ifndef NDEBUG
+ void dumpScheduledState();
+#endif
};
} // namespace llvm
diff --git a/include/llvm/CodeGen/MachineTraceMetrics.h b/include/llvm/CodeGen/MachineTraceMetrics.h
index 9794707..dc0bc1d 100644
--- a/include/llvm/CodeGen/MachineTraceMetrics.h
+++ b/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -77,10 +77,10 @@ public:
class Trace;
static char ID;
MachineTraceMetrics();
- void getAnalysisUsage(AnalysisUsage&) const;
- bool runOnMachineFunction(MachineFunction&);
- void releaseMemory();
- void verifyAnalysis() const;
+ void getAnalysisUsage(AnalysisUsage&) const override;
+ bool runOnMachineFunction(MachineFunction&) override;
+ void releaseMemory() override;
+ void verifyAnalysis() const override;
friend class Ensemble;
friend class Trace;
diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h
new file mode 100644
index 0000000..84053ca
--- /dev/null
+++ b/include/llvm/CodeGen/MachineValueType.h
@@ -0,0 +1,578 @@
+//===- CodeGen/MachineValueType.h - Machine-Level 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 machine-level target independent types which
+// legal values in the code generator use.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEVALUETYPE_H
+#define LLVM_CODEGEN_MACHINEVALUETYPE_H
+
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+ class Type;
+
+ /// 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 an MVT.
+ class MVT {
+ public:
+ enum SimpleValueType {
+ // INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are
+ // considered extended value types.
+ INVALID_SIMPLE_VALUE_TYPE = -1,
+
+ // If you change this numbering, you must change the values in
+ // ValueTypes.td as well!
+ Other = 0, // This is a non-standard value
+ 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,
+
+ v2i1 = 13, // 2 x i1
+ v4i1 = 14, // 4 x i1
+ v8i1 = 15, // 8 x i1
+ v16i1 = 16, // 16 x i1
+ v32i1 = 17, // 32 x i1
+ v64i1 = 18, // 64 x i1
+
+ v1i8 = 19, // 1 x i8
+ v2i8 = 20, // 2 x i8
+ v4i8 = 21, // 4 x i8
+ v8i8 = 22, // 8 x i8
+ v16i8 = 23, // 16 x i8
+ v32i8 = 24, // 32 x i8
+ v64i8 = 25, // 64 x i8
+ v1i16 = 26, // 1 x i16
+ v2i16 = 27, // 2 x i16
+ v4i16 = 28, // 4 x i16
+ v8i16 = 29, // 8 x i16
+ v16i16 = 30, // 16 x i16
+ v32i16 = 31, // 32 x i16
+ v1i32 = 32, // 1 x i32
+ v2i32 = 33, // 2 x i32
+ v4i32 = 34, // 4 x i32
+ v8i32 = 35, // 8 x i32
+ v16i32 = 36, // 16 x i32
+ v1i64 = 37, // 1 x i64
+ v2i64 = 38, // 2 x i64
+ v4i64 = 39, // 4 x i64
+ v8i64 = 40, // 8 x i64
+ v16i64 = 41, // 16 x i64
+
+ FIRST_INTEGER_VECTOR_VALUETYPE = v2i1,
+ LAST_INTEGER_VECTOR_VALUETYPE = v16i64,
+
+ v2f16 = 42, // 2 x f16
+ v4f16 = 43, // 4 x f16
+ v8f16 = 44, // 8 x f16
+ v1f32 = 45, // 1 x f32
+ v2f32 = 46, // 2 x f32
+ v4f32 = 47, // 4 x f32
+ v8f32 = 48, // 8 x f32
+ v16f32 = 49, // 16 x f32
+ v1f64 = 50, // 1 x f64
+ v2f64 = 51, // 2 x f64
+ v4f64 = 52, // 4 x f64
+ v8f64 = 53, // 8 x f64
+
+ FIRST_FP_VECTOR_VALUETYPE = v2f16,
+ LAST_FP_VECTOR_VALUETYPE = v8f64,
+
+ FIRST_VECTOR_VALUETYPE = v2i1,
+ LAST_VECTOR_VALUETYPE = v8f64,
+
+ x86mmx = 54, // This is an X86 MMX value
+
+ Glue = 55, // This glues nodes together during pre-RA sched
+
+ isVoid = 56, // This has no value
+
+ Untyped = 57, // This value takes a register, but has
+ // unspecified type. The register class
+ // will be determined by the opcode.
+
+ LAST_VALUETYPE = 58, // 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
+ };
+
+ 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::FIRST_INTEGER_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_INTEGER_VECTOR_VALUETYPE));
+ }
+
+ /// isVector - Return true if this is a vector value type.
+ bool isVector() const {
+ return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
+ SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
+ }
+
+ /// is16BitVector - Return true if this is a 16-bit vector type.
+ bool is16BitVector() const {
+ return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 ||
+ SimpleTy == MVT::v16i1);
+ }
+
+ /// is32BitVector - Return true if this is a 32-bit vector type.
+ bool is32BitVector() const {
+ return (SimpleTy == MVT::v4i8 || SimpleTy == MVT::v2i16 ||
+ SimpleTy == MVT::v1i32);
+ }
+
+ /// is64BitVector - Return true if this is a 64-bit vector type.
+ bool is64BitVector() const {
+ return (SimpleTy == MVT::v8i8 || SimpleTy == MVT::v4i16 ||
+ SimpleTy == MVT::v2i32 || SimpleTy == MVT::v1i64 ||
+ SimpleTy == MVT::v1f64 || SimpleTy == MVT::v2f32);
+ }
+
+ /// is128BitVector - Return true if this is a 128-bit vector type.
+ bool is128BitVector() const {
+ return (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v8i16 ||
+ SimpleTy == MVT::v4i32 || SimpleTy == MVT::v2i64 ||
+ SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64);
+ }
+
+ /// is256BitVector - Return true if this is a 256-bit vector type.
+ bool is256BitVector() const {
+ return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 ||
+ SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 ||
+ SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64);
+ }
+
+ /// is512BitVector - Return true if this is a 512-bit vector type.
+ bool is512BitVector() const {
+ return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 ||
+ SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 ||
+ SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32);
+ }
+
+ /// is1024BitVector - Return true if this is a 1024-bit vector type.
+ bool is1024BitVector() const {
+ return (SimpleTy == MVT::v16i64);
+ }
+
+ /// isOverloaded - Return true if this is an overloaded type for TableGen.
+ bool isOverloaded() const {
+ return (SimpleTy==MVT::iAny || SimpleTy==MVT::fAny ||
+ SimpleTy==MVT::vAny || SimpleTy==MVT::iPTRAny);
+ }
+
+ /// 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:
+ llvm_unreachable("Not a vector MVT!");
+ case v2i1 :
+ case v4i1 :
+ case v8i1 :
+ case v16i1 :
+ case v32i1 :
+ case v64i1: return i1;
+ case v1i8 :
+ case v2i8 :
+ case v4i8 :
+ case v8i8 :
+ case v16i8:
+ case v32i8:
+ case v64i8: return i8;
+ case v1i16:
+ case v2i16:
+ case v4i16:
+ case v8i16:
+ case v16i16:
+ case v32i16: return i16;
+ case v1i32:
+ case v2i32:
+ case v4i32:
+ case v8i32:
+ case v16i32: return i32;
+ case v1i64:
+ case v2i64:
+ case v4i64:
+ case v8i64:
+ case v16i64: return i64;
+ case v2f16:
+ case v4f16:
+ case v8f16: return f16;
+ case v1f32:
+ case v2f32:
+ case v4f32:
+ case v8f32:
+ case v16f32: return f32;
+ case v1f64:
+ case v2f64:
+ case v4f64:
+ case v8f64: return f64;
+ }
+ }
+
+ unsigned getVectorNumElements() const {
+ switch (SimpleTy) {
+ default:
+ llvm_unreachable("Not a vector MVT!");
+ case v32i1:
+ case v32i8:
+ case v32i16: return 32;
+ case v64i1:
+ case v64i8: return 64;
+ case v16i1:
+ case v16i8:
+ case v16i16:
+ case v16i32:
+ case v16i64:
+ case v16f32: return 16;
+ case v8i1 :
+ case v8i8 :
+ case v8i16:
+ case v8i32:
+ case v8i64:
+ case v8f16:
+ case v8f32:
+ case v8f64: return 8;
+ case v4i1:
+ case v4i8:
+ case v4i16:
+ case v4i32:
+ case v4i64:
+ case v4f16:
+ case v4f32:
+ case v4f64: return 4;
+ case v2i1:
+ case v2i8:
+ case v2i16:
+ case v2i32:
+ case v2i64:
+ case v2f16:
+ case v2f32:
+ case v2f64: return 2;
+ case v1i8:
+ case v1i16:
+ case v1i32:
+ case v1i64:
+ case v1f32:
+ case v1f64: return 1;
+ }
+ }
+
+ unsigned getSizeInBits() const {
+ switch (SimpleTy) {
+ default:
+ llvm_unreachable("getSizeInBits called on extended MVT.");
+ case Other:
+ llvm_unreachable("Value type is non-standard value, Other.");
+ case iPTR:
+ llvm_unreachable("Value type size is target-dependent. Ask TLI.");
+ case iPTRAny:
+ case iAny:
+ case fAny:
+ case vAny:
+ llvm_unreachable("Value type is overloaded.");
+ case Metadata:
+ llvm_unreachable("Value type is metadata.");
+ case i1 : return 1;
+ case v2i1: return 2;
+ case v4i1: return 4;
+ case i8 :
+ case v1i8:
+ case v8i1: return 8;
+ case i16 :
+ case f16:
+ case v16i1:
+ case v2i8:
+ case v1i16: return 16;
+ case f32 :
+ case i32 :
+ case v32i1:
+ case v4i8:
+ case v2i16:
+ case v2f16:
+ case v1f32:
+ case v1i32: return 32;
+ case x86mmx:
+ case f64 :
+ case i64 :
+ case v64i1:
+ case v8i8:
+ case v4i16:
+ case v2i32:
+ case v1i64:
+ case v4f16:
+ case v2f32:
+ case v1f64: return 64;
+ case f80 : return 80;
+ case f128:
+ case ppcf128:
+ case i128:
+ case v16i8:
+ case v8i16:
+ case v4i32:
+ case v2i64:
+ case v8f16:
+ case v4f32:
+ case v2f64: return 128;
+ case v32i8:
+ case v16i16:
+ case v8i32:
+ case v4i64:
+ case v8f32:
+ case v4f64: return 256;
+ case v64i8:
+ case v32i16:
+ case v16i32:
+ case v8i64:
+ case v16f32:
+ case v8f64: return 512;
+ case v16i64:return 1024;
+ }
+ }
+
+ unsigned getScalarSizeInBits() const {
+ return getScalarType().getSizeInBits();
+ }
+
+ /// 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;
+ }
+
+ /// Return true if this has more bits than VT.
+ bool bitsGT(MVT VT) const {
+ return getSizeInBits() > VT.getSizeInBits();
+ }
+
+ /// Return true if this has no less bits than VT.
+ bool bitsGE(MVT VT) const {
+ return getSizeInBits() >= VT.getSizeInBits();
+ }
+
+ /// Return true if this has less bits than VT.
+ bool bitsLT(MVT VT) const {
+ return getSizeInBits() < VT.getSizeInBits();
+ }
+
+ /// Return true if this has no more bits than VT.
+ bool bitsLE(MVT VT) const {
+ return getSizeInBits() <= VT.getSizeInBits();
+ }
+
+
+ static MVT getFloatingPointVT(unsigned BitWidth) {
+ switch (BitWidth) {
+ default:
+ 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::i1:
+ if (NumElements == 2) return MVT::v2i1;
+ if (NumElements == 4) return MVT::v4i1;
+ if (NumElements == 8) return MVT::v8i1;
+ if (NumElements == 16) return MVT::v16i1;
+ if (NumElements == 32) return MVT::v32i1;
+ if (NumElements == 64) return MVT::v64i1;
+ break;
+ case MVT::i8:
+ if (NumElements == 1) return MVT::v1i8;
+ if (NumElements == 2) return MVT::v2i8;
+ if (NumElements == 4) return MVT::v4i8;
+ if (NumElements == 8) return MVT::v8i8;
+ if (NumElements == 16) return MVT::v16i8;
+ if (NumElements == 32) return MVT::v32i8;
+ if (NumElements == 64) return MVT::v64i8;
+ break;
+ case MVT::i16:
+ if (NumElements == 1) return MVT::v1i16;
+ if (NumElements == 2) return MVT::v2i16;
+ if (NumElements == 4) return MVT::v4i16;
+ if (NumElements == 8) return MVT::v8i16;
+ if (NumElements == 16) return MVT::v16i16;
+ if (NumElements == 32) return MVT::v32i16;
+ break;
+ case MVT::i32:
+ if (NumElements == 1) return MVT::v1i32;
+ if (NumElements == 2) return MVT::v2i32;
+ if (NumElements == 4) return MVT::v4i32;
+ if (NumElements == 8) return MVT::v8i32;
+ if (NumElements == 16) return MVT::v16i32;
+ 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;
+ if (NumElements == 16) return MVT::v16i64;
+ break;
+ case MVT::f16:
+ if (NumElements == 2) return MVT::v2f16;
+ if (NumElements == 4) return MVT::v4f16;
+ if (NumElements == 8) return MVT::v8f16;
+ break;
+ case MVT::f32:
+ if (NumElements == 1) return MVT::v1f32;
+ if (NumElements == 2) return MVT::v2f32;
+ if (NumElements == 4) return MVT::v4f32;
+ if (NumElements == 8) return MVT::v8f32;
+ if (NumElements == 16) return MVT::v16f32;
+ break;
+ case MVT::f64:
+ if (NumElements == 1) return MVT::v1f64;
+ if (NumElements == 2) return MVT::v2f64;
+ if (NumElements == 4) return MVT::v4f64;
+ if (NumElements == 8) return MVT::v8f64;
+ break;
+ }
+ return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
+ }
+
+ /// Return the value type corresponding to the specified type. This returns
+ /// all pointers as iPTR. If HandleUnknown is true, unknown types are
+ /// returned as Other, otherwise they are invalid.
+ static MVT getVT(Type *Ty, bool HandleUnknown = false);
+
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/PBQP/CostAllocator.h b/include/llvm/CodeGen/PBQP/CostAllocator.h
new file mode 100644
index 0000000..1646334
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/CostAllocator.h
@@ -0,0 +1,147 @@
+//===---------- CostAllocator.h - PBQP Cost Allocator -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines classes conforming to the PBQP cost value manager concept.
+//
+// Cost value managers are memory managers for PBQP cost values (vectors and
+// matrices). Since PBQP graphs can grow very large (E.g. hundreds of thousands
+// of edges on the largest function in SPEC2006).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_COSTALLOCATOR_H
+#define LLVM_COSTALLOCATOR_H
+
+#include <set>
+#include <type_traits>
+
+namespace PBQP {
+
+template <typename CostT,
+ typename CostKeyTComparator>
+class CostPool {
+public:
+
+ class PoolEntry {
+ public:
+ template <typename CostKeyT>
+ PoolEntry(CostPool &pool, CostKeyT cost)
+ : pool(pool), cost(std::move(cost)), refCount(0) {}
+ ~PoolEntry() { pool.removeEntry(this); }
+ void incRef() { ++refCount; }
+ bool decRef() { --refCount; return (refCount == 0); }
+ CostT& getCost() { return cost; }
+ const CostT& getCost() const { return cost; }
+ private:
+ CostPool &pool;
+ CostT cost;
+ std::size_t refCount;
+ };
+
+ class PoolRef {
+ public:
+ PoolRef(PoolEntry *entry) : entry(entry) {
+ this->entry->incRef();
+ }
+ PoolRef(const PoolRef &r) {
+ entry = r.entry;
+ entry->incRef();
+ }
+ PoolRef& operator=(const PoolRef &r) {
+ assert(entry != 0 && "entry should not be null.");
+ PoolEntry *temp = r.entry;
+ temp->incRef();
+ entry->decRef();
+ entry = temp;
+ return *this;
+ }
+
+ ~PoolRef() {
+ if (entry->decRef())
+ delete entry;
+ }
+ void reset(PoolEntry *entry) {
+ entry->incRef();
+ this->entry->decRef();
+ this->entry = entry;
+ }
+ CostT& operator*() { return entry->getCost(); }
+ const CostT& operator*() const { return entry->getCost(); }
+ CostT* operator->() { return &entry->getCost(); }
+ const CostT* operator->() const { return &entry->getCost(); }
+ private:
+ PoolEntry *entry;
+ };
+
+private:
+ class EntryComparator {
+ public:
+ template <typename CostKeyT>
+ typename std::enable_if<
+ !std::is_same<PoolEntry*,
+ typename std::remove_const<CostKeyT>::type>::value,
+ bool>::type
+ operator()(const PoolEntry* a, const CostKeyT &b) {
+ return compare(a->getCost(), b);
+ }
+ bool operator()(const PoolEntry* a, const PoolEntry* b) {
+ return compare(a->getCost(), b->getCost());
+ }
+ private:
+ CostKeyTComparator compare;
+ };
+
+ typedef std::set<PoolEntry*, EntryComparator> EntrySet;
+
+ EntrySet entrySet;
+
+ void removeEntry(PoolEntry *p) { entrySet.erase(p); }
+
+public:
+
+ template <typename CostKeyT>
+ PoolRef getCost(CostKeyT costKey) {
+ typename EntrySet::iterator itr =
+ std::lower_bound(entrySet.begin(), entrySet.end(), costKey,
+ EntryComparator());
+
+ if (itr != entrySet.end() && costKey == (*itr)->getCost())
+ return PoolRef(*itr);
+
+ PoolEntry *p = new PoolEntry(*this, std::move(costKey));
+ entrySet.insert(itr, p);
+ return PoolRef(p);
+ }
+};
+
+template <typename VectorT, typename VectorTComparator,
+ typename MatrixT, typename MatrixTComparator>
+class PoolCostAllocator {
+private:
+ typedef CostPool<VectorT, VectorTComparator> VectorCostPool;
+ typedef CostPool<MatrixT, MatrixTComparator> MatrixCostPool;
+public:
+ typedef VectorT Vector;
+ typedef MatrixT Matrix;
+ typedef typename VectorCostPool::PoolRef VectorPtr;
+ typedef typename MatrixCostPool::PoolRef MatrixPtr;
+
+ template <typename VectorKeyT>
+ VectorPtr getVector(VectorKeyT v) { return vectorPool.getCost(std::move(v)); }
+
+ template <typename MatrixKeyT>
+ MatrixPtr getMatrix(MatrixKeyT m) { return matrixPool.getCost(std::move(m)); }
+private:
+ VectorCostPool vectorPool;
+ MatrixCostPool matrixPool;
+};
+
+}
+
+#endif // LLVM_COSTALLOCATOR_H
diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h
index aca0a91..07c3337 100644
--- a/include/llvm/CodeGen/PBQP/Graph.h
+++ b/include/llvm/CodeGen/PBQP/Graph.h
@@ -15,464 +15,628 @@
#ifndef LLVM_CODEGEN_PBQP_GRAPH_H
#define LLVM_CODEGEN_PBQP_GRAPH_H
-#include "Math.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/Support/Compiler.h"
#include <list>
#include <map>
#include <set>
namespace PBQP {
- /// PBQP Graph class.
- /// Instances of this class describe PBQP problems.
- class Graph {
+ class GraphBase {
public:
-
typedef unsigned NodeId;
typedef unsigned EdgeId;
- private:
+ /// \brief Returns a value representing an invalid (non-existant) node.
+ static NodeId invalidNodeId() {
+ return std::numeric_limits<NodeId>::max();
+ }
- typedef std::set<NodeId> AdjEdgeList;
+ /// \brief Returns a value representing an invalid (non-existant) edge.
+ static EdgeId invalidEdgeId() {
+ return std::numeric_limits<EdgeId>::max();
+ }
+ };
+ /// PBQP Graph class.
+ /// Instances of this class describe PBQP problems.
+ ///
+ template <typename SolverT>
+ class Graph : public GraphBase {
+ private:
+ typedef typename SolverT::CostAllocator CostAllocator;
public:
-
- typedef AdjEdgeList::iterator AdjEdgeItr;
+ typedef typename SolverT::RawVector RawVector;
+ typedef typename SolverT::RawMatrix RawMatrix;
+ typedef typename SolverT::Vector Vector;
+ typedef typename SolverT::Matrix Matrix;
+ typedef typename CostAllocator::VectorPtr VectorPtr;
+ typedef typename CostAllocator::MatrixPtr MatrixPtr;
+ typedef typename SolverT::NodeMetadata NodeMetadata;
+ typedef typename SolverT::EdgeMetadata EdgeMetadata;
private:
class NodeEntry {
- private:
- Vector costs;
- AdjEdgeList adjEdges;
- void *data;
- NodeEntry() : costs(0, 0) {}
public:
- NodeEntry(const Vector &costs) : costs(costs), data(0) {}
- Vector& getCosts() { return costs; }
- const Vector& getCosts() const { return costs; }
- unsigned getDegree() const { return adjEdges.size(); }
- AdjEdgeItr edgesBegin() { return adjEdges.begin(); }
- AdjEdgeItr edgesEnd() { return adjEdges.end(); }
- AdjEdgeItr addEdge(EdgeId e) {
- return adjEdges.insert(adjEdges.end(), e);
+ typedef std::vector<EdgeId> AdjEdgeList;
+ typedef AdjEdgeList::size_type AdjEdgeIdx;
+ typedef AdjEdgeList::const_iterator AdjEdgeItr;
+
+ static AdjEdgeIdx getInvalidAdjEdgeIdx() {
+ return std::numeric_limits<AdjEdgeIdx>::max();
}
- void removeEdge(AdjEdgeItr ae) {
- adjEdges.erase(ae);
+
+ NodeEntry(VectorPtr Costs) : Costs(Costs) {}
+
+ AdjEdgeIdx addAdjEdgeId(EdgeId EId) {
+ AdjEdgeIdx Idx = AdjEdgeIds.size();
+ AdjEdgeIds.push_back(EId);
+ return Idx;
+ }
+
+ void removeAdjEdgeId(Graph &G, NodeId ThisNId, AdjEdgeIdx Idx) {
+ // Swap-and-pop for fast removal.
+ // 1) Update the adj index of the edge currently at back().
+ // 2) Move last Edge down to Idx.
+ // 3) pop_back()
+ // If Idx == size() - 1 then the setAdjEdgeIdx and swap are
+ // redundant, but both operations are cheap.
+ G.getEdge(AdjEdgeIds.back()).setAdjEdgeIdx(ThisNId, Idx);
+ AdjEdgeIds[Idx] = AdjEdgeIds.back();
+ AdjEdgeIds.pop_back();
}
- void setData(void *data) { this->data = data; }
- void* getData() { return data; }
+
+ const AdjEdgeList& getAdjEdgeIds() const { return AdjEdgeIds; }
+
+ VectorPtr Costs;
+ NodeMetadata Metadata;
+ private:
+ AdjEdgeList AdjEdgeIds;
};
class EdgeEntry {
- private:
- NodeId node1, node2;
- Matrix costs;
- AdjEdgeItr node1AEItr, node2AEItr;
- void *data;
- EdgeEntry() : costs(0, 0, 0), data(0) {}
public:
- EdgeEntry(NodeId node1, NodeId node2, const Matrix &costs)
- : node1(node1), node2(node2), costs(costs) {}
- NodeId getNode1() const { return node1; }
- NodeId 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; }
+ EdgeEntry(NodeId N1Id, NodeId N2Id, MatrixPtr Costs)
+ : Costs(Costs) {
+ NIds[0] = N1Id;
+ NIds[1] = N2Id;
+ ThisEdgeAdjIdxs[0] = NodeEntry::getInvalidAdjEdgeIdx();
+ ThisEdgeAdjIdxs[1] = NodeEntry::getInvalidAdjEdgeIdx();
+ }
+
+ void invalidate() {
+ NIds[0] = NIds[1] = Graph::invalidNodeId();
+ ThisEdgeAdjIdxs[0] = ThisEdgeAdjIdxs[1] =
+ NodeEntry::getInvalidAdjEdgeIdx();
+ Costs = nullptr;
+ }
+
+ void connectToN(Graph &G, EdgeId ThisEdgeId, unsigned NIdx) {
+ assert(ThisEdgeAdjIdxs[NIdx] == NodeEntry::getInvalidAdjEdgeIdx() &&
+ "Edge already connected to NIds[NIdx].");
+ NodeEntry &N = G.getNode(NIds[NIdx]);
+ ThisEdgeAdjIdxs[NIdx] = N.addAdjEdgeId(ThisEdgeId);
+ }
+
+ void connectTo(Graph &G, EdgeId ThisEdgeId, NodeId NId) {
+ if (NId == NIds[0])
+ connectToN(G, ThisEdgeId, 0);
+ else {
+ assert(NId == NIds[1] && "Edge does not connect NId.");
+ connectToN(G, ThisEdgeId, 1);
+ }
+ }
+
+ void connect(Graph &G, EdgeId ThisEdgeId) {
+ connectToN(G, ThisEdgeId, 0);
+ connectToN(G, ThisEdgeId, 1);
+ }
+
+ void setAdjEdgeIdx(NodeId NId, typename NodeEntry::AdjEdgeIdx NewIdx) {
+ if (NId == NIds[0])
+ ThisEdgeAdjIdxs[0] = NewIdx;
+ else {
+ assert(NId == NIds[1] && "Edge not connected to NId");
+ ThisEdgeAdjIdxs[1] = NewIdx;
+ }
+ }
+
+ void disconnectFromN(Graph &G, unsigned NIdx) {
+ assert(ThisEdgeAdjIdxs[NIdx] != NodeEntry::getInvalidAdjEdgeIdx() &&
+ "Edge not connected to NIds[NIdx].");
+ NodeEntry &N = G.getNode(NIds[NIdx]);
+ N.removeAdjEdgeId(G, NIds[NIdx], ThisEdgeAdjIdxs[NIdx]);
+ ThisEdgeAdjIdxs[NIdx] = NodeEntry::getInvalidAdjEdgeIdx();
+ }
+
+ void disconnectFrom(Graph &G, NodeId NId) {
+ if (NId == NIds[0])
+ disconnectFromN(G, 0);
+ else {
+ assert(NId == NIds[1] && "Edge does not connect NId");
+ disconnectFromN(G, 1);
+ }
+ }
+
+ NodeId getN1Id() const { return NIds[0]; }
+ NodeId getN2Id() const { return NIds[1]; }
+ MatrixPtr Costs;
+ EdgeMetadata Metadata;
+ private:
+ NodeId NIds[2];
+ typename NodeEntry::AdjEdgeIdx ThisEdgeAdjIdxs[2];
};
// ----- MEMBERS -----
+ CostAllocator CostAlloc;
+ SolverT *Solver;
+
typedef std::vector<NodeEntry> NodeVector;
typedef std::vector<NodeId> FreeNodeVector;
- NodeVector nodes;
- FreeNodeVector freeNodes;
+ NodeVector Nodes;
+ FreeNodeVector FreeNodeIds;
typedef std::vector<EdgeEntry> EdgeVector;
typedef std::vector<EdgeId> FreeEdgeVector;
- EdgeVector edges;
- FreeEdgeVector freeEdges;
+ EdgeVector Edges;
+ FreeEdgeVector FreeEdgeIds;
// ----- INTERNAL METHODS -----
- NodeEntry& getNode(NodeId nId) { return nodes[nId]; }
- const NodeEntry& getNode(NodeId nId) const { return nodes[nId]; }
+ NodeEntry& getNode(NodeId NId) { return Nodes[NId]; }
+ const NodeEntry& getNode(NodeId NId) const { return Nodes[NId]; }
- EdgeEntry& getEdge(EdgeId eId) { return edges[eId]; }
- const EdgeEntry& getEdge(EdgeId eId) const { return edges[eId]; }
+ EdgeEntry& getEdge(EdgeId EId) { return Edges[EId]; }
+ const EdgeEntry& getEdge(EdgeId EId) const { return Edges[EId]; }
- NodeId addConstructedNode(const NodeEntry &n) {
- NodeId nodeId = 0;
- if (!freeNodes.empty()) {
- nodeId = freeNodes.back();
- freeNodes.pop_back();
- nodes[nodeId] = n;
+ NodeId addConstructedNode(const NodeEntry &N) {
+ NodeId NId = 0;
+ if (!FreeNodeIds.empty()) {
+ NId = FreeNodeIds.back();
+ FreeNodeIds.pop_back();
+ Nodes[NId] = std::move(N);
} else {
- nodeId = nodes.size();
- nodes.push_back(n);
+ NId = Nodes.size();
+ Nodes.push_back(std::move(N));
}
- return nodeId;
+ return NId;
}
- EdgeId addConstructedEdge(const EdgeEntry &e) {
- assert(findEdge(e.getNode1(), e.getNode2()) == invalidEdgeId() &&
+ EdgeId addConstructedEdge(const EdgeEntry &E) {
+ assert(findEdge(E.getN1Id(), E.getN2Id()) == invalidEdgeId() &&
"Attempt to add duplicate edge.");
- EdgeId edgeId = 0;
- if (!freeEdges.empty()) {
- edgeId = freeEdges.back();
- freeEdges.pop_back();
- edges[edgeId] = e;
+ EdgeId EId = 0;
+ if (!FreeEdgeIds.empty()) {
+ EId = FreeEdgeIds.back();
+ FreeEdgeIds.pop_back();
+ Edges[EId] = std::move(E);
} else {
- edgeId = edges.size();
- edges.push_back(e);
+ EId = Edges.size();
+ Edges.push_back(std::move(E));
}
- EdgeEntry &ne = getEdge(edgeId);
- 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.");
+ EdgeEntry &NE = getEdge(EId);
- ne.setNode1AEItr(n1.addEdge(edgeId));
- ne.setNode2AEItr(n2.addEdge(edgeId));
- return edgeId;
+ // Add the edge to the adjacency sets of its nodes.
+ NE.connect(*this, EId);
+ return EId;
}
- Graph(const Graph &other) {}
- void operator=(const Graph &other) {}
+ Graph(const Graph &Other) {}
+ void operator=(const Graph &Other) {}
public:
+ typedef typename NodeEntry::AdjEdgeItr AdjEdgeItr;
+
class NodeItr {
public:
- NodeItr(NodeId nodeId, const Graph &g)
- : nodeId(nodeId), endNodeId(g.nodes.size()), freeNodes(g.freeNodes) {
- this->nodeId = findNextInUse(nodeId); // Move to the first in-use nodeId
+ NodeItr(NodeId CurNId, const Graph &G)
+ : CurNId(CurNId), EndNId(G.Nodes.size()), FreeNodeIds(G.FreeNodeIds) {
+ this->CurNId = findNextInUse(CurNId); // Move to first in-use node id
}
- bool operator==(const NodeItr& n) const { return nodeId == n.nodeId; }
- bool operator!=(const NodeItr& n) const { return !(*this == n); }
- NodeItr& operator++() { nodeId = findNextInUse(++nodeId); return *this; }
- NodeId operator*() const { return nodeId; }
+ bool operator==(const NodeItr &O) const { return CurNId == O.CurNId; }
+ bool operator!=(const NodeItr &O) const { return !(*this == O); }
+ NodeItr& operator++() { CurNId = findNextInUse(++CurNId); return *this; }
+ NodeId operator*() const { return CurNId; }
private:
- NodeId findNextInUse(NodeId n) const {
- while (n < endNodeId &&
- std::find(freeNodes.begin(), freeNodes.end(), n) !=
- freeNodes.end()) {
- ++n;
+ NodeId findNextInUse(NodeId NId) const {
+ while (NId < EndNId &&
+ std::find(FreeNodeIds.begin(), FreeNodeIds.end(), NId) !=
+ FreeNodeIds.end()) {
+ ++NId;
}
- return n;
+ return NId;
}
- NodeId nodeId, endNodeId;
- const FreeNodeVector& freeNodes;
+ NodeId CurNId, EndNId;
+ const FreeNodeVector &FreeNodeIds;
};
class EdgeItr {
public:
- EdgeItr(EdgeId edgeId, const Graph &g)
- : edgeId(edgeId), endEdgeId(g.edges.size()), freeEdges(g.freeEdges) {
- this->edgeId = findNextInUse(edgeId); // Move to the first in-use edgeId
+ EdgeItr(EdgeId CurEId, const Graph &G)
+ : CurEId(CurEId), EndEId(G.Edges.size()), FreeEdgeIds(G.FreeEdgeIds) {
+ this->CurEId = findNextInUse(CurEId); // Move to first in-use edge id
}
- bool operator==(const EdgeItr& n) const { return edgeId == n.edgeId; }
- bool operator!=(const EdgeItr& n) const { return !(*this == n); }
- EdgeItr& operator++() { edgeId = findNextInUse(++edgeId); return *this; }
- EdgeId operator*() const { return edgeId; }
+ bool operator==(const EdgeItr &O) const { return CurEId == O.CurEId; }
+ bool operator!=(const EdgeItr &O) const { return !(*this == O); }
+ EdgeItr& operator++() { CurEId = findNextInUse(++CurEId); return *this; }
+ EdgeId operator*() const { return CurEId; }
private:
- EdgeId findNextInUse(EdgeId n) const {
- while (n < endEdgeId &&
- std::find(freeEdges.begin(), freeEdges.end(), n) !=
- freeEdges.end()) {
- ++n;
+ EdgeId findNextInUse(EdgeId EId) const {
+ while (EId < EndEId &&
+ std::find(FreeEdgeIds.begin(), FreeEdgeIds.end(), EId) !=
+ FreeEdgeIds.end()) {
+ ++EId;
}
- return n;
+ return EId;
+ }
+
+ EdgeId CurEId, EndEId;
+ const FreeEdgeVector &FreeEdgeIds;
+ };
+
+ class NodeIdSet {
+ public:
+ NodeIdSet(const Graph &G) : G(G) { }
+ NodeItr begin() const { return NodeItr(0, G); }
+ NodeItr end() const { return NodeItr(G.Nodes.size(), G); }
+ bool empty() const { return G.Nodes.empty(); }
+ typename NodeVector::size_type size() const {
+ return G.Nodes.size() - G.FreeNodeIds.size();
}
+ private:
+ const Graph& G;
+ };
- EdgeId edgeId, endEdgeId;
- const FreeEdgeVector& freeEdges;
+ class EdgeIdSet {
+ public:
+ EdgeIdSet(const Graph &G) : G(G) { }
+ EdgeItr begin() const { return EdgeItr(0, G); }
+ EdgeItr end() const { return EdgeItr(G.Edges.size(), G); }
+ bool empty() const { return G.Edges.empty(); }
+ typename NodeVector::size_type size() const {
+ return G.Edges.size() - G.FreeEdgeIds.size();
+ }
+ private:
+ const Graph& G;
+ };
+
+ class AdjEdgeIdSet {
+ public:
+ AdjEdgeIdSet(const NodeEntry &NE) : NE(NE) { }
+ typename NodeEntry::AdjEdgeItr begin() const {
+ return NE.getAdjEdgeIds().begin();
+ }
+ typename NodeEntry::AdjEdgeItr end() const {
+ return NE.getAdjEdgeIds().end();
+ }
+ bool empty() const { return NE.getAdjEdgeIds().empty(); }
+ typename NodeEntry::AdjEdgeList::size_type size() const {
+ return NE.getAdjEdgeIds().size();
+ }
+ private:
+ const NodeEntry &NE;
};
/// \brief Construct an empty PBQP graph.
- Graph() {}
+ Graph() : Solver(nullptr) { }
+
+ /// \brief Lock this graph to the given solver instance in preparation
+ /// for running the solver. This method will call solver.handleAddNode for
+ /// each node in the graph, and handleAddEdge for each edge, to give the
+ /// solver an opportunity to set up any requried metadata.
+ void setSolver(SolverT &S) {
+ assert(Solver == nullptr && "Solver already set. Call unsetSolver().");
+ Solver = &S;
+ for (auto NId : nodeIds())
+ Solver->handleAddNode(NId);
+ for (auto EId : edgeIds())
+ Solver->handleAddEdge(EId);
+ }
+
+ /// \brief Release from solver instance.
+ void unsetSolver() {
+ assert(Solver != nullptr && "Solver not set.");
+ Solver = nullptr;
+ }
/// \brief Add a node with the given costs.
- /// @param costs Cost vector for the new node.
+ /// @param Costs Cost vector for the new node.
/// @return Node iterator for the added node.
- NodeId addNode(const Vector &costs) {
- return addConstructedNode(NodeEntry(costs));
+ template <typename OtherVectorT>
+ NodeId addNode(OtherVectorT Costs) {
+ // Get cost vector from the problem domain
+ VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
+ NodeId NId = addConstructedNode(NodeEntry(AllocatedCosts));
+ if (Solver)
+ Solver->handleAddNode(NId);
+ return NId;
}
/// \brief Add an edge between the given nodes with the given costs.
- /// @param n1Id First node.
- /// @param n2Id Second node.
+ /// @param N1Id First node.
+ /// @param N2Id Second node.
/// @return Edge iterator for the added edge.
- EdgeId addEdge(NodeId n1Id, NodeId n2Id, const Matrix &costs) {
- assert(getNodeCosts(n1Id).getLength() == costs.getRows() &&
- getNodeCosts(n2Id).getLength() == costs.getCols() &&
+ template <typename OtherVectorT>
+ EdgeId addEdge(NodeId N1Id, NodeId N2Id, OtherVectorT Costs) {
+ assert(getNodeCosts(N1Id).getLength() == Costs.getRows() &&
+ getNodeCosts(N2Id).getLength() == Costs.getCols() &&
"Matrix dimensions mismatch.");
- return addConstructedEdge(EdgeEntry(n1Id, n2Id, costs));
+ // Get cost matrix from the problem domain.
+ MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
+ EdgeId EId = addConstructedEdge(EdgeEntry(N1Id, N2Id, AllocatedCosts));
+ if (Solver)
+ Solver->handleAddEdge(EId);
+ return EId;
}
+ /// \brief Returns true if the graph is empty.
+ bool empty() const { return NodeIdSet(*this).empty(); }
+
+ NodeIdSet nodeIds() const { return NodeIdSet(*this); }
+ EdgeIdSet edgeIds() const { return EdgeIdSet(*this); }
+
+ AdjEdgeIdSet adjEdgeIds(NodeId NId) { return AdjEdgeIdSet(getNode(NId)); }
+
/// \brief Get the number of nodes in the graph.
/// @return Number of nodes in the graph.
- unsigned getNumNodes() const { return nodes.size() - freeNodes.size(); }
+ unsigned getNumNodes() const { return NodeIdSet(*this).size(); }
/// \brief Get the number of edges in the graph.
/// @return Number of edges in the graph.
- unsigned getNumEdges() const { return edges.size() - freeEdges.size(); }
-
- /// \brief Get a node's cost vector.
- /// @param nId Node id.
- /// @return Node cost vector.
- Vector& getNodeCosts(NodeId nId) { return getNode(nId).getCosts(); }
+ unsigned getNumEdges() const { return EdgeIdSet(*this).size(); }
+
+ /// \brief Set a node's cost vector.
+ /// @param NId Node to update.
+ /// @param Costs New costs to set.
+ template <typename OtherVectorT>
+ void setNodeCosts(NodeId NId, OtherVectorT Costs) {
+ VectorPtr AllocatedCosts = CostAlloc.getVector(std::move(Costs));
+ if (Solver)
+ Solver->handleSetNodeCosts(NId, *AllocatedCosts);
+ getNode(NId).Costs = AllocatedCosts;
+ }
/// \brief Get a node's cost vector (const version).
- /// @param nId Node id.
+ /// @param NId Node id.
/// @return Node cost vector.
- const Vector& getNodeCosts(NodeId nId) const {
- return getNode(nId).getCosts();
+ const Vector& getNodeCosts(NodeId NId) const {
+ return *getNode(NId).Costs;
}
- /// \brief Set a node's data pointer.
- /// @param nId Node id.
- /// @param data Pointer to node data.
- ///
- /// Typically used by a PBQP solver to attach data to aid in solution.
- void setNodeData(NodeId nId, void *data) { getNode(nId).setData(data); }
-
- /// \brief Get the node's data pointer.
- /// @param nId Node id.
- /// @return Pointer to node data.
- void* getNodeData(NodeId nId) { return getNode(nId).getData(); }
-
- /// \brief Get an edge's cost matrix.
- /// @param eId Edge id.
- /// @return Edge cost matrix.
- Matrix& getEdgeCosts(EdgeId eId) { return getEdge(eId).getCosts(); }
-
- /// \brief Get an edge's cost matrix (const version).
- /// @param eId Edge id.
- /// @return Edge cost matrix.
- const Matrix& getEdgeCosts(EdgeId eId) const {
- return getEdge(eId).getCosts();
+ NodeMetadata& getNodeMetadata(NodeId NId) {
+ return getNode(NId).Metadata;
}
- /// \brief Set an edge's data pointer.
- /// @param eId Edge id.
- /// @param data Pointer to edge data.
- ///
- /// Typically used by a PBQP solver to attach data to aid in solution.
- void setEdgeData(EdgeId eId, void *data) { getEdge(eId).setData(data); }
-
- /// \brief Get an edge's data pointer.
- /// @param eId Edge id.
- /// @return Pointer to edge data.
- void* getEdgeData(EdgeId eId) { return getEdge(eId).getData(); }
-
- /// \brief Get a node's degree.
- /// @param nId Node id.
- /// @return The degree of the node.
- unsigned getNodeDegree(NodeId nId) const {
- return getNode(nId).getDegree();
+ const NodeMetadata& getNodeMetadata(NodeId NId) const {
+ return getNode(NId).Metadata;
}
- /// \brief Begin iterator for node set.
- NodeItr nodesBegin() const { return NodeItr(0, *this); }
-
- /// \brief End iterator for node set.
- NodeItr nodesEnd() const { return NodeItr(nodes.size(), *this); }
+ typename NodeEntry::AdjEdgeList::size_type getNodeDegree(NodeId NId) const {
+ return getNode(NId).getAdjEdgeIds().size();
+ }
- /// \brief Begin iterator for edge set.
- EdgeItr edgesBegin() const { return EdgeItr(0, *this); }
+ /// \brief Set an edge's cost matrix.
+ /// @param EId Edge id.
+ /// @param Costs New cost matrix.
+ template <typename OtherMatrixT>
+ void setEdgeCosts(EdgeId EId, OtherMatrixT Costs) {
+ MatrixPtr AllocatedCosts = CostAlloc.getMatrix(std::move(Costs));
+ if (Solver)
+ Solver->handleSetEdgeCosts(EId, *AllocatedCosts);
+ getEdge(EId).Costs = AllocatedCosts;
+ }
- /// \brief End iterator for edge set.
- EdgeItr edgesEnd() const { return EdgeItr(edges.size(), *this); }
+ /// \brief Get an edge's cost matrix (const version).
+ /// @param EId Edge id.
+ /// @return Edge cost matrix.
+ const Matrix& getEdgeCosts(EdgeId EId) const { return *getEdge(EId).Costs; }
- /// \brief Get begin iterator for adjacent edge set.
- /// @param nId Node id.
- /// @return Begin iterator for the set of edges connected to the given node.
- AdjEdgeItr adjEdgesBegin(NodeId nId) {
- return getNode(nId).edgesBegin();
+ EdgeMetadata& getEdgeMetadata(EdgeId NId) {
+ return getEdge(NId).Metadata;
}
- /// \brief Get end iterator for adjacent edge set.
- /// @param nId Node id.
- /// @return End iterator for the set of edges connected to the given node.
- AdjEdgeItr adjEdgesEnd(NodeId nId) {
- return getNode(nId).edgesEnd();
+ const EdgeMetadata& getEdgeMetadata(EdgeId NId) const {
+ return getEdge(NId).Metadata;
}
/// \brief Get the first node connected to this edge.
- /// @param eId Edge id.
+ /// @param EId Edge id.
/// @return The first node connected to the given edge.
- NodeId getEdgeNode1(EdgeId eId) {
- return getEdge(eId).getNode1();
+ NodeId getEdgeNode1Id(EdgeId EId) {
+ return getEdge(EId).getN1Id();
}
/// \brief Get the second node connected to this edge.
- /// @param eId Edge id.
+ /// @param EId Edge id.
/// @return The second node connected to the given edge.
- NodeId getEdgeNode2(EdgeId eId) {
- return getEdge(eId).getNode2();
+ NodeId getEdgeNode2Id(EdgeId EId) {
+ return getEdge(EId).getN2Id();
}
/// \brief Get the "other" node connected to this edge.
- /// @param eId Edge id.
- /// @param nId Node id for the "given" node.
+ /// @param EId Edge id.
+ /// @param NId Node id for the "given" node.
/// @return The iterator for the "other" node connected to this edge.
- NodeId getEdgeOtherNode(EdgeId eId, NodeId nId) {
- EdgeEntry &e = getEdge(eId);
- if (e.getNode1() == nId) {
- return e.getNode2();
+ NodeId getEdgeOtherNodeId(EdgeId EId, NodeId NId) {
+ EdgeEntry &E = getEdge(EId);
+ if (E.getN1Id() == NId) {
+ return E.getN2Id();
} // else
- return e.getNode1();
- }
-
- EdgeId invalidEdgeId() const {
- return std::numeric_limits<EdgeId>::max();
+ return E.getN1Id();
}
/// \brief Get the edge connecting two nodes.
- /// @param n1Id First node id.
- /// @param n2Id Second node id.
- /// @return An id for edge (n1Id, n2Id) if such an edge exists,
+ /// @param N1Id First node id.
+ /// @param N2Id Second node id.
+ /// @return An id for edge (N1Id, N2Id) if such an edge exists,
/// otherwise returns an invalid edge id.
- EdgeId findEdge(NodeId n1Id, NodeId n2Id) {
- for (AdjEdgeItr aeItr = adjEdgesBegin(n1Id), aeEnd = adjEdgesEnd(n1Id);
- aeItr != aeEnd; ++aeItr) {
- if ((getEdgeNode1(*aeItr) == n2Id) ||
- (getEdgeNode2(*aeItr) == n2Id)) {
- return *aeItr;
+ EdgeId findEdge(NodeId N1Id, NodeId N2Id) {
+ for (auto AEId : adjEdgeIds(N1Id)) {
+ if ((getEdgeNode1Id(AEId) == N2Id) ||
+ (getEdgeNode2Id(AEId) == N2Id)) {
+ return AEId;
}
}
return invalidEdgeId();
}
/// \brief Remove a node from the graph.
- /// @param nId Node id.
- void removeNode(NodeId nId) {
- NodeEntry &n = getNode(nId);
- for (AdjEdgeItr itr = n.edgesBegin(), end = n.edgesEnd(); itr != end; ++itr) {
- EdgeId eId = *itr;
- removeEdge(eId);
+ /// @param NId Node id.
+ void removeNode(NodeId NId) {
+ if (Solver)
+ Solver->handleRemoveNode(NId);
+ NodeEntry &N = getNode(NId);
+ // TODO: Can this be for-each'd?
+ for (AdjEdgeItr AEItr = N.adjEdgesBegin(),
+ AEEnd = N.adjEdgesEnd();
+ AEItr != AEEnd;) {
+ EdgeId EId = *AEItr;
+ ++AEItr;
+ removeEdge(EId);
}
- freeNodes.push_back(nId);
+ FreeNodeIds.push_back(NId);
+ }
+
+ /// \brief Disconnect an edge from the given node.
+ ///
+ /// Removes the given edge from the adjacency list of the given node.
+ /// This operation leaves the edge in an 'asymmetric' state: It will no
+ /// longer appear in an iteration over the given node's (NId's) edges, but
+ /// will appear in an iteration over the 'other', unnamed node's edges.
+ ///
+ /// This does not correspond to any normal graph operation, but exists to
+ /// support efficient PBQP graph-reduction based solvers. It is used to
+ /// 'effectively' remove the unnamed node from the graph while the solver
+ /// is performing the reduction. The solver will later call reconnectNode
+ /// to restore the edge in the named node's adjacency list.
+ ///
+ /// Since the degree of a node is the number of connected edges,
+ /// disconnecting an edge from a node 'u' will cause the degree of 'u' to
+ /// drop by 1.
+ ///
+ /// A disconnected edge WILL still appear in an iteration over the graph
+ /// edges.
+ ///
+ /// A disconnected edge should not be removed from the graph, it should be
+ /// reconnected first.
+ ///
+ /// A disconnected edge can be reconnected by calling the reconnectEdge
+ /// method.
+ void disconnectEdge(EdgeId EId, NodeId NId) {
+ if (Solver)
+ Solver->handleDisconnectEdge(EId, NId);
+
+ EdgeEntry &E = getEdge(EId);
+ E.disconnectFrom(*this, NId);
+ }
+
+ /// \brief Convenience method to disconnect all neighbours from the given
+ /// node.
+ void disconnectAllNeighborsFromNode(NodeId NId) {
+ for (auto AEId : adjEdgeIds(NId))
+ disconnectEdge(AEId, getEdgeOtherNodeId(AEId, NId));
+ }
+
+ /// \brief Re-attach an edge to its nodes.
+ ///
+ /// Adds an edge that had been previously disconnected back into the
+ /// adjacency set of the nodes that the edge connects.
+ void reconnectEdge(EdgeId EId, NodeId NId) {
+ EdgeEntry &E = getEdge(EId);
+ E.connectTo(*this, EId, NId);
+ if (Solver)
+ Solver->handleReconnectEdge(EId, NId);
}
/// \brief Remove an edge from the graph.
- /// @param eId Edge id.
- void removeEdge(EdgeId eId) {
- EdgeEntry &e = getEdge(eId);
- NodeEntry &n1 = getNode(e.getNode1());
- NodeEntry &n2 = getNode(e.getNode2());
- n1.removeEdge(e.getNode1AEItr());
- n2.removeEdge(e.getNode2AEItr());
- freeEdges.push_back(eId);
+ /// @param EId Edge id.
+ void removeEdge(EdgeId EId) {
+ if (Solver)
+ Solver->handleRemoveEdge(EId);
+ EdgeEntry &E = getEdge(EId);
+ E.disconnect();
+ FreeEdgeIds.push_back(EId);
+ Edges[EId].invalidate();
}
/// \brief Remove all nodes and edges from the graph.
void clear() {
- nodes.clear();
- freeNodes.clear();
- edges.clear();
- freeEdges.clear();
+ Nodes.clear();
+ FreeNodeIds.clear();
+ Edges.clear();
+ FreeEdgeIds.clear();
}
/// \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];
+ void dump(OStream &OS) {
+ OS << nodeIds().size() << " " << edgeIds().size() << "\n";
+
+ for (auto NId : nodeIds()) {
+ const Vector& V = getNodeCosts(NId);
+ 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";
+ OS << "\n";
}
- for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
- NodeId n1 = getEdgeNode1(*edgeItr);
- NodeId n2 = 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];
+ for (auto EId : edgeIds()) {
+ NodeId N1Id = getEdgeNode1Id(EId);
+ NodeId N2Id = getEdgeNode2Id(EId);
+ assert(N1Id != N2Id && "PBQP graphs shound not have self-edges.");
+ const Matrix& M = getEdgeCosts(EId);
+ OS << "\n" << N1Id << " " << N2Id << "\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";
+ OS << "\n";
}
}
}
/// \brief Print a representation of this graph in DOT format.
- /// @param os Output stream to print on.
+ /// @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";
+ void printDot(OStream &OS) {
+ OS << "graph {\n";
+ for (auto NId : nodeIds()) {
+ OS << " node" << NId << " [ label=\""
+ << NId << ": " << getNodeCosts(NId) << "\" ]\n";
}
-
- os << " edge [ len=" << getNumNodes() << " ]\n";
-
- for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
- edgeItr != edgeEnd; ++edgeItr) {
-
- os << " node" << getEdgeNode1(*edgeItr)
- << " -- node" << getEdgeNode2(*edgeItr)
+ OS << " edge [ len=" << nodeIds().size() << " ]\n";
+ for (auto EId : edgeIds()) {
+ OS << " node" << getEdgeNode1Id(EId)
+ << " -- node" << getEdgeNode2Id(EId)
<< " [ label=\"";
-
- const Matrix &edgeCosts = getEdgeCosts(*edgeItr);
-
- for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
- os << edgeCosts.getRowAsVector(i) << "\\n";
+ const Matrix &EdgeCosts = getEdgeCosts(EId);
+ for (unsigned i = 0; i < EdgeCosts.getRows(); ++i) {
+ OS << EdgeCosts.getRowAsVector(i) << "\\n";
}
- os << "\" ]\n";
+ OS << "\" ]\n";
}
- os << "}\n";
+ OS << "}\n";
}
-
};
-// 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/include/llvm/CodeGen/PBQP/HeuristicBase.h b/include/llvm/CodeGen/PBQP/HeuristicBase.h
deleted file mode 100644
index 8bcbb9e..0000000
--- a/include/llvm/CodeGen/PBQP/HeuristicBase.h
+++ /dev/null
@@ -1,247 +0,0 @@
-//===-- 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::NodeId> 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::NodeId nId) {
- optimalList.insert(optimalList.end(), nId);
- }
-
- 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::NodeId nId) {
- if (g.getNodeDegree(nId) < 3)
- return true;
- // else
- return false;
- }
-
- /// \brief Add the given node to the list of nodes to be optimally reduced.
- /// @param nId Node id 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::NodeId nId) {
- optimalList.push_back(nId);
- }
-
- /// \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::NodeId nId = optimalList.front();
- optimalList.pop_front();
-
- switch (s.getSolverDegree(nId)) {
- case 0: s.applyR0(nId); break;
- case 1: s.applyR1(nId); break;
- case 2: s.applyR2(nId); 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 nId Node id to add to the heuristic reduce list.
- void addToHeuristicList(Graph::NodeId nId) {
- 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.
- bool heuristicReduce() {
- llvm_unreachable("Must be implemented in derived class.");
- return false;
- }
-
- /// \brief Prepare a change in the costs on the given edge.
- /// @param eId Edge id.
- void preUpdateEdgeCosts(Graph::EdgeId eId) {
- llvm_unreachable("Must be implemented in derived class.");
- }
-
- /// \brief Handle the change in the costs on the given edge.
- /// @param eId Edge id.
- void postUpdateEdgeCostts(Graph::EdgeId eId) {
- llvm_unreachable("Must be implemented in derived class.");
- }
-
- /// \brief Handle the addition of a new edge into the PBQP graph.
- /// @param eId Edge id for the added edge.
- void handleAddEdge(Graph::EdgeId eId) {
- llvm_unreachable("Must be implemented in derived class.");
- }
-
- /// \brief Handle disconnection of an edge from a node.
- /// @param eId Edge id for edge being disconnected.
- /// @param nId Node id 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::EdgeId eId, Graph::NodeId nId) {
- 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/include/llvm/CodeGen/PBQP/HeuristicSolver.h b/include/llvm/CodeGen/PBQP/HeuristicSolver.h
deleted file mode 100644
index e26ca02..0000000
--- a/include/llvm/CodeGen/PBQP/HeuristicSolver.h
+++ /dev/null
@@ -1,618 +0,0 @@
-//===-- 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 <limits>
-#include <vector>
-
-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::EdgeId> 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::EdgeId eId) {
- ++solverDegree;
- return solverEdges.insert(solverEdges.end(), eId);
- }
-
- 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::NodeId> 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 nId Node id.
- /// @return The heuristic data attached to the given node.
- HeuristicNodeData& getHeuristicNodeData(Graph::NodeId nId) {
- return getSolverNodeData(nId).getHeuristicData();
- }
-
- /// \brief Get the heuristic data attached to the given edge.
- /// @param eId Edge id.
- /// @return The heuristic data attached to the given node.
- HeuristicEdgeData& getHeuristicEdgeData(Graph::EdgeId eId) {
- return getSolverEdgeData(eId).getHeuristicData();
- }
-
- /// \brief Begin iterator for the set of edges adjacent to the given node in
- /// the solver graph.
- /// @param nId Node id.
- /// @return Begin iterator for the set of edges adjacent to the given node
- /// in the solver graph.
- SolverEdgeItr solverEdgesBegin(Graph::NodeId nId) {
- return getSolverNodeData(nId).solverEdgesBegin();
- }
-
- /// \brief End iterator for the set of edges adjacent to the given node in
- /// the solver graph.
- /// @param nId Node id.
- /// @return End iterator for the set of edges adjacent to the given node in
- /// the solver graph.
- SolverEdgeItr solverEdgesEnd(Graph::NodeId nId) {
- return getSolverNodeData(nId).solverEdgesEnd();
- }
-
- /// \brief Remove a node from the solver graph.
- /// @param eId Edge id 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::EdgeId eId) {
- EdgeData &eData = getSolverEdgeData(eId);
- NodeData &n1Data = getSolverNodeData(g.getEdgeNode1(eId)),
- &n2Data = getSolverNodeData(g.getEdgeNode2(eId));
-
- 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 nId Node id to add to the reduction stack.
- void pushToStack(Graph::NodeId nId) {
- getSolverNodeData(nId).clearSolverEdges();
- stack.push_back(nId);
- }
-
- /// \brief Returns the solver degree of the given node.
- /// @param nId Node id for which degree is requested.
- /// @return Node degree in the <i>solver</i> graph (not the original graph).
- unsigned getSolverDegree(Graph::NodeId nId) {
- return getSolverNodeData(nId).getSolverDegree();
- }
-
- /// \brief Set the solution of the given node.
- /// @param nId Node id to set solution for.
- /// @param selection Selection for node.
- void setSolution(const Graph::NodeId &nId, unsigned selection) {
- s.setSelection(nId, selection);
-
- for (Graph::AdjEdgeItr aeItr = g.adjEdgesBegin(nId),
- aeEnd = g.adjEdgesEnd(nId);
- aeItr != aeEnd; ++aeItr) {
- Graph::EdgeId eId(*aeItr);
- Graph::NodeId anId(g.getEdgeOtherNode(eId, nId));
- getSolverNodeData(anId).addSolverEdge(eId);
- }
- }
-
- /// \brief Apply rule R0.
- /// @param nId Node id for node to apply R0 to.
- ///
- /// Node will be automatically pushed to the solver stack.
- void applyR0(Graph::NodeId nId) {
- assert(getSolverNodeData(nId).getSolverDegree() == 0 &&
- "R0 applied to node with degree != 0.");
-
- // Nothing to do. Just push the node onto the reduction stack.
- pushToStack(nId);
-
- s.recordR0();
- }
-
- /// \brief Apply rule R1.
- /// @param xnId Node id for node to apply R1 to.
- ///
- /// Node will be automatically pushed to the solver stack.
- void applyR1(Graph::NodeId xnId) {
- NodeData &nd = getSolverNodeData(xnId);
- assert(nd.getSolverDegree() == 1 &&
- "R1 applied to node with degree != 1.");
-
- Graph::EdgeId eId = *nd.solverEdgesBegin();
-
- const Matrix &eCosts = g.getEdgeCosts(eId);
- const Vector &xCosts = g.getNodeCosts(xnId);
-
- // Duplicate a little to avoid transposing matrices.
- if (xnId == g.getEdgeNode1(eId)) {
- Graph::NodeId ynId = g.getEdgeNode2(eId);
- Vector &yCosts = g.getNodeCosts(ynId);
- 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(eId, ynId);
- } else {
- Graph::NodeId ynId = g.getEdgeNode1(eId);
- Vector &yCosts = g.getNodeCosts(ynId);
- 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(eId, ynId);
- }
- removeSolverEdge(eId);
- assert(nd.getSolverDegree() == 0 &&
- "Degree 1 with edge removed should be 0.");
- pushToStack(xnId);
- s.recordR1();
- }
-
- /// \brief Apply rule R2.
- /// @param xnId Node id for node to apply R2 to.
- ///
- /// Node will be automatically pushed to the solver stack.
- void applyR2(Graph::NodeId xnId) {
- assert(getSolverNodeData(xnId).getSolverDegree() == 2 &&
- "R2 applied to node with degree != 2.");
-
- NodeData &nd = getSolverNodeData(xnId);
- const Vector &xCosts = g.getNodeCosts(xnId);
-
- SolverEdgeItr aeItr = nd.solverEdgesBegin();
- Graph::EdgeId yxeId = *aeItr,
- zxeId = *(++aeItr);
-
- Graph::NodeId ynId = g.getEdgeOtherNode(yxeId, xnId),
- znId = g.getEdgeOtherNode(zxeId, xnId);
-
- bool flipEdge1 = (g.getEdgeNode1(yxeId) == xnId),
- flipEdge2 = (g.getEdgeNode1(zxeId) == xnId);
-
- const Matrix *yxeCosts = flipEdge1 ?
- new Matrix(g.getEdgeCosts(yxeId).transpose()) :
- &g.getEdgeCosts(yxeId);
-
- const Matrix *zxeCosts = flipEdge2 ?
- new Matrix(g.getEdgeCosts(zxeId).transpose()) :
- &g.getEdgeCosts(zxeId);
-
- 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::EdgeId yzeId = g.findEdge(ynId, znId);
- bool addedEdge = false;
-
- if (yzeId == g.invalidEdgeId()) {
- yzeId = g.addEdge(ynId, znId, delta);
- addedEdge = true;
- } else {
- Matrix &yzeCosts = g.getEdgeCosts(yzeId);
- h.preUpdateEdgeCosts(yzeId);
- if (ynId == g.getEdgeNode1(yzeId)) {
- yzeCosts += delta;
- } else {
- yzeCosts += delta.transpose();
- }
- }
-
- bool nullCostEdge = tryNormaliseEdgeMatrix(yzeId);
-
- if (!addedEdge) {
- // If we modified the edge costs let the heuristic know.
- h.postUpdateEdgeCosts(yzeId);
- }
-
- 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(yzeId, ynId);
- h.handleRemoveEdge(yzeId, znId);
- removeSolverEdge(yzeId);
- }
- g.removeEdge(yzeId);
- } 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(yzeId, &edgeDataList.back());
- addSolverEdge(yzeId);
- h.handleAddEdge(yzeId);
- }
-
- h.handleRemoveEdge(yxeId, ynId);
- removeSolverEdge(yxeId);
- h.handleRemoveEdge(zxeId, znId);
- removeSolverEdge(zxeId);
-
- pushToStack(xnId);
- s.recordR2();
- }
-
- /// \brief Record an application of the RN rule.
- ///
- /// For use by the HeuristicBase.
- void recordRN() { s.recordRN(); }
-
- private:
-
- NodeData& getSolverNodeData(Graph::NodeId nId) {
- return *static_cast<NodeData*>(g.getNodeData(nId));
- }
-
- EdgeData& getSolverEdgeData(Graph::EdgeId eId) {
- return *static_cast<EdgeData*>(g.getEdgeData(eId));
- }
-
- void addSolverEdge(Graph::EdgeId eId) {
- EdgeData &eData = getSolverEdgeData(eId);
- NodeData &n1Data = getSolverNodeData(g.getEdgeNode1(eId)),
- &n2Data = getSolverNodeData(g.getEdgeNode2(eId));
-
- eData.setN1SolverEdgeItr(n1Data.addSolverEdge(eId));
- eData.setN2SolverEdgeItr(n2Data.addSolverEdge(eId));
- }
-
- 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) {
-
- Graph::NodeId nId = *nItr;
-
- if (g.getNodeCosts(nId).getLength() == 1) {
-
- std::vector<Graph::EdgeId> edgesToRemove;
-
- for (Graph::AdjEdgeItr aeItr = g.adjEdgesBegin(nId),
- aeEnd = g.adjEdgesEnd(nId);
- aeItr != aeEnd; ++aeItr) {
-
- Graph::EdgeId eId = *aeItr;
-
- if (g.getEdgeNode1(eId) == nId) {
- Graph::NodeId otherNodeId = g.getEdgeNode2(eId);
- g.getNodeCosts(otherNodeId) +=
- g.getEdgeCosts(eId).getRowAsVector(0);
- }
- else {
- Graph::NodeId otherNodeId = g.getEdgeNode1(eId);
- g.getNodeCosts(otherNodeId) +=
- g.getEdgeCosts(eId).getColAsVector(0);
- }
-
- edgesToRemove.push_back(eId);
- }
-
- if (!edgesToRemove.empty())
- ++numDisconnected;
-
- while (!edgesToRemove.empty()) {
- g.removeEdge(edgesToRemove.back());
- edgesToRemove.pop_back();
- }
- }
- }
- }
-
- void eliminateIndependentEdges() {
- std::vector<Graph::EdgeId> 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::EdgeId eId) {
- if (tryNormaliseEdgeMatrix(eId)) {
- g.removeEdge(eId);
- return true;
- }
- return false;
- }
-
- bool tryNormaliseEdgeMatrix(Graph::EdgeId &eId) {
-
- const PBQPNum infinity = std::numeric_limits<PBQPNum>::infinity();
-
- Matrix &edgeCosts = g.getEdgeCosts(eId);
- Vector &uCosts = g.getNodeCosts(g.getEdgeNode1(eId)),
- &vCosts = g.getNodeCosts(g.getEdgeNode2(eId));
-
- 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::NodeId nId) {
-
- NodeData &nodeData = getSolverNodeData(nId);
-
- Vector v(g.getNodeCosts(nId));
-
- // Solve based on existing solved edges.
- for (SolverEdgeItr solvedEdgeItr = nodeData.solverEdgesBegin(),
- solvedEdgeEnd = nodeData.solverEdgesEnd();
- solvedEdgeItr != solvedEdgeEnd; ++solvedEdgeItr) {
-
- Graph::EdgeId eId(*solvedEdgeItr);
- Matrix &edgeCosts = g.getEdgeCosts(eId);
-
- if (nId == g.getEdgeNode1(eId)) {
- Graph::NodeId adjNode(g.getEdgeNode2(eId));
- unsigned adjSolution = s.getSelection(adjNode);
- v += edgeCosts.getColAsVector(adjSolution);
- }
- else {
- Graph::NodeId adjNode(g.getEdgeNode1(eId));
- unsigned adjSolution = s.getSelection(adjNode);
- v += edgeCosts.getRowAsVector(adjSolution);
- }
-
- }
-
- setSolution(nId, 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/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
deleted file mode 100644
index c355c2c..0000000
--- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h
+++ /dev/null
@@ -1,468 +0,0 @@
-//===-- 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 "../HeuristicBase.h"
-#include "../HeuristicSolver.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::NodeId n1Id, Graph::NodeId n2Id) const {
- if (s->getSolverDegree(n1Id) > s->getSolverDegree(n2Id))
- return true;
- return false;
- }
- private:
- HeuristicSolverImpl<Briggs> *s;
- };
-
- class SpillCostComparator {
- public:
- SpillCostComparator(HeuristicSolverImpl<Briggs> &s)
- : s(&s), g(&s.getGraph()) {}
- bool operator()(Graph::NodeId n1Id, Graph::NodeId n2Id) const {
- const PBQP::Vector &cv1 = g->getNodeCosts(n1Id);
- const PBQP::Vector &cv2 = g->getNodeCosts(n2Id);
-
- PBQPNum cost1 = cv1[0] / s->getSolverDegree(n1Id);
- PBQPNum cost2 = cv2[0] / s->getSolverDegree(n2Id);
-
- if (cost1 < cost2)
- return true;
- return false;
- }
-
- private:
- HeuristicSolverImpl<Briggs> *s;
- Graph *g;
- };
-
- typedef std::list<Graph::NodeId> RNAllocableList;
- typedef RNAllocableList::iterator RNAllocableListItr;
-
- typedef std::list<Graph::NodeId> 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 nId Node id 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::NodeId nId) {
- if (getSolver().getSolverDegree(nId) < 3) {
- return true;
- }
- // else
- return false;
- }
-
- /// \brief Add a node to the heuristic reduce list.
- /// @param nId Node id to add to the heuristic reduce list.
- void addToHeuristicReduceList(Graph::NodeId nId) {
- NodeData &nd = getHeuristicNodeData(nId);
- initializeNode(nId);
- nd.isHeuristic = true;
- if (nd.isAllocable) {
- nd.rnaItr = rnAllocableList.insert(rnAllocableList.end(), nId);
- } else {
- nd.rnuItr = rnUnallocableList.insert(rnUnallocableList.end(), nId);
- }
- }
-
- /// \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::NodeId nId = *rnaItr;
- rnAllocableList.erase(rnaItr);
- handleRemoveNode(nId);
- getSolver().pushToStack(nId);
- return true;
- } else if (!rnUnallocableList.empty()) {
- RNUnallocableListItr rnuItr =
- min_element(rnUnallocableList.begin(), rnUnallocableList.end(),
- SpillCostComparator(getSolver()));
- Graph::NodeId nId = *rnuItr;
- rnUnallocableList.erase(rnuItr);
- handleRemoveNode(nId);
- getSolver().pushToStack(nId);
- return true;
- }
- // else
- return false;
- }
-
- /// \brief Prepare a change in the costs on the given edge.
- /// @param eId Edge id.
- void preUpdateEdgeCosts(Graph::EdgeId eId) {
- Graph &g = getGraph();
- Graph::NodeId n1Id = g.getEdgeNode1(eId),
- n2Id = g.getEdgeNode2(eId);
- NodeData &n1 = getHeuristicNodeData(n1Id),
- &n2 = getHeuristicNodeData(n2Id);
-
- if (n1.isHeuristic)
- subtractEdgeContributions(eId, getGraph().getEdgeNode1(eId));
- if (n2.isHeuristic)
- subtractEdgeContributions(eId, getGraph().getEdgeNode2(eId));
-
- EdgeData &ed = getHeuristicEdgeData(eId);
- ed.isUpToDate = false;
- }
-
- /// \brief Handle the change in the costs on the given edge.
- /// @param eId Edge id.
- void postUpdateEdgeCosts(Graph::EdgeId eId) {
- // This is effectively the same as adding a new edge now, since
- // we've factored out the costs of the old one.
- handleAddEdge(eId);
- }
-
- /// \brief Handle the addition of a new edge into the PBQP graph.
- /// @param eId Edge id 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::EdgeId eId) {
- Graph &g = getGraph();
- Graph::NodeId n1Id = g.getEdgeNode1(eId),
- n2Id = g.getEdgeNode2(eId);
- NodeData &n1 = getHeuristicNodeData(n1Id),
- &n2 = getHeuristicNodeData(n2Id);
-
- // 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(eId);
-
- // Update node 1 if it's managed by the heuristic.
- if (n1.isHeuristic) {
- bool n1WasAllocable = n1.isAllocable;
- addEdgeContributions(eId, n1Id);
- updateAllocability(n1Id);
- if (n1WasAllocable && !n1.isAllocable) {
- rnAllocableList.erase(n1.rnaItr);
- n1.rnuItr =
- rnUnallocableList.insert(rnUnallocableList.end(), n1Id);
- }
- }
-
- // Likewise for node 2.
- if (n2.isHeuristic) {
- bool n2WasAllocable = n2.isAllocable;
- addEdgeContributions(eId, n2Id);
- updateAllocability(n2Id);
- if (n2WasAllocable && !n2.isAllocable) {
- rnAllocableList.erase(n2.rnaItr);
- n2.rnuItr =
- rnUnallocableList.insert(rnUnallocableList.end(), n2Id);
- }
- }
- }
-
- /// \brief Handle disconnection of an edge from a node.
- /// @param eId Edge id for edge being disconnected.
- /// @param nId Node id 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::EdgeId eId, Graph::NodeId nId) {
- NodeData &nd =getHeuristicNodeData(nId);
-
- // If the node is not managed by the heuristic there's nothing to be
- // done.
- if (!nd.isHeuristic)
- return;
-
- EdgeData &ed = getHeuristicEdgeData(eId);
- (void)ed;
- assert(ed.isUpToDate && "Edge data is not up to date.");
-
- // Update node.
- bool ndWasAllocable = nd.isAllocable;
- subtractEdgeContributions(eId, nId);
- updateAllocability(nId);
-
- // If the node has gone optimal...
- if (shouldOptimallyReduce(nId)) {
- nd.isHeuristic = false;
- addToOptimalReduceList(nId);
- 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(), nId);
- }
- }
- }
-
- private:
-
- NodeData& getHeuristicNodeData(Graph::NodeId nId) {
- return getSolver().getHeuristicNodeData(nId);
- }
-
- EdgeData& getHeuristicEdgeData(Graph::EdgeId eId) {
- return getSolver().getHeuristicEdgeData(eId);
- }
-
- // Work out what this edge will contribute to the allocability of the
- // nodes connected to it.
- void computeEdgeContributions(Graph::EdgeId eId) {
- EdgeData &ed = getHeuristicEdgeData(eId);
-
- if (ed.isUpToDate)
- return; // Edge data is already up to date.
-
- Matrix &eCosts = getGraph().getEdgeCosts(eId);
-
- 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::EdgeId eId, Graph::NodeId nId) {
- EdgeData &ed = getHeuristicEdgeData(eId);
-
- assert(ed.isUpToDate && "Using out-of-date edge numbers.");
-
- NodeData &nd = getHeuristicNodeData(nId);
- unsigned numRegs = getGraph().getNodeCosts(nId).getLength() - 1;
-
- bool nIsNode1 = nId == getGraph().getEdgeNode1(eId);
- 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::EdgeId eId, Graph::NodeId nId) {
- EdgeData &ed = getHeuristicEdgeData(eId);
-
- assert(ed.isUpToDate && "Using out-of-date edge numbers.");
-
- NodeData &nd = getHeuristicNodeData(nId);
- unsigned numRegs = getGraph().getNodeCosts(nId).getLength() - 1;
-
- bool nIsNode1 = nId == getGraph().getEdgeNode1(eId);
- 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::NodeId nId) {
- NodeData &nd = getHeuristicNodeData(nId);
- unsigned numRegs = getGraph().getNodeCosts(nId).getLength() - 1;
- nd.isAllocable = nd.numDenied < numRegs || nd.numSafe > 0;
- }
-
- void initializeNode(Graph::NodeId nId) {
- NodeData &nd = getHeuristicNodeData(nId);
-
- if (nd.isInitialized)
- return; // Node data is already up to date.
-
- unsigned numRegs = getGraph().getNodeCosts(nId).getLength() - 1;
-
- nd.numDenied = 0;
- const Vector& nCosts = getGraph().getNodeCosts(nId);
- 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(nId),
- aeEnd = getSolver().solverEdgesEnd(nId);
- aeItr != aeEnd; ++aeItr) {
-
- Graph::EdgeId eId = *aeItr;
- computeEdgeContributions(eId);
- addEdgeContributions(eId, nId);
- }
-
- updateAllocability(nId);
- nd.isInitialized = true;
- }
-
- void handleRemoveNode(Graph::NodeId xnId) {
- typedef HeuristicSolverImpl<Briggs>::SolverEdgeItr SolverEdgeItr;
- std::vector<Graph::EdgeId> edgesToRemove;
- for (SolverEdgeItr aeItr = getSolver().solverEdgesBegin(xnId),
- aeEnd = getSolver().solverEdgesEnd(xnId);
- aeItr != aeEnd; ++aeItr) {
- Graph::NodeId ynId = getGraph().getEdgeOtherNode(*aeItr, xnId);
- handleRemoveEdge(*aeItr, ynId);
- 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/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h
index 08f8b98..69a9d83 100644
--- a/include/llvm/CodeGen/PBQP/Math.h
+++ b/include/llvm/CodeGen/PBQP/Math.h
@@ -20,268 +20,418 @@ 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;
+ friend class VectorComparator;
+public:
+
+ /// \brief Construct a PBQP vector of the given size.
+ explicit Vector(unsigned Length)
+ : Length(Length), Data(new PBQPNum[Length]) {
+ // llvm::dbgs() << "Constructing PBQP::Vector "
+ // << this << " (length " << Length << ")\n";
+ }
+
+ /// \brief Construct a PBQP vector with initializer.
+ Vector(unsigned Length, PBQPNum InitVal)
+ : Length(Length), Data(new PBQPNum[Length]) {
+ // llvm::dbgs() << "Constructing PBQP::Vector "
+ // << this << " (length " << Length << ", fill "
+ // << InitVal << ")\n";
+ std::fill(Data, Data + Length, InitVal);
+ }
+
+ /// \brief Copy construct a PBQP vector.
+ Vector(const Vector &V)
+ : Length(V.Length), Data(new PBQPNum[Length]) {
+ // llvm::dbgs() << "Copy-constructing PBQP::Vector " << this
+ // << " from PBQP::Vector " << &V << "\n";
+ std::copy(V.Data, V.Data + Length, Data);
+ }
+
+ /// \brief Move construct a PBQP vector.
+ Vector(Vector &&V)
+ : Length(V.Length), Data(V.Data) {
+ V.Length = 0;
+ V.Data = nullptr;
+ }
+
+ /// \brief Destroy this vector, return its memory.
+ ~Vector() {
+ // llvm::dbgs() << "Deleting PBQP::Vector " << this << "\n";
+ delete[] Data;
+ }
+
+ /// \brief Copy-assignment operator.
+ Vector& operator=(const Vector &V) {
+ // llvm::dbgs() << "Assigning to PBQP::Vector " << this
+ // << " from PBQP::Vector " << &V << "\n";
+ delete[] Data;
+ Length = V.Length;
+ Data = new PBQPNum[Length];
+ std::copy(V.Data, V.Data + Length, Data);
+ return *this;
+ }
+
+ /// \brief Move-assignment operator.
+ Vector& operator=(Vector &&V) {
+ delete[] Data;
+ Length = V.Length;
+ Data = V.Data;
+ V.Length = 0;
+ V.Data = nullptr;
+ return *this;
+ }
+
+ /// \brief Comparison operator.
+ bool operator==(const Vector &V) const {
+ assert(Length != 0 && Data != nullptr && "Invalid vector");
+ if (Length != V.Length)
+ return false;
+ return std::equal(Data, Data + Length, V.Data);
+ }
+
+ /// \brief Return the length of the vector
+ unsigned getLength() const {
+ assert(Length != 0 && Data != nullptr && "Invalid vector");
+ return Length;
+ }
+
+ /// \brief Element access.
+ PBQPNum& operator[](unsigned Index) {
+ assert(Length != 0 && Data != nullptr && "Invalid vector");
+ assert(Index < Length && "Vector element access out of bounds.");
+ return Data[Index];
+ }
+
+ /// \brief Const element access.
+ const PBQPNum& operator[](unsigned Index) const {
+ assert(Length != 0 && Data != nullptr && "Invalid vector");
+ 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 != 0 && Data != nullptr && "Invalid vector");
+ 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 != 0 && Data != nullptr && "Invalid vector");
+ 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 {
+ assert(Length != 0 && Data != nullptr && "Invalid vector");
+ return std::min_element(Data, Data + Length) - Data;
+ }
+
+private:
+ unsigned Length;
+ PBQPNum *Data;
+};
+
+class VectorComparator {
+public:
+ bool operator()(const Vector &A, const Vector &B) {
+ if (A.Length < B.Length)
+ return true;
+ if (B.Length < A.Length)
+ return false;
+ char *AData = reinterpret_cast<char*>(A.Data);
+ char *BData = reinterpret_cast<char*>(B.Data);
+ return std::lexicographical_compare(AData,
+ AData + A.Length * sizeof(PBQPNum),
+ BData,
+ BData + A.Length * sizeof(PBQPNum));
+ }
};
/// \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.");
+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 << " ]";
+ OS << "[ " << V[0];
+ for (unsigned i = 1; i < V.getLength(); ++i)
+ OS << ", " << V[i];
+ OS << " ]";
- return 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;
+private:
+ friend class MatrixComparator;
+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 Move construct a PBQP matrix.
+ Matrix(Matrix &&M)
+ : Rows(M.Rows), Cols(M.Cols), Data(M.Data) {
+ M.Rows = M.Cols = 0;
+ M.Data = nullptr;
+ }
+
+ /// \brief Destroy this matrix, return its memory.
+ ~Matrix() { delete[] Data; }
+
+ /// \brief Copy-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 Move-assignment operator.
+ Matrix& operator=(Matrix &&M) {
+ delete[] Data;
+ Rows = M.Rows;
+ Cols = M.Cols;
+ Data = M.Data;
+ M.Rows = M.Cols = 0;
+ M.Data = nullptr;
+ return *this;
+ }
+
+ /// \brief Comparison operator.
+ bool operator==(const Matrix &M) const {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ if (Rows != M.Rows || Cols != M.Cols)
+ return false;
+ return std::equal(Data, Data + (Rows * Cols), M.Data);
+ }
+
+ /// \brief Return the number of rows in this matrix.
+ unsigned getRows() const {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ return Rows;
+ }
+
+ /// \brief Return the number of cols in this matrix.
+ unsigned getCols() const {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ return Cols;
+ }
+
+ /// \brief Matrix element access.
+ PBQPNum* operator[](unsigned R) {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ assert(R < Rows && "Row out of bounds.");
+ return Data + (R * Cols);
+ }
+
+ /// \brief Matrix element access.
+ const PBQPNum* operator[](unsigned R) const {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ assert(R < Rows && "Row out of bounds.");
+ return Data + (R * Cols);
+ }
+
+ /// \brief Returns the given row as a vector.
+ Vector getRowAsVector(unsigned R) const {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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 {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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) {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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 {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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 != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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 != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ assert(Rows == M.Rows && Cols == M.Cols &&
+ "Matrix dimensions mismatch.");
+ std::transform(Data, Data + (Rows * Cols), M.Data, Data,
+ std::plus<PBQPNum>());
+ return *this;
+ }
+
+ Matrix operator+(const Matrix &M) {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ Matrix Tmp(*this);
+ Tmp += M;
+ return Tmp;
+ }
+
+ /// \brief Returns the minimum of the given row
+ PBQPNum getRowMin(unsigned R) const {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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 {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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) {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ 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 {
+ assert(Rows != 0 && Cols != 0 && Data != nullptr && "Invalid matrix");
+ return find_if(Data, Data + (Rows * Cols),
+ std::bind2nd(std::not_equal_to<PBQPNum>(), 0)) ==
+ Data + (Rows * Cols);
+ }
+
+private:
+ unsigned Rows, Cols;
+ PBQPNum *Data;
+};
+
+class MatrixComparator {
+public:
+ bool operator()(const Matrix &A, const Matrix &B) {
+ if (A.Rows < B.Rows)
+ return true;
+ if (B.Rows < A.Rows)
+ return false;
+ if (A.Cols < B.Cols)
+ return true;
+ if (B.Cols < A.Cols)
+ return false;
+ char *AData = reinterpret_cast<char*>(A.Data);
+ char *BData = reinterpret_cast<char*>(B.Data);
+ return std::lexicographical_compare(
+ AData, AData + (A.Rows * A.Cols * sizeof(PBQPNum)),
+ BData, BData + (A.Rows * A.Cols * sizeof(PBQPNum)));
+ }
};
/// \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.");
+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;
+}
- for (unsigned i = 0; i < m.getRows(); ++i) {
- os << m.getRowAsVector(i);
- }
+template <typename Metadata>
+class MDVector : public Vector {
+public:
+ MDVector(const Vector &v) : Vector(v), md(*this) { }
+ MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
+ const Metadata& getMetadata() const { return md; }
+private:
+ Metadata md;
+};
- return os;
-}
+template <typename Metadata>
+class MDMatrix : public Matrix {
+public:
+ MDMatrix(const Matrix &m) : Matrix(m), md(*this) { }
+ MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
+ const Metadata& getMetadata() const { return md; }
+private:
+ Metadata md;
+};
}
diff --git a/include/llvm/CodeGen/PBQP/ReductionRules.h b/include/llvm/CodeGen/PBQP/ReductionRules.h
new file mode 100644
index 0000000..a55a060
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/ReductionRules.h
@@ -0,0 +1,191 @@
+//===----------- ReductionRules.h - Reduction Rules -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Reduction Rules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REDUCTIONRULES_H
+#define LLVM_REDUCTIONRULES_H
+
+#include "Graph.h"
+#include "Math.h"
+#include "Solution.h"
+
+namespace PBQP {
+
+ /// \brief Reduce a node of degree one.
+ ///
+ /// Propagate costs from the given node, which must be of degree one, to its
+ /// neighbor. Notify the problem domain.
+ template <typename GraphT>
+ void applyR1(GraphT &G, typename GraphT::NodeId NId) {
+ typedef typename GraphT::NodeId NodeId;
+ typedef typename GraphT::EdgeId EdgeId;
+ typedef typename GraphT::Vector Vector;
+ typedef typename GraphT::Matrix Matrix;
+ typedef typename GraphT::RawVector RawVector;
+
+ assert(G.getNodeDegree(NId) == 1 &&
+ "R1 applied to node with degree != 1.");
+
+ EdgeId EId = *G.adjEdgeIds(NId).begin();
+ NodeId MId = G.getEdgeOtherNodeId(EId, NId);
+
+ const Matrix &ECosts = G.getEdgeCosts(EId);
+ const Vector &XCosts = G.getNodeCosts(NId);
+ RawVector YCosts = G.getNodeCosts(MId);
+
+ // Duplicate a little to avoid transposing matrices.
+ if (NId == G.getEdgeNode1Id(EId)) {
+ 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;
+ }
+ } else {
+ 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;
+ }
+ }
+ G.setNodeCosts(MId, YCosts);
+ G.disconnectEdge(EId, MId);
+ }
+
+ template <typename GraphT>
+ void applyR2(GraphT &G, typename GraphT::NodeId NId) {
+ typedef typename GraphT::NodeId NodeId;
+ typedef typename GraphT::EdgeId EdgeId;
+ typedef typename GraphT::Vector Vector;
+ typedef typename GraphT::Matrix Matrix;
+ typedef typename GraphT::RawMatrix RawMatrix;
+
+ assert(G.getNodeDegree(NId) == 2 &&
+ "R2 applied to node with degree != 2.");
+
+ const Vector &XCosts = G.getNodeCosts(NId);
+
+ typename GraphT::AdjEdgeItr AEItr = G.adjEdgeIds(NId).begin();
+ EdgeId YXEId = *AEItr,
+ ZXEId = *(++AEItr);
+
+ NodeId YNId = G.getEdgeOtherNodeId(YXEId, NId),
+ ZNId = G.getEdgeOtherNodeId(ZXEId, NId);
+
+ bool FlipEdge1 = (G.getEdgeNode1Id(YXEId) == NId),
+ FlipEdge2 = (G.getEdgeNode1Id(ZXEId) == NId);
+
+ const Matrix *YXECosts = FlipEdge1 ?
+ new Matrix(G.getEdgeCosts(YXEId).transpose()) :
+ &G.getEdgeCosts(YXEId);
+
+ const Matrix *ZXECosts = FlipEdge2 ?
+ new Matrix(G.getEdgeCosts(ZXEId).transpose()) :
+ &G.getEdgeCosts(ZXEId);
+
+ unsigned XLen = XCosts.getLength(),
+ YLen = YXECosts->getRows(),
+ ZLen = ZXECosts->getRows();
+
+ RawMatrix 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;
+
+ EdgeId YZEId = G.findEdge(YNId, ZNId);
+
+ if (YZEId == G.invalidEdgeId()) {
+ YZEId = G.addEdge(YNId, ZNId, Delta);
+ } else {
+ const Matrix &YZECosts = G.getEdgeCosts(YZEId);
+ if (YNId == G.getEdgeNode1Id(YZEId)) {
+ G.setEdgeCosts(YZEId, Delta + YZECosts);
+ } else {
+ G.setEdgeCosts(YZEId, Delta.transpose() + YZECosts);
+ }
+ }
+
+ G.disconnectEdge(YXEId, YNId);
+ G.disconnectEdge(ZXEId, ZNId);
+
+ // TODO: Try to normalize newly added/modified edge.
+ }
+
+
+ // \brief Find a solution to a fully reduced graph by backpropagation.
+ //
+ // Given a graph and a reduction order, pop each node from the reduction
+ // order and greedily compute a minimum solution based on the node costs, and
+ // the dependent costs due to previously solved nodes.
+ //
+ // Note - This does not return the graph to its original (pre-reduction)
+ // state: the existing solvers destructively alter the node and edge
+ // costs. Given that, the backpropagate function doesn't attempt to
+ // replace the edges either, but leaves the graph in its reduced
+ // state.
+ template <typename GraphT, typename StackT>
+ Solution backpropagate(GraphT& G, StackT stack) {
+ typedef GraphBase::NodeId NodeId;
+ typedef typename GraphT::Matrix Matrix;
+ typedef typename GraphT::RawVector RawVector;
+
+ Solution s;
+
+ while (!stack.empty()) {
+ NodeId NId = stack.back();
+ stack.pop_back();
+
+ RawVector v = G.getNodeCosts(NId);
+
+ for (auto EId : G.adjEdgeIds(NId)) {
+ const Matrix& edgeCosts = G.getEdgeCosts(EId);
+ if (NId == G.getEdgeNode1Id(EId)) {
+ NodeId mId = G.getEdgeNode2Id(EId);
+ v += edgeCosts.getColAsVector(s.getSelection(mId));
+ } else {
+ NodeId mId = G.getEdgeNode1Id(EId);
+ v += edgeCosts.getRowAsVector(s.getSelection(mId));
+ }
+ }
+
+ s.setSelection(NId, v.minIndex());
+ }
+
+ return s;
+ }
+
+}
+
+#endif // LLVM_REDUCTIONRULES_H
diff --git a/include/llvm/CodeGen/PBQP/RegAllocSolver.h b/include/llvm/CodeGen/PBQP/RegAllocSolver.h
new file mode 100644
index 0000000..79ff6b4
--- /dev/null
+++ b/include/llvm/CodeGen/PBQP/RegAllocSolver.h
@@ -0,0 +1,359 @@
+//===-- RegAllocSolver.h - Heuristic PBQP Solver for reg alloc --*- 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 for register allocation problems. This solver uses a
+// graph reduction approach. Nodes of degree 0, 1 and 2 are eliminated with
+// optimality-preserving rules (see ReductionRules.h). When no low-degree (<3)
+// nodes are present, a heuristic derived from Brigg's graph coloring approach
+// is used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H
+#define LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H
+
+#include "CostAllocator.h"
+#include "Graph.h"
+#include "ReductionRules.h"
+#include "Solution.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <limits>
+#include <vector>
+
+namespace PBQP {
+
+ namespace RegAlloc {
+
+ /// \brief Metadata to speed allocatability test.
+ ///
+ /// Keeps track of the number of infinities in each row and column.
+ class MatrixMetadata {
+ private:
+ MatrixMetadata(const MatrixMetadata&);
+ void operator=(const MatrixMetadata&);
+ public:
+ MatrixMetadata(const PBQP::Matrix& M)
+ : WorstRow(0), WorstCol(0),
+ UnsafeRows(new bool[M.getRows() - 1]()),
+ UnsafeCols(new bool[M.getCols() - 1]()) {
+
+ unsigned* ColCounts = new unsigned[M.getCols() - 1]();
+
+ for (unsigned i = 1; i < M.getRows(); ++i) {
+ unsigned RowCount = 0;
+ for (unsigned j = 1; j < M.getCols(); ++j) {
+ if (M[i][j] == std::numeric_limits<PBQP::PBQPNum>::infinity()) {
+ ++RowCount;
+ ++ColCounts[j - 1];
+ UnsafeRows[i - 1] = true;
+ UnsafeCols[j - 1] = true;
+ }
+ }
+ WorstRow = std::max(WorstRow, RowCount);
+ }
+ unsigned WorstColCountForCurRow =
+ *std::max_element(ColCounts, ColCounts + M.getCols() - 1);
+ WorstCol = std::max(WorstCol, WorstColCountForCurRow);
+ delete[] ColCounts;
+ }
+
+ ~MatrixMetadata() {
+ delete[] UnsafeRows;
+ delete[] UnsafeCols;
+ }
+
+ unsigned getWorstRow() const { return WorstRow; }
+ unsigned getWorstCol() const { return WorstCol; }
+ const bool* getUnsafeRows() const { return UnsafeRows; }
+ const bool* getUnsafeCols() const { return UnsafeCols; }
+
+ private:
+ unsigned WorstRow, WorstCol;
+ bool* UnsafeRows;
+ bool* UnsafeCols;
+ };
+
+ class NodeMetadata {
+ public:
+ typedef enum { Unprocessed,
+ OptimallyReducible,
+ ConservativelyAllocatable,
+ NotProvablyAllocatable } ReductionState;
+
+ NodeMetadata() : RS(Unprocessed), DeniedOpts(0), OptUnsafeEdges(0) {}
+ ~NodeMetadata() { delete[] OptUnsafeEdges; }
+
+ void setup(const Vector& Costs) {
+ NumOpts = Costs.getLength() - 1;
+ OptUnsafeEdges = new unsigned[NumOpts]();
+ }
+
+ ReductionState getReductionState() const { return RS; }
+ void setReductionState(ReductionState RS) { this->RS = RS; }
+
+ void handleAddEdge(const MatrixMetadata& MD, bool Transpose) {
+ DeniedOpts += Transpose ? MD.getWorstCol() : MD.getWorstRow();
+ const bool* UnsafeOpts =
+ Transpose ? MD.getUnsafeCols() : MD.getUnsafeRows();
+ for (unsigned i = 0; i < NumOpts; ++i)
+ OptUnsafeEdges[i] += UnsafeOpts[i];
+ }
+
+ void handleRemoveEdge(const MatrixMetadata& MD, bool Transpose) {
+ DeniedOpts -= Transpose ? MD.getWorstCol() : MD.getWorstRow();
+ const bool* UnsafeOpts =
+ Transpose ? MD.getUnsafeCols() : MD.getUnsafeRows();
+ for (unsigned i = 0; i < NumOpts; ++i)
+ OptUnsafeEdges[i] -= UnsafeOpts[i];
+ }
+
+ bool isConservativelyAllocatable() const {
+ return (DeniedOpts < NumOpts) ||
+ (std::find(OptUnsafeEdges, OptUnsafeEdges + NumOpts, 0) !=
+ OptUnsafeEdges + NumOpts);
+ }
+
+ private:
+ ReductionState RS;
+ unsigned NumOpts;
+ unsigned DeniedOpts;
+ unsigned* OptUnsafeEdges;
+ };
+
+ class RegAllocSolverImpl {
+ private:
+ typedef PBQP::MDMatrix<MatrixMetadata> RAMatrix;
+ public:
+ typedef PBQP::Vector RawVector;
+ typedef PBQP::Matrix RawMatrix;
+ typedef PBQP::Vector Vector;
+ typedef RAMatrix Matrix;
+ typedef PBQP::PoolCostAllocator<
+ Vector, PBQP::VectorComparator,
+ Matrix, PBQP::MatrixComparator> CostAllocator;
+
+ typedef PBQP::GraphBase::NodeId NodeId;
+ typedef PBQP::GraphBase::EdgeId EdgeId;
+
+ typedef RegAlloc::NodeMetadata NodeMetadata;
+
+ struct EdgeMetadata { };
+
+ typedef PBQP::Graph<RegAllocSolverImpl> Graph;
+
+ RegAllocSolverImpl(Graph &G) : G(G) {}
+
+ Solution solve() {
+ G.setSolver(*this);
+ Solution S;
+ setup();
+ S = backpropagate(G, reduce());
+ G.unsetSolver();
+ return S;
+ }
+
+ void handleAddNode(NodeId NId) {
+ G.getNodeMetadata(NId).setup(G.getNodeCosts(NId));
+ }
+ void handleRemoveNode(NodeId NId) {}
+ void handleSetNodeCosts(NodeId NId, const Vector& newCosts) {}
+
+ void handleAddEdge(EdgeId EId) {
+ handleReconnectEdge(EId, G.getEdgeNode1Id(EId));
+ handleReconnectEdge(EId, G.getEdgeNode2Id(EId));
+ }
+
+ void handleRemoveEdge(EdgeId EId) {
+ handleDisconnectEdge(EId, G.getEdgeNode1Id(EId));
+ handleDisconnectEdge(EId, G.getEdgeNode2Id(EId));
+ }
+
+ void handleDisconnectEdge(EdgeId EId, NodeId NId) {
+ NodeMetadata& NMd = G.getNodeMetadata(NId);
+ const MatrixMetadata& MMd = G.getEdgeCosts(EId).getMetadata();
+ NMd.handleRemoveEdge(MMd, NId == G.getEdgeNode2Id(EId));
+ if (G.getNodeDegree(NId) == 3) {
+ // This node is becoming optimally reducible.
+ moveToOptimallyReducibleNodes(NId);
+ } else if (NMd.getReductionState() ==
+ NodeMetadata::NotProvablyAllocatable &&
+ NMd.isConservativelyAllocatable()) {
+ // This node just became conservatively allocatable.
+ moveToConservativelyAllocatableNodes(NId);
+ }
+ }
+
+ void handleReconnectEdge(EdgeId EId, NodeId NId) {
+ NodeMetadata& NMd = G.getNodeMetadata(NId);
+ const MatrixMetadata& MMd = G.getEdgeCosts(EId).getMetadata();
+ NMd.handleAddEdge(MMd, NId == G.getEdgeNode2Id(EId));
+ }
+
+ void handleSetEdgeCosts(EdgeId EId, const Matrix& NewCosts) {
+ handleRemoveEdge(EId);
+
+ NodeId N1Id = G.getEdgeNode1Id(EId);
+ NodeId N2Id = G.getEdgeNode2Id(EId);
+ NodeMetadata& N1Md = G.getNodeMetadata(N1Id);
+ NodeMetadata& N2Md = G.getNodeMetadata(N2Id);
+ const MatrixMetadata& MMd = NewCosts.getMetadata();
+ N1Md.handleAddEdge(MMd, N1Id != G.getEdgeNode1Id(EId));
+ N2Md.handleAddEdge(MMd, N2Id != G.getEdgeNode1Id(EId));
+ }
+
+ private:
+
+ void removeFromCurrentSet(NodeId NId) {
+ switch (G.getNodeMetadata(NId).getReductionState()) {
+ case NodeMetadata::Unprocessed: break;
+ case NodeMetadata::OptimallyReducible:
+ assert(OptimallyReducibleNodes.find(NId) !=
+ OptimallyReducibleNodes.end() &&
+ "Node not in optimally reducible set.");
+ OptimallyReducibleNodes.erase(NId);
+ break;
+ case NodeMetadata::ConservativelyAllocatable:
+ assert(ConservativelyAllocatableNodes.find(NId) !=
+ ConservativelyAllocatableNodes.end() &&
+ "Node not in conservatively allocatable set.");
+ ConservativelyAllocatableNodes.erase(NId);
+ break;
+ case NodeMetadata::NotProvablyAllocatable:
+ assert(NotProvablyAllocatableNodes.find(NId) !=
+ NotProvablyAllocatableNodes.end() &&
+ "Node not in not-provably-allocatable set.");
+ NotProvablyAllocatableNodes.erase(NId);
+ break;
+ }
+ }
+
+ void moveToOptimallyReducibleNodes(NodeId NId) {
+ removeFromCurrentSet(NId);
+ OptimallyReducibleNodes.insert(NId);
+ G.getNodeMetadata(NId).setReductionState(
+ NodeMetadata::OptimallyReducible);
+ }
+
+ void moveToConservativelyAllocatableNodes(NodeId NId) {
+ removeFromCurrentSet(NId);
+ ConservativelyAllocatableNodes.insert(NId);
+ G.getNodeMetadata(NId).setReductionState(
+ NodeMetadata::ConservativelyAllocatable);
+ }
+
+ void moveToNotProvablyAllocatableNodes(NodeId NId) {
+ removeFromCurrentSet(NId);
+ NotProvablyAllocatableNodes.insert(NId);
+ G.getNodeMetadata(NId).setReductionState(
+ NodeMetadata::NotProvablyAllocatable);
+ }
+
+ void setup() {
+ // Set up worklists.
+ for (auto NId : G.nodeIds()) {
+ if (G.getNodeDegree(NId) < 3)
+ moveToOptimallyReducibleNodes(NId);
+ else if (G.getNodeMetadata(NId).isConservativelyAllocatable())
+ moveToConservativelyAllocatableNodes(NId);
+ else
+ moveToNotProvablyAllocatableNodes(NId);
+ }
+ }
+
+ // Compute a reduction order for the graph by iteratively applying PBQP
+ // reduction rules. Locally optimal rules are applied whenever possible (R0,
+ // R1, R2). If no locally-optimal rules apply then any conservatively
+ // allocatable node is reduced. Finally, if no conservatively allocatable
+ // node exists then the node with the lowest spill-cost:degree ratio is
+ // selected.
+ std::vector<GraphBase::NodeId> reduce() {
+ assert(!G.empty() && "Cannot reduce empty graph.");
+
+ typedef GraphBase::NodeId NodeId;
+ std::vector<NodeId> NodeStack;
+
+ // Consume worklists.
+ while (true) {
+ if (!OptimallyReducibleNodes.empty()) {
+ NodeSet::iterator NItr = OptimallyReducibleNodes.begin();
+ NodeId NId = *NItr;
+ OptimallyReducibleNodes.erase(NItr);
+ NodeStack.push_back(NId);
+ switch (G.getNodeDegree(NId)) {
+ case 0:
+ break;
+ case 1:
+ applyR1(G, NId);
+ break;
+ case 2:
+ applyR2(G, NId);
+ break;
+ default: llvm_unreachable("Not an optimally reducible node.");
+ }
+ } else if (!ConservativelyAllocatableNodes.empty()) {
+ // Conservatively allocatable nodes will never spill. For now just
+ // take the first node in the set and push it on the stack. When we
+ // start optimizing more heavily for register preferencing, it may
+ // would be better to push nodes with lower 'expected' or worst-case
+ // register costs first (since early nodes are the most
+ // constrained).
+ NodeSet::iterator NItr = ConservativelyAllocatableNodes.begin();
+ NodeId NId = *NItr;
+ ConservativelyAllocatableNodes.erase(NItr);
+ NodeStack.push_back(NId);
+ G.disconnectAllNeighborsFromNode(NId);
+
+ } else if (!NotProvablyAllocatableNodes.empty()) {
+ NodeSet::iterator NItr =
+ std::min_element(NotProvablyAllocatableNodes.begin(),
+ NotProvablyAllocatableNodes.end(),
+ SpillCostComparator(G));
+ NodeId NId = *NItr;
+ NotProvablyAllocatableNodes.erase(NItr);
+ NodeStack.push_back(NId);
+ G.disconnectAllNeighborsFromNode(NId);
+ } else
+ break;
+ }
+
+ return NodeStack;
+ }
+
+ class SpillCostComparator {
+ public:
+ SpillCostComparator(const Graph& G) : G(G) {}
+ bool operator()(NodeId N1Id, NodeId N2Id) {
+ PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id);
+ PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id);
+ return N1SC < N2SC;
+ }
+ private:
+ const Graph& G;
+ };
+
+ Graph& G;
+ typedef std::set<NodeId> NodeSet;
+ NodeSet OptimallyReducibleNodes;
+ NodeSet ConservativelyAllocatableNodes;
+ NodeSet NotProvablyAllocatableNodes;
+ };
+
+ typedef Graph<RegAllocSolverImpl> Graph;
+
+ Solution solve(Graph& G) {
+ if (G.empty())
+ return Solution();
+ RegAllocSolverImpl RegAllocSolver(G);
+ return RegAllocSolver.solve();
+ }
+
+ }
+}
+
+#endif // LLVM_CODEGEN_PBQP_REGALLOCSOLVER_H
diff --git a/include/llvm/CodeGen/PBQP/Solution.h b/include/llvm/CodeGen/PBQP/Solution.h
index 091805d..3556e60 100644
--- a/include/llvm/CodeGen/PBQP/Solution.h
+++ b/include/llvm/CodeGen/PBQP/Solution.h
@@ -26,7 +26,7 @@ namespace PBQP {
class Solution {
private:
- typedef std::map<Graph::NodeId, unsigned> SelectionsMap;
+ typedef std::map<GraphBase::NodeId, unsigned> SelectionsMap;
SelectionsMap selections;
unsigned r0Reductions, r1Reductions, r2Reductions, rNReductions;
@@ -72,14 +72,14 @@ namespace PBQP {
/// \brief Set the selection for a given node.
/// @param nodeId Node id.
/// @param selection Selection for nodeId.
- void setSelection(Graph::NodeId nodeId, unsigned selection) {
+ void setSelection(GraphBase::NodeId nodeId, unsigned selection) {
selections[nodeId] = selection;
}
/// \brief Get a node's selection.
/// @param nodeId Node id.
/// @return The selection for nodeId;
- unsigned getSelection(Graph::NodeId nodeId) const {
+ unsigned getSelection(GraphBase::NodeId nodeId) const {
SelectionsMap::const_iterator sItr = selections.find(nodeId);
assert(sItr != selections.end() && "No selection for node.");
return sItr->second;
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index ae4a2fa..5d68f86 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -207,9 +207,9 @@ public:
/// Fully developed targets will not generally override this.
virtual void addMachinePasses();
- /// createTargetScheduler - Create an instance of ScheduleDAGInstrs to be run
- /// within the standard MachineScheduler pass for this function and target at
- /// the current optimization level.
+ /// Create an instance of ScheduleDAGInstrs to be run within the standard
+ /// MachineScheduler pass for this function and target at the current
+ /// optimization level.
///
/// This can also be used to plug a new MachineSchedStrategy into an instance
/// of the standard ScheduleDAGMI:
@@ -221,6 +221,13 @@ public:
return 0;
}
+ /// Similar to createMachineScheduler but used when postRA machine scheduling
+ /// is enabled.
+ virtual ScheduleDAGInstrs *
+ createPostMachineScheduler(MachineSchedContext *C) const {
+ return 0;
+ }
+
protected:
// Helper to verify the analysis is really immutable.
void setOpt(bool &Opt, bool Val);
@@ -363,6 +370,10 @@ namespace llvm {
createMachineFunctionPrinterPass(raw_ostream &OS,
const std::string &Banner ="");
+ /// createCodeGenPreparePass - Transform the code to expose more pattern
+ /// matching during instruction selection.
+ FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = 0);
+
/// MachineLoopInfo - This pass is a loop analysis pass.
extern char &MachineLoopInfoID;
@@ -403,6 +414,9 @@ namespace llvm {
/// MachineScheduler - This pass schedules machine instructions.
extern char &MachineSchedulerID;
+ /// PostMachineScheduler - This pass schedules machine instructions postRA.
+ extern char &PostMachineSchedulerID;
+
/// SpillPlacement analysis. Suggest optimal placement of spill code between
/// basic blocks.
extern char &SpillPlacementID;
@@ -568,6 +582,11 @@ namespace llvm {
/// bundles (created earlier, e.g. during pre-RA scheduling).
extern char &FinalizeMachineBundlesID;
+ /// StackMapLiveness - This pass analyses the register live-out set of
+ /// stackmap/patchpoint intrinsics and attaches the calculated information to
+ /// the intrinsic for later emission to the StackMap.
+ extern char &StackMapLivenessID;
+
} // End llvm namespace
#endif
diff --git a/include/llvm/CodeGen/PseudoSourceValue.h b/include/llvm/CodeGen/PseudoSourceValue.h
index 705086c..0af8915 100644
--- a/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/include/llvm/CodeGen/PseudoSourceValue.h
@@ -29,7 +29,7 @@ namespace llvm {
/// printCustom - Implement printing for PseudoSourceValue. This is called
/// from Value::print or Value's operator<<.
///
- virtual void printCustom(raw_ostream &O) const;
+ void printCustom(raw_ostream &O) const override;
public:
explicit PseudoSourceValue(enum ValueTy Subclass = PseudoSourceValueVal);
@@ -93,13 +93,13 @@ namespace llvm {
return V->getValueID() == FixedStackPseudoSourceValueVal;
}
- virtual bool isConstant(const MachineFrameInfo *MFI) const;
+ bool isConstant(const MachineFrameInfo *MFI) const override;
- virtual bool isAliased(const MachineFrameInfo *MFI) const;
+ bool isAliased(const MachineFrameInfo *MFI) const override;
- virtual bool mayAlias(const MachineFrameInfo *) const;
+ bool mayAlias(const MachineFrameInfo *) const override;
- virtual void printCustom(raw_ostream &OS) const;
+ void printCustom(raw_ostream &OS) const override;
int getFrameIndex() const { return FI; }
};
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index 7472e5a..efd7c61 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -17,9 +17,9 @@
#define LLVM_CODEGEN_REGALLOCPBQP_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/PBQP/Graph.h"
-#include "llvm/CodeGen/PBQP/Solution.h"
+#include "llvm/CodeGen/PBQP/RegAllocSolver.h"
#include <map>
#include <set>
@@ -29,30 +29,30 @@ namespace llvm {
class MachineBlockFrequencyInfo;
class MachineFunction;
class TargetRegisterInfo;
- template<class T> class OwningPtr;
+
+ typedef PBQP::RegAlloc::Graph PBQPRAGraph;
/// 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; }
+ PBQPRAGraph& getGraph() { return graph; }
- const PBQP::Graph& getGraph() const { return graph; }
+ const PBQPRAGraph& 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.
+ /// vregs will already have been set up for you by the base class.
template <typename AllowedRegsItr>
- void recordVReg(unsigned vreg, PBQP::Graph::NodeId nodeId,
+ void recordVReg(unsigned vreg, PBQPRAGraph::NodeId nodeId,
AllowedRegsItr arBegin, AllowedRegsItr arEnd) {
assert(node2VReg.find(nodeId) == node2VReg.end() && "Re-mapping node.");
assert(vreg2Node.find(vreg) == vreg2Node.end() && "Re-mapping vreg.");
@@ -64,10 +64,10 @@ namespace llvm {
}
/// Get the virtual register corresponding to the given PBQP node.
- unsigned getVRegForNode(PBQP::Graph::NodeId nodeId) const;
+ unsigned getVRegForNode(PBQPRAGraph::NodeId nodeId) const;
/// Get the PBQP node corresponding to the given virtual register.
- PBQP::Graph::NodeId getNodeForVReg(unsigned vreg) const;
+ PBQPRAGraph::NodeId getNodeForVReg(unsigned vreg) const;
/// Returns true if the given PBQP option represents a physical register,
/// false otherwise.
@@ -92,16 +92,16 @@ namespace llvm {
private:
- typedef std::map<PBQP::Graph::NodeId, unsigned> Node2VReg;
- typedef DenseMap<unsigned, PBQP::Graph::NodeId> VReg2Node;
+ typedef std::map<PBQPRAGraph::NodeId, unsigned> Node2VReg;
+ typedef DenseMap<unsigned, PBQPRAGraph::NodeId> VReg2Node;
typedef DenseMap<unsigned, AllowedSet> AllowedSetMap;
- PBQP::Graph graph;
+ PBQPRAGraph graph;
Node2VReg node2VReg;
VReg2Node vreg2Node;
AllowedSetMap allowedSets;
-
+
};
/// Builds PBQP instances to represent register allocation problems. Includes
@@ -114,7 +114,7 @@ namespace llvm {
public:
typedef std::set<unsigned> RegSet;
-
+
/// Default constructor.
PBQPBuilder() {}
@@ -139,12 +139,12 @@ namespace llvm {
/// 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 PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
- const MachineBlockFrequencyInfo *mbfi,
- const RegSet &vregs);
+ PBQPRAProblem *build(MachineFunction *mf, const LiveIntervals *lis,
+ const MachineBlockFrequencyInfo *mbfi,
+ const RegSet &vregs) override;
private:
@@ -157,8 +157,9 @@ namespace llvm {
PBQP::PBQPNum benefit);
};
- FunctionPass* createPBQPRegisterAllocator(OwningPtr<PBQPBuilder> &builder,
- char *customPassID=0);
+ FunctionPass *
+ createPBQPRegisterAllocator(std::unique_ptr<PBQPBuilder> &builder,
+ char *customPassID = 0);
}
#endif /* LLVM_CODEGEN_REGALLOCPBQP_H */
diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h
index f20a9fc..7ae9111 100644
--- a/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -81,17 +81,17 @@ namespace llvm {
delete ResourcesModel;
}
- bool isBottomUp() const { return false; }
+ bool isBottomUp() const override { return false; }
- void initNodes(std::vector<SUnit> &sunits);
+ void initNodes(std::vector<SUnit> &sunits) override;
- void addNode(const SUnit *SU) {
+ void addNode(const SUnit *SU) override {
NumNodesSolelyBlocking.resize(SUnits->size(), 0);
}
- void updateNode(const SUnit *SU) {}
+ void updateNode(const SUnit *SU) override {}
- void releaseState() {
+ void releaseState() override {
SUnits = 0;
}
@@ -116,18 +116,18 @@ namespace llvm {
signed regPressureDelta(SUnit *SU, bool RawPressure = false);
signed rawRegPressureDelta (SUnit *SU, unsigned RCId);
- bool empty() const { return Queue.empty(); }
+ bool empty() const override { return Queue.empty(); }
- virtual void push(SUnit *U);
+ void push(SUnit *U) override;
- virtual SUnit *pop();
+ SUnit *pop() override;
- virtual void remove(SUnit *SU);
+ void remove(SUnit *SU) override;
- virtual void dump(ScheduleDAG* DAG) const;
+ void dump(ScheduleDAG* DAG) const override;
/// scheduledNode - Main resource tracking point.
- void scheduledNode(SUnit *Node);
+ void scheduledNode(SUnit *Node) override;
bool isResourceAvailable(SUnit *SU);
void reserveResources(SUnit *SU);
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index ccba1b0..4886e5c 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -184,6 +184,12 @@ namespace llvm {
|| Contents.OrdKind == MustAliasMem);
}
+ /// isBarrier - Test if this is an Order dependence that is marked
+ /// as a barrier.
+ bool isBarrier() const {
+ return getKind() == Order && Contents.OrdKind == Barrier;
+ }
+
/// 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.
@@ -248,7 +254,7 @@ namespace llvm {
/// SUnit - Scheduling unit. This is a node in the scheduling DAG.
class SUnit {
private:
- enum LLVM_ENUM_INT_TYPE(unsigned) { BoundaryID = ~0u };
+ enum : unsigned { BoundaryID = ~0u };
SDNode *Node; // Representative node.
MachineInstr *Instr; // Alternatively, a MachineInstr.
@@ -292,6 +298,8 @@ namespace llvm {
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.
+ bool isUnbuffered : 1; // Uses an unbuffered resource.
+ bool hasReservedResource : 1; // Uses a reserved resource.
Sched::Preference SchedulingPref; // Scheduling preference.
private:
@@ -316,7 +324,8 @@ namespace llvm {
isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
isAvailable(false), isScheduled(false), isScheduleHigh(false),
- isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None),
+ isScheduleLow(false), isCloned(false), isUnbuffered(false),
+ hasReservedResource(false), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
@@ -330,7 +339,8 @@ namespace llvm {
isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
isAvailable(false), isScheduled(false), isScheduleHigh(false),
- isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None),
+ isScheduleLow(false), isCloned(false), isUnbuffered(false),
+ hasReservedResource(false), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
@@ -343,7 +353,8 @@ namespace llvm {
isTwoAddress(false), isCommutable(false), hasPhysRegUses(false),
hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false),
isAvailable(false), isScheduled(false), isScheduleHigh(false),
- isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None),
+ isScheduleLow(false), isCloned(false), isUnbuffered(false),
+ hasReservedResource(false), SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index fe4f3c2..72bbe8b 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -15,8 +15,8 @@
#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
-#include "llvm/ADT/SparseSet.h"
#include "llvm/ADT/SparseMultiSet.h"
+#include "llvm/ADT/SparseSet.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/Support/Compiler.h"
@@ -43,7 +43,7 @@ namespace llvm {
};
/// Record a physical register access.
- /// For non data-dependent uses, OpIdx == -1.
+ /// For non-data-dependent uses, OpIdx == -1.
struct PhysRegSUOper {
SUnit *SU;
int OpIdx;
@@ -88,9 +88,13 @@ namespace llvm {
/// isPostRA flag indicates vregs cannot be present.
bool IsPostRA;
+ /// True if the DAG builder should remove kill flags (in preparation for
+ /// rescheduling).
+ bool RemoveKillFlags;
+
/// 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
+ /// reordering. A specialized scheduler can override
/// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
/// it has taken responsibility for scheduling the terminator correctly.
bool CanHandleTerminators;
@@ -145,15 +149,21 @@ namespace llvm {
DbgValueVector DbgValues;
MachineInstr *FirstDbgValue;
+ /// Set of live physical registers for updating kill flags.
+ BitVector LiveRegs;
+
public:
explicit ScheduleDAGInstrs(MachineFunction &mf,
const MachineLoopInfo &mli,
const MachineDominatorTree &mdt,
bool IsPostRAFlag,
+ bool RemoveKillFlags = false,
LiveIntervals *LIS = 0);
virtual ~ScheduleDAGInstrs() {}
+ bool isPostRA() const { return IsPostRA; }
+
/// \brief Expose LiveIntervals for use in DAG mutators and such.
LiveIntervals *getLIS() const { return LIS; }
@@ -219,20 +229,31 @@ namespace llvm {
/// the level of the whole MachineFunction. By default does nothing.
virtual void finalizeSchedule() {}
- virtual void dumpNode(const SUnit *SU) const;
+ void dumpNode(const SUnit *SU) const override;
/// Return a label for a DAG node that points to an instruction.
- virtual std::string getGraphNodeLabel(const SUnit *SU) const;
+ std::string getGraphNodeLabel(const SUnit *SU) const override;
/// Return a label for the region of code covered by the DAG.
- virtual std::string getDAGName() const;
+ std::string getDAGName() const override;
+ /// \brief Fix register kill flags that scheduling has made invalid.
+ void fixupKills(MachineBasicBlock *MBB);
protected:
void initSUnits();
void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx);
void addPhysRegDeps(SUnit *SU, unsigned OperIdx);
void addVRegDefDeps(SUnit *SU, unsigned OperIdx);
void addVRegUseDeps(SUnit *SU, unsigned OperIdx);
+
+ /// \brief PostRA helper for rewriting kill flags.
+ void startBlockForKills(MachineBasicBlock *BB);
+
+ /// \brief Toggle a register operand kill flag.
+ ///
+ /// Other adjustments may be made to the instruction if necessary. Return
+ /// true if the operand has been deleted, false if not.
+ bool toggleKillFlag(MachineInstr *MI, MachineOperand &MO);
};
/// newSUnit - Creates a new SUnit and return a ptr to it.
diff --git a/include/llvm/CodeGen/ScheduleHazardRecognizer.h b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
index 9dfa344..8a40e72 100644
--- a/include/llvm/CodeGen/ScheduleHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScheduleHazardRecognizer.h
@@ -70,6 +70,22 @@ public:
/// emitted, to advance the hazard state.
virtual void EmitInstruction(SUnit *) {}
+ /// PreEmitNoops - This callback is invoked prior to emitting an instruction.
+ /// It should return the number of noops to emit prior to the provided
+ /// instruction.
+ /// Note: This is only used during PostRA scheduling. EmitNoop is not called
+ /// for these noops.
+ virtual unsigned PreEmitNoops(SUnit *) {
+ return 0;
+ }
+
+ /// ShouldPreferAnother - This callback may be invoked if getHazardType
+ /// returns NoHazard. If, even though there is no hazard, it would be better to
+ /// schedule another available instruction, this callback should return true.
+ virtual bool ShouldPreferAnother(SUnit *) {
+ return false;
+ }
+
/// 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
diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index c2103fb..fbbbb0c 100644
--- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -110,15 +110,15 @@ public:
/// atIssueLimit - Return true if no more instructions may be issued in this
/// cycle.
- virtual bool atIssueLimit() const;
+ bool atIssueLimit() const override;
// 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();
+ HazardType getHazardType(SUnit *SU, int Stalls) override;
+ void Reset() override;
+ void EmitInstruction(SUnit *SU) override;
+ void AdvanceCycle() override;
+ void RecedeCycle() override;
};
}
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 82becca..a30656a 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -36,7 +36,6 @@ class MDNode;
class SDDbgValue;
class TargetLowering;
class TargetSelectionDAGInfo;
-class TargetTransformInfo;
class SDVTListNode : public FoldingSetNode {
friend struct FoldingSetTrait<SDVTListNode>;
@@ -169,7 +168,6 @@ void checkForCycles(const SelectionDAG *DAG);
class SelectionDAG {
const TargetMachine &TM;
const TargetSelectionDAGInfo &TSI;
- const TargetTransformInfo *TTI;
const TargetLowering *TLI;
MachineFunction *MF;
LLVMContext *Context;
@@ -269,8 +267,7 @@ public:
/// init - Prepare this SelectionDAG to process code in the given
/// MachineFunction.
///
- void init(MachineFunction &mf, const TargetTransformInfo *TTI,
- const TargetLowering *TLI);
+ void init(MachineFunction &mf, const TargetLowering *TLI);
/// clear - Clear state and free memory necessary to make this
/// SelectionDAG ready to process a new block.
@@ -281,7 +278,6 @@ public:
const TargetMachine &getTarget() const { return TM; }
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
- const TargetTransformInfo *getTargetTransformInfo() const { return TTI; }
LLVMContext *getContext() const {return Context; }
/// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
@@ -401,18 +397,22 @@ public:
//===--------------------------------------------------------------------===//
// 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 getConstant(uint64_t Val, EVT VT, bool isTarget = false,
+ bool isOpaque = false);
+ SDValue getConstant(const APInt &Val, EVT VT, bool isTarget = false,
+ bool isOpaque = false);
+ SDValue getConstant(const ConstantInt &Val, EVT VT, bool isTarget = false,
+ bool isOpaque = false);
SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false);
- SDValue getTargetConstant(uint64_t Val, EVT VT) {
- return getConstant(Val, VT, true);
+ SDValue getTargetConstant(uint64_t Val, EVT VT, bool isOpaque = false) {
+ return getConstant(Val, VT, true, isOpaque);
}
- SDValue getTargetConstant(const APInt &Val, EVT VT) {
- return getConstant(Val, VT, true);
+ SDValue getTargetConstant(const APInt &Val, EVT VT, bool isOpaque = false) {
+ return getConstant(Val, VT, true, isOpaque);
}
- SDValue getTargetConstant(const ConstantInt &Val, EVT VT) {
- return getConstant(Val, VT, true);
+ SDValue getTargetConstant(const ConstantInt &Val, EVT VT,
+ bool isOpaque = false) {
+ return getConstant(Val, VT, true, isOpaque);
}
// 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.
@@ -692,12 +692,14 @@ public:
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp,
MachinePointerInfo PtrInfo, unsigned Alignment,
- AtomicOrdering Ordering,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope);
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp,
MachineMemOperand *MMO,
- AtomicOrdering Ordering,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope);
/// getAtomic - Gets a node for an atomic op, produces result (if relevant)
@@ -726,9 +728,13 @@ public:
/// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes N operands.
SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList,
- SDValue* Ops, unsigned NumOps, MachineMemOperand *MMO,
- AtomicOrdering Ordering,
+ SDValue *Ops, unsigned NumOps, MachineMemOperand *MMO,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
SynchronizationScope SynchScope);
+ SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList,
+ SDValue *Ops, unsigned NumOps, 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,
@@ -1143,7 +1149,7 @@ public:
/// low/high part.
std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL) {
EVT LoVT, HiVT;
- llvm::tie(LoVT, HiVT) = GetSplitDestVTs(N.getValueType());
+ std::tie(LoVT, HiVT) = GetSplitDestVTs(N.getValueType());
return SplitVector(N, DL, LoVT, HiVT);
}
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index b5ec8cb..b92b6ec 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -30,7 +30,6 @@ namespace llvm {
class MachineInstr;
class TargetLowering;
class TargetLibraryInfo;
- class TargetTransformInfo;
class FunctionLoweringInfo;
class ScheduleHazardRecognizer;
class GCFunctionInfo;
@@ -43,7 +42,6 @@ class SelectionDAGISel : public MachineFunctionPass {
public:
TargetMachine &TM;
const TargetLibraryInfo *LibInfo;
- const TargetTransformInfo *TTI;
FunctionLoweringInfo *FuncInfo;
MachineFunction *MF;
MachineRegisterInfo *RegInfo;
@@ -62,9 +60,9 @@ public:
return TM.getTargetLowering();
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
- virtual bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &MF) override;
virtual void EmitFunctionEntryCode() {}
@@ -125,6 +123,8 @@ public:
OPC_CheckChild3Type, OPC_CheckChild4Type, OPC_CheckChild5Type,
OPC_CheckChild6Type, OPC_CheckChild7Type,
OPC_CheckInteger,
+ OPC_CheckChild0Integer, OPC_CheckChild1Integer, OPC_CheckChild2Integer,
+ OPC_CheckChild3Integer, OPC_CheckChild4Integer,
OPC_CheckCondCode,
OPC_CheckValueType,
OPC_CheckComplexPat,
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 70c15e6..fd915b0 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -29,9 +29,9 @@
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/DebugLoc.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
@@ -70,6 +70,10 @@ namespace ISD {
/// BUILD_VECTOR where all of the elements are 0 or undef.
bool isBuildVectorAllZeros(const SDNode *N);
+ /// \brief Return true if the specified node is a BUILD_VECTOR node of
+ /// all ConstantSDNode or undef.
+ bool isBuildVectorOfConstantSDNodes(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.
@@ -116,7 +120,7 @@ public:
return !operator==(O);
}
bool operator<(const SDValue &O) const {
- return Node < O.Node || (Node == O.Node && ResNo < O.ResNo);
+ return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
}
SDValue getValue(unsigned R) const {
@@ -141,6 +145,10 @@ public:
return getValueType().getSizeInBits();
}
+ unsigned getScalarValueSizeInBits() const {
+ return getValueType().getScalarType().getSizeInBits();
+ }
+
// Forwarding methods - These forward to the corresponding methods in SDNode.
inline unsigned getOpcode() const;
inline unsigned getNumOperands() const;
@@ -404,7 +412,7 @@ public:
/// hasOneUse - Return true if there is exactly one use of this node.
///
bool hasOneUse() const {
- return !use_empty() && llvm::next(use_begin()) == use_end();
+ return !use_empty() && std::next(use_begin()) == use_end();
}
/// use_size - Return the number of uses of this node. This method takes
@@ -1085,15 +1093,27 @@ public:
class AtomicSDNode : public MemSDNode {
SDUse Ops[4];
- void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) {
+ /// For cmpxchg instructions, the ordering requirements when a store does not
+ /// occur.
+ AtomicOrdering FailureOrdering;
+
+ void InitAtomic(AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope) {
// This must match encodeMemSDNodeFlags() in SelectionDAG.cpp.
- assert((Ordering & 15) == Ordering &&
+ assert((SuccessOrdering & 15) == SuccessOrdering &&
+ "Ordering may not require more than 4 bits!");
+ assert((FailureOrdering & 15) == FailureOrdering &&
"Ordering may not require more than 4 bits!");
assert((SynchScope & 1) == SynchScope &&
"SynchScope may not require more than 1 bit!");
- SubclassData |= Ordering << 8;
+ SubclassData |= SuccessOrdering << 8;
SubclassData |= SynchScope << 12;
- assert(getOrdering() == Ordering && "Ordering encoding error!");
+ this->FailureOrdering = FailureOrdering;
+ assert(getSuccessOrdering() == SuccessOrdering &&
+ "Ordering encoding error!");
+ assert(getFailureOrdering() == FailureOrdering &&
+ "Ordering encoding error!");
assert(getSynchScope() == SynchScope && "Synch-scope encoding error!");
}
@@ -1107,12 +1127,11 @@ public:
// SrcVal: address to update as a Value (used for MemOperand)
// Align: alignment of memory
AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL,
- EVT MemVT,
- SDValue Chain, SDValue Ptr,
- SDValue Cmp, SDValue Swp, MachineMemOperand *MMO,
- AtomicOrdering Ordering, SynchronizationScope SynchScope)
- : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
- InitAtomic(Ordering, SynchScope);
+ EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp,
+ MachineMemOperand *MMO, AtomicOrdering Ordering,
+ SynchronizationScope SynchScope)
+ : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
+ InitAtomic(Ordering, Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr, Cmp, Swp);
}
AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL,
@@ -1121,7 +1140,7 @@ public:
SDValue Val, MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
- InitAtomic(Ordering, SynchScope);
+ InitAtomic(Ordering, Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr, Val);
}
AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL,
@@ -1130,15 +1149,16 @@ public:
MachineMemOperand *MMO,
AtomicOrdering Ordering, SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
- InitAtomic(Ordering, SynchScope);
+ InitAtomic(Ordering, Ordering, SynchScope);
InitOperands(Ops, Chain, Ptr);
}
AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT,
SDValue* AllOps, SDUse *DynOps, unsigned NumOps,
MachineMemOperand *MMO,
- AtomicOrdering Ordering, SynchronizationScope SynchScope)
+ AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope)
: MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
- InitAtomic(Ordering, SynchScope);
+ InitAtomic(SuccessOrdering, FailureOrdering, SynchScope);
assert((DynOps || NumOps <= array_lengthof(Ops)) &&
"Too many ops for internal storage!");
InitOperands(DynOps ? DynOps : Ops, AllOps, NumOps);
@@ -1147,6 +1167,16 @@ public:
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getVal() const { return getOperand(2); }
+ AtomicOrdering getSuccessOrdering() const {
+ return getOrdering();
+ }
+
+ // Not quite enough room in SubclassData for everything, so failure gets its
+ // own field.
+ AtomicOrdering getFailureOrdering() const {
+ return FailureOrdering;
+ }
+
bool isCompareAndSwap() const {
unsigned Op = getOpcode();
return Op == ISD::ATOMIC_CMP_SWAP;
@@ -1246,9 +1276,10 @@ public:
class ConstantSDNode : public SDNode {
const ConstantInt *Value;
friend class SelectionDAG;
- ConstantSDNode(bool isTarget, const ConstantInt *val, EVT VT)
+ ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val, EVT VT)
: SDNode(isTarget ? ISD::TargetConstant : ISD::Constant,
0, DebugLoc(), getSDVTList(VT)), Value(val) {
+ SubclassData |= (uint16_t)isOpaque;
}
public:
@@ -1261,6 +1292,8 @@ public:
bool isNullValue() const { return Value->isNullValue(); }
bool isAllOnesValue() const { return Value->isAllOnesValue(); }
+ bool isOpaque() const { return SubclassData & 1; }
+
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::Constant ||
N->getOpcode() == ISD::TargetConstant;
@@ -1486,7 +1519,16 @@ public:
/// undefined. isBigEndian describes the endianness of the target.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
unsigned &SplatBitSize, bool &HasAnyUndefs,
- unsigned MinSplatBits = 0, bool isBigEndian = false);
+ unsigned MinSplatBits = 0,
+ bool isBigEndian = false) const;
+
+ /// getConstantSplatValue - Check if this is a constant splat, and if so,
+ /// return the splat value only if it is a ConstantSDNode. Otherwise
+ /// return nullptr. This is a simpler form of isConstantSplat.
+ /// Get the constant splat only if you care about the splat value.
+ ConstantSDNode *getConstantSplatValue() const;
+
+ bool isConstant() const;
static inline bool classof(const SDNode *N) {
return N->getOpcode() == ISD::BUILD_VECTOR;
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index 984796a..1cc34d5 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -377,10 +377,10 @@ namespace llvm {
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
}
- virtual void getAnalysisUsage(AnalysisUsage &au) const;
- virtual void releaseMemory();
+ void getAnalysisUsage(AnalysisUsage &au) const override;
+ void releaseMemory() override;
- virtual bool runOnMachineFunction(MachineFunction &fn);
+ bool runOnMachineFunction(MachineFunction &fn) override;
/// Dump the indexes.
void dump() const;
@@ -545,7 +545,7 @@ namespace llvm {
std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start);
if (itr == idx2MBBMap.end()) {
- itr = prior(itr);
+ itr = std::prev(itr);
return itr->second;
}
@@ -553,7 +553,7 @@ namespace llvm {
if (itr->first < end)
return 0;
- itr = prior(itr);
+ itr = std::prev(itr);
if (itr->first <= start)
return itr->second;
@@ -581,11 +581,11 @@ namespace llvm {
if (Late) {
// Insert mi's index immediately before the following instruction.
nextItr = getIndexAfter(mi).listEntry();
- prevItr = prior(nextItr);
+ prevItr = std::prev(nextItr);
} else {
// Insert mi's index immediately after the preceding instruction.
prevItr = getIndexBefore(mi).listEntry();
- nextItr = llvm::next(prevItr);
+ nextItr = std::next(prevItr);
}
// Get a number for the new instr, or 0 if there's no room currently.
@@ -638,7 +638,7 @@ namespace llvm {
/// Add the given MachineBasicBlock into the maps.
void insertMBBInMaps(MachineBasicBlock *mbb) {
MachineFunction::iterator nextMBB =
- llvm::next(MachineFunction::iterator(mbb));
+ std::next(MachineFunction::iterator(mbb));
IndexListEntry *startEntry = 0;
IndexListEntry *endEntry = 0;
diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
new file mode 100644
index 0000000..6ba7256
--- /dev/null
+++ b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
@@ -0,0 +1,65 @@
+//===--- StackMapLivenessAnalysis - StackMap Liveness 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 calculates the liveness for each basic block in a function and
+// attaches the register live-out information to a stackmap or patchpoint
+// intrinsic if present.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
+#define LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
+
+#include "llvm/CodeGen/LivePhysRegs.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+
+namespace llvm {
+
+/// \brief This pass calculates the liveness information for each basic block in
+/// a function and attaches the register live-out information to a stackmap or
+/// patchpoint intrinsic if present.
+///
+/// This is an optional pass that has to be explicitly enabled via the
+/// -enable-stackmap-liveness and/or -enable-patchpoint-liveness flag. The pass
+/// skips functions that don't have any stackmap or patchpoint intrinsics. The
+/// information provided by this pass is optional and not required by the
+/// aformentioned intrinsics to function.
+class StackMapLiveness : public MachineFunctionPass {
+ MachineFunction *MF;
+ const TargetRegisterInfo *TRI;
+ LivePhysRegs LiveRegs;
+public:
+ static char ID;
+
+ /// \brief Default construct and initialize the pass.
+ StackMapLiveness();
+
+ /// \brief Tell the pass manager which passes we depend on and what
+ /// information we preserve.
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+ /// \brief Calculate the liveness information for the given machine function.
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+private:
+ /// \brief Performs the actual liveness calculation for the function.
+ bool calculateLiveness();
+
+ /// \brief Add the current register live set to the instruction.
+ void addLiveOutSetToMI(MachineInstr &MI);
+
+ /// \brief Create a register mask and initialize it with the registers from
+ /// the register live set.
+ uint32_t *createRegisterMask() const;
+};
+
+} // llvm namespace
+
+#endif // LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h
index e90f22e..a62ab6e 100644
--- a/include/llvm/CodeGen/StackMaps.h
+++ b/include/llvm/CodeGen/StackMaps.h
@@ -1,4 +1,5 @@
//===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===//
+
//
// The LLVM Compiler Infrastructure
//
@@ -10,6 +11,7 @@
#ifndef LLVM_STACKMAPS
#define LLVM_STACKMAPS
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstr.h"
#include <map>
@@ -92,19 +94,28 @@ public:
: LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
};
- // Typedef a function pointer for functions that parse sequences of operands
- // and return a Location, plus a new "next" operand iterator.
- typedef std::pair<Location, MachineInstr::const_mop_iterator>
- (*OperandParser)(MachineInstr::const_mop_iterator,
- MachineInstr::const_mop_iterator, const TargetMachine&);
+ struct LiveOutReg {
+ unsigned short Reg;
+ unsigned short RegNo;
+ unsigned short Size;
+
+ LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
+ LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
+ : Reg(Reg), RegNo(RegNo), Size(Size) {}
+
+ void MarkInvalid() { Reg = 0; }
+
+ // Only sort by the dwarf register number.
+ bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
+ static bool IsInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
+ };
// OpTypes are used to encode information about the following logical
// operand (which may consist of several MachineOperands) for the
// OpParser.
typedef enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType;
- StackMaps(AsmPrinter &AP, OperandParser OpParser)
- : AP(AP), OpParser(OpParser) {}
+ StackMaps(AsmPrinter &AP) : AP(AP) {}
/// \brief Generate a stackmap record for a stackmap instruction.
///
@@ -121,15 +132,19 @@ public:
private:
typedef SmallVector<Location, 8> LocationVec;
+ typedef SmallVector<LiveOutReg, 8> LiveOutVec;
+ typedef MapVector<const MCSymbol *, uint64_t> FnStackSizeMap;
struct CallsiteInfo {
const MCExpr *CSOffsetExpr;
- unsigned ID;
+ uint64_t ID;
LocationVec Locations;
+ LiveOutVec LiveOuts;
CallsiteInfo() : CSOffsetExpr(0), ID(0) {}
- CallsiteInfo(const MCExpr *CSOffsetExpr, unsigned ID,
- LocationVec Locations)
- : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations) {}
+ CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
+ LocationVec &Locations, LiveOutVec &LiveOuts)
+ : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations),
+ LiveOuts(LiveOuts) {}
};
typedef std::vector<CallsiteInfo> CallsiteInfoList;
@@ -155,16 +170,29 @@ private:
};
AsmPrinter &AP;
- OperandParser OpParser;
CallsiteInfoList CSInfos;
ConstantPool ConstPool;
+ FnStackSizeMap FnStackSize;
+
+ MachineInstr::const_mop_iterator
+ parseOperand(MachineInstr::const_mop_iterator MOI,
+ MachineInstr::const_mop_iterator MOE,
+ LocationVec &Locs, LiveOutVec &LiveOuts) const;
+
+ /// \brief Create a live-out register record for the given register @p Reg.
+ LiveOutReg createLiveOutReg(unsigned Reg,
+ const TargetRegisterInfo *TRI) const;
+
+ /// \brief Parse the register live-out mask and return a vector of live-out
+ /// registers that need to be recorded in the stackmap.
+ LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
/// This should be called by the MC lowering code _immediately_ before
/// lowering the MI to an MCInst. It records where the operands for the
/// instruction are stored, and outputs a label to record the offset of
/// the call from the start of the text section. In special cases (e.g. AnyReg
/// calling convention) the return register is also recorded if requested.
- void recordStackMapOpers(const MachineInstr &MI, uint32_t ID,
+ void recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
MachineInstr::const_mop_iterator MOI,
MachineInstr::const_mop_iterator MOE,
bool recordResult = false);
diff --git a/include/llvm/CodeGen/StackProtector.h b/include/llvm/CodeGen/StackProtector.h
index d09a933..0b8b8c0 100644
--- a/include/llvm/CodeGen/StackProtector.h
+++ b/include/llvm/CodeGen/StackProtector.h
@@ -19,12 +19,12 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/ValueMap.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/ValueMap.h"
#include "llvm/Pass.h"
#include "llvm/Target/TargetLowering.h"
namespace llvm {
-class DominatorTree;
class Function;
class Module;
class PHINode;
@@ -114,13 +114,14 @@ public:
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addPreserved<DominatorTree>();
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addPreserved<DominatorTreeWrapperPass>();
}
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
+ void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
- virtual bool runOnFunction(Function &Fn);
+ bool runOnFunction(Function &Fn) override;
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 5b22c9c..16fed32 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -38,81 +38,81 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
public:
virtual ~TargetLoweringObjectFileELF() {}
- virtual void emitPersonalityValue(MCStreamer &Streamer,
+ void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM,
+ const MCSymbol *Sym) const override;
+
+ /// Given a constant with the SectionKind, return a section that it should be
+ /// placed in.
+ const MCSection *getSectionForConstant(SectionKind Kind) const override;
+
+ const MCSection *getExplicitSectionGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const override;
+
+ const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const override;
+
+ /// Return an MCExpr to use for a reference to the specified type info global
+ /// variable from exception handling information.
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const override;
+
+ // The symbol that gets passed to .cfi_personality.
+ MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
const TargetMachine &TM,
- const MCSymbol *Sym) const;
+ MachineModuleInfo *MMI) const override;
- /// getSectionForConstant - Given a constant with the SectionKind, return a
- /// section that it should be placed in.
- virtual const MCSection *getSectionForConstant(SectionKind Kind) const;
+ void InitializeELF(bool UseInitArray_);
+ const MCSection *
+ getStaticCtorSection(unsigned Priority = 65535) const override;
+ const MCSection *
+ getStaticDtorSection(unsigned Priority = 65535) const override;
+};
- virtual const MCSection *
- getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
- virtual const MCSection *
- SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
+class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
+public:
+ virtual ~TargetLoweringObjectFileMachO() {}
- /// getTTypeGlobalReference - Return an MCExpr to use for a reference to the
- /// specified type info global variable from exception handling information.
- virtual const MCExpr *
- getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ /// Extract the dependent library name from a linker option string. Returns
+ /// StringRef() if the option does not specify a library.
+ StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
- // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
- virtual MCSymbol *
- getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI) const;
+ /// Emit the module flags that specify the garbage collection information.
+ void emitModuleFlags(MCStreamer &Streamer,
+ ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
+ Mangler &Mang, const TargetMachine &TM) const override;
- void InitializeELF(bool UseInitArray_);
- virtual const MCSection *
- getStaticCtorSection(unsigned Priority = 65535) const;
- virtual const MCSection *
- getStaticDtorSection(unsigned Priority = 65535) const;
-};
+ bool isSectionAtomizableBySymbols(const MCSection &Section) const override;
+ const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const override;
+ const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const override;
-class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
-public:
- virtual ~TargetLoweringObjectFileMachO() {}
+ const MCSection *getSectionForConstant(SectionKind Kind) const override;
+
+ /// The mach-o version of this method defaults to returning a stub reference.
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const override;
- /// 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;
-
- /// getTTypeGlobalReference - The mach-o version of this method
- /// defaults to returning a stub reference.
- virtual const MCExpr *
- getTTypeGlobalReference(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;
+ // The symbol that gets passed to .cfi_personality.
+ MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
+ const TargetMachine &TM,
+ MachineModuleInfo *MMI) const override;
};
@@ -121,19 +121,25 @@ 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;
-
- /// emitModuleFlags - Emit Obj-C garbage collection and linker options. Only
- /// linker option emission is implemented for COFF.
- virtual void emitModuleFlags(MCStreamer &Streamer,
- ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
- Mangler *Mang, const TargetMachine &TM) const;
+ const MCSection *
+ getExplicitSectionGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const override;
+
+ const MCSection *
+ SelectSectionForGlobal(const GlobalValue *GV,
+ SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM) const override;
+
+ /// Extract the dependent library name from a linker option string. Returns
+ /// StringRef() if the option does not specify a library.
+ StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
+
+ /// Emit Obj-C garbage collection and linker options. Only linker option
+ /// emission is implemented for COFF.
+ void emitModuleFlags(MCStreamer &Streamer,
+ ArrayRef<Module::ModuleFlagEntry> ModuleFlags,
+ Mangler &Mang, const TargetMachine &TM) const override;
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
index 8ef26b7..4e178d0 100644
--- a/include/llvm/CodeGen/TargetSchedule.h
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -98,6 +98,14 @@ public:
return SchedModel.getProcResource(PIdx);
}
+#ifndef NDEBUG
+ const char *getResourceName(unsigned PIdx) const {
+ if (!PIdx)
+ return "MOps";
+ return SchedModel.getProcResource(PIdx)->Name;
+ }
+#endif
+
typedef const MCWriteProcResEntry *ProcResIter;
// \brief Get an iterator into the processor resources consumed by this
@@ -150,7 +158,7 @@ public:
/// model.
///
/// Compute and return the expected latency of this instruction independent of
- /// a particular use. computeOperandLatency is the prefered API, but this is
+ /// a particular use. computeOperandLatency is the preferred API, but this is
/// occasionally useful to help estimate instruction cost.
///
/// If UseDefaultDefLatency is false and no new machine sched model is
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index 79f3233..8cf26fa 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -16,559 +16,14 @@
#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 "llvm/CodeGen/MachineValueType.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 an MVT.
- class MVT {
- public:
- enum SimpleValueType {
- // INVALID_SIMPLE_VALUE_TYPE - Simple value types less than zero are
- // considered extended value types.
- INVALID_SIMPLE_VALUE_TYPE = -1,
-
- // If you change this numbering, you must change the values in
- // ValueTypes.td as well!
- Other = 0, // This is a non-standard value
- 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,
-
- v2i1 = 13, // 2 x i1
- v4i1 = 14, // 4 x i1
- v8i1 = 15, // 8 x i1
- v16i1 = 16, // 16 x i1
- v32i1 = 17, // 32 x i1
- v64i1 = 18, // 64 x i1
-
- v1i8 = 19, // 1 x i8
- v2i8 = 20, // 2 x i8
- v4i8 = 21, // 4 x i8
- v8i8 = 22, // 8 x i8
- v16i8 = 23, // 16 x i8
- v32i8 = 24, // 32 x i8
- v64i8 = 25, // 64 x i8
- v1i16 = 26, // 1 x i16
- v2i16 = 27, // 2 x i16
- v4i16 = 28, // 4 x i16
- v8i16 = 29, // 8 x i16
- v16i16 = 30, // 16 x i16
- v32i16 = 31, // 32 x i16
- v1i32 = 32, // 1 x i32
- v2i32 = 33, // 2 x i32
- v4i32 = 34, // 4 x i32
- v8i32 = 35, // 8 x i32
- v16i32 = 36, // 16 x i32
- v1i64 = 37, // 1 x i64
- v2i64 = 38, // 2 x i64
- v4i64 = 39, // 4 x i64
- v8i64 = 40, // 8 x i64
- v16i64 = 41, // 16 x i64
-
- FIRST_INTEGER_VECTOR_VALUETYPE = v2i1,
- LAST_INTEGER_VECTOR_VALUETYPE = v16i64,
-
- v2f16 = 42, // 2 x f16
- v4f16 = 43, // 4 x f16
- v8f16 = 44, // 8 x f16
- v1f32 = 45, // 1 x f32
- v2f32 = 46, // 2 x f32
- v4f32 = 47, // 4 x f32
- v8f32 = 48, // 8 x f32
- v16f32 = 49, // 16 x f32
- v1f64 = 50, // 1 x f64
- v2f64 = 51, // 2 x f64
- v4f64 = 52, // 4 x f64
- v8f64 = 53, // 8 x f64
-
- FIRST_FP_VECTOR_VALUETYPE = v2f16,
- LAST_FP_VECTOR_VALUETYPE = v8f64,
-
- FIRST_VECTOR_VALUETYPE = v2i1,
- LAST_VECTOR_VALUETYPE = v8f64,
-
- x86mmx = 54, // This is an X86 MMX value
-
- Glue = 55, // This glues nodes together during pre-RA sched
-
- isVoid = 56, // This has no value
-
- Untyped = 57, // This value takes a register, but has
- // unspecified type. The register class
- // will be determined by the opcode.
-
- LAST_VALUETYPE = 58, // 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
- };
-
- 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::FIRST_INTEGER_VECTOR_VALUETYPE &&
- SimpleTy <= MVT::LAST_INTEGER_VECTOR_VALUETYPE));
- }
-
- /// isVector - Return true if this is a vector value type.
- bool isVector() const {
- return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
- SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
- }
-
- /// is16BitVector - Return true if this is a 16-bit vector type.
- bool is16BitVector() const {
- return (SimpleTy == MVT::v2i8 || SimpleTy == MVT::v1i16 ||
- SimpleTy == MVT::v16i1);
- }
-
- /// is32BitVector - Return true if this is a 32-bit vector type.
- bool is32BitVector() const {
- return (SimpleTy == MVT::v4i8 || SimpleTy == MVT::v2i16 ||
- SimpleTy == MVT::v1i32);
- }
-
- /// is64BitVector - Return true if this is a 64-bit vector type.
- bool is64BitVector() const {
- return (SimpleTy == MVT::v8i8 || SimpleTy == MVT::v4i16 ||
- SimpleTy == MVT::v2i32 || SimpleTy == MVT::v1i64 ||
- SimpleTy == MVT::v1f64 || SimpleTy == MVT::v2f32);
- }
-
- /// is128BitVector - Return true if this is a 128-bit vector type.
- bool is128BitVector() const {
- return (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v8i16 ||
- SimpleTy == MVT::v4i32 || SimpleTy == MVT::v2i64 ||
- SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64);
- }
-
- /// is256BitVector - Return true if this is a 256-bit vector type.
- bool is256BitVector() const {
- return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 ||
- SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 ||
- SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64);
- }
-
- /// is512BitVector - Return true if this is a 512-bit vector type.
- bool is512BitVector() const {
- return (SimpleTy == MVT::v8f64 || SimpleTy == MVT::v16f32 ||
- SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 ||
- SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32);
- }
-
- /// is1024BitVector - Return true if this is a 1024-bit vector type.
- bool is1024BitVector() const {
- return (SimpleTy == MVT::v16i64);
- }
-
- /// 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:
- llvm_unreachable("Not a vector MVT!");
- case v2i1 :
- case v4i1 :
- case v8i1 :
- case v16i1 :
- case v32i1 :
- case v64i1: return i1;
- case v1i8 :
- case v2i8 :
- case v4i8 :
- case v8i8 :
- case v16i8:
- case v32i8:
- case v64i8: return i8;
- case v1i16:
- case v2i16:
- case v4i16:
- case v8i16:
- case v16i16:
- case v32i16: return i16;
- case v1i32:
- case v2i32:
- case v4i32:
- case v8i32:
- case v16i32: return i32;
- case v1i64:
- case v2i64:
- case v4i64:
- case v8i64:
- case v16i64: return i64;
- case v2f16:
- case v4f16:
- case v8f16: return f16;
- case v1f32:
- case v2f32:
- case v4f32:
- case v8f32:
- case v16f32: return f32;
- case v1f64:
- case v2f64:
- case v4f64:
- case v8f64: return f64;
- }
- }
-
- unsigned getVectorNumElements() const {
- switch (SimpleTy) {
- default:
- llvm_unreachable("Not a vector MVT!");
- case v32i1:
- case v32i8:
- case v32i16: return 32;
- case v64i1:
- case v64i8: return 64;
- case v16i1:
- case v16i8:
- case v16i16:
- case v16i32:
- case v16i64:
- case v16f32: return 16;
- case v8i1 :
- case v8i8 :
- case v8i16:
- case v8i32:
- case v8i64:
- case v8f16:
- case v8f32:
- case v8f64: return 8;
- case v4i1:
- case v4i8:
- case v4i16:
- case v4i32:
- case v4i64:
- case v4f16:
- case v4f32:
- case v4f64: return 4;
- case v2i1:
- case v2i8:
- case v2i16:
- case v2i32:
- case v2i64:
- case v2f16:
- case v2f32:
- case v2f64: return 2;
- case v1i8:
- case v1i16:
- case v1i32:
- case v1i64:
- case v1f32:
- case v1f64: return 1;
- }
- }
-
- unsigned getSizeInBits() const {
- switch (SimpleTy) {
- default:
- llvm_unreachable("getSizeInBits called on extended MVT.");
- case Other:
- llvm_unreachable("Value type is non-standard value, Other.");
- case iPTR:
- llvm_unreachable("Value type size is target-dependent. Ask TLI.");
- case iPTRAny:
- case iAny:
- case fAny:
- case vAny:
- llvm_unreachable("Value type is overloaded.");
- case Metadata:
- llvm_unreachable("Value type is metadata.");
- case i1 : return 1;
- case v2i1: return 2;
- case v4i1: return 4;
- case i8 :
- case v1i8:
- case v8i1: return 8;
- case i16 :
- case f16:
- case v16i1:
- case v2i8:
- case v1i16: return 16;
- case f32 :
- case i32 :
- case v32i1:
- case v4i8:
- case v2i16:
- case v2f16:
- case v1f32:
- case v1i32: return 32;
- case x86mmx:
- case f64 :
- case i64 :
- case v64i1:
- case v8i8:
- case v4i16:
- case v2i32:
- case v1i64:
- case v4f16:
- case v2f32:
- case v1f64: return 64;
- case f80 : return 80;
- case f128:
- case ppcf128:
- case i128:
- case v16i8:
- case v8i16:
- case v4i32:
- case v2i64:
- case v8f16:
- case v4f32:
- case v2f64: return 128;
- case v32i8:
- case v16i16:
- case v8i32:
- case v4i64:
- case v8f32:
- case v4f64: return 256;
- case v64i8:
- case v32i16:
- case v16i32:
- case v8i64:
- case v16f32:
- case v8f64: return 512;
- case v16i64:return 1024;
- }
- }
-
- /// 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;
- }
-
- /// Return true if this has more bits than VT.
- bool bitsGT(MVT VT) const {
- return getSizeInBits() > VT.getSizeInBits();
- }
-
- /// Return true if this has no less bits than VT.
- bool bitsGE(MVT VT) const {
- return getSizeInBits() >= VT.getSizeInBits();
- }
-
- /// Return true if this has less bits than VT.
- bool bitsLT(MVT VT) const {
- return getSizeInBits() < VT.getSizeInBits();
- }
-
- /// Return true if this has no more bits than VT.
- bool bitsLE(MVT VT) const {
- return getSizeInBits() <= VT.getSizeInBits();
- }
-
-
- static MVT getFloatingPointVT(unsigned BitWidth) {
- switch (BitWidth) {
- default:
- 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::i1:
- if (NumElements == 2) return MVT::v2i1;
- if (NumElements == 4) return MVT::v4i1;
- if (NumElements == 8) return MVT::v8i1;
- if (NumElements == 16) return MVT::v16i1;
- if (NumElements == 32) return MVT::v32i1;
- if (NumElements == 64) return MVT::v64i1;
- break;
- case MVT::i8:
- if (NumElements == 1) return MVT::v1i8;
- if (NumElements == 2) return MVT::v2i8;
- if (NumElements == 4) return MVT::v4i8;
- if (NumElements == 8) return MVT::v8i8;
- if (NumElements == 16) return MVT::v16i8;
- if (NumElements == 32) return MVT::v32i8;
- if (NumElements == 64) return MVT::v64i8;
- break;
- case MVT::i16:
- if (NumElements == 1) return MVT::v1i16;
- if (NumElements == 2) return MVT::v2i16;
- if (NumElements == 4) return MVT::v4i16;
- if (NumElements == 8) return MVT::v8i16;
- if (NumElements == 16) return MVT::v16i16;
- if (NumElements == 32) return MVT::v32i16;
- break;
- case MVT::i32:
- if (NumElements == 1) return MVT::v1i32;
- if (NumElements == 2) return MVT::v2i32;
- if (NumElements == 4) return MVT::v4i32;
- if (NumElements == 8) return MVT::v8i32;
- if (NumElements == 16) return MVT::v16i32;
- 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;
- if (NumElements == 16) return MVT::v16i64;
- break;
- case MVT::f16:
- if (NumElements == 2) return MVT::v2f16;
- if (NumElements == 4) return MVT::v4f16;
- if (NumElements == 8) return MVT::v8f16;
- break;
- case MVT::f32:
- if (NumElements == 1) return MVT::v1f32;
- if (NumElements == 2) return MVT::v2f32;
- if (NumElements == 4) return MVT::v4f32;
- if (NumElements == 8) return MVT::v8f32;
- if (NumElements == 16) return MVT::v16f32;
- break;
- case MVT::f64:
- if (NumElements == 1) return MVT::v1f64;
- if (NumElements == 2) return MVT::v2f64;
- if (NumElements == 4) return MVT::v4f64;
- if (NumElements == 8) return MVT::v8f64;
- break;
- }
- return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
- }
-
- /// Return the value type corresponding to the specified type. This returns
- /// all pointers as iPTR. If HandleUnknown is true, unknown types are
- /// returned as Other, otherwise they are invalid.
- static MVT getVT(Type *Ty, bool HandleUnknown = false);
-
- };
+ class LLVMContext;
+ class 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
@@ -782,6 +237,10 @@ namespace llvm {
return getExtendedSizeInBits();
}
+ unsigned getScalarSizeInBits() const {
+ return getScalarType().getSizeInBits();
+ }
+
/// getStoreSize - Return the number of bytes overwritten by a store
/// of the specified value type.
unsigned getStoreSize() const {
@@ -821,6 +280,14 @@ namespace llvm {
return getIntegerVT(Context, (EVTSize + 1) / 2);
}
+ /// \brief Return a VT for an integer vector type with the size of the
+ /// elements doubled. The typed returned may be an extended type.
+ EVT widenIntegerVectorElementType(LLVMContext &Context) const {
+ EVT EltVT = getVectorElementType();
+ EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
+ return EVT::getVectorVT(Context, EltVT, getVectorNumElements());
+ }
+
/// isPow2VectorType - Returns true if the given vector is a power of 2.
bool isPow2VectorType() const {
unsigned NElts = getVectorNumElements();
@@ -880,18 +347,18 @@ namespace llvm {
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 isExtended16BitVector() const;
- bool isExtended32BitVector() const;
- bool isExtended64BitVector() const;
- bool isExtended128BitVector() const;
- bool isExtended256BitVector() const;
- bool isExtended512BitVector() const;
- bool isExtended1024BitVector() const;
+ bool isExtendedFloatingPoint() const LLVM_READONLY;
+ bool isExtendedInteger() const LLVM_READONLY;
+ bool isExtendedVector() const LLVM_READONLY;
+ bool isExtended16BitVector() const LLVM_READONLY;
+ bool isExtended32BitVector() const LLVM_READONLY;
+ bool isExtended64BitVector() const LLVM_READONLY;
+ bool isExtended128BitVector() const LLVM_READONLY;
+ bool isExtended256BitVector() const LLVM_READONLY;
+ bool isExtended512BitVector() const LLVM_READONLY;
+ bool isExtended1024BitVector() const LLVM_READONLY;
EVT getExtendedVectorElementType() const;
- unsigned getExtendedVectorNumElements() const;
+ unsigned getExtendedVectorNumElements() const LLVM_READONLY;
unsigned getExtendedSizeInBits() const;
};
diff --git a/include/llvm/CodeGen/VirtRegMap.h b/include/llvm/CodeGen/VirtRegMap.h
index 3bc6ebd..89b5a9f 100644
--- a/include/llvm/CodeGen/VirtRegMap.h
+++ b/include/llvm/CodeGen/VirtRegMap.h
@@ -70,9 +70,9 @@ namespace llvm {
static char ID;
VirtRegMap() : MachineFunctionPass(ID), Virt2PhysMap(NO_PHYS_REG),
Virt2StackSlotMap(NO_STACK_SLOT), Virt2SplitMap(0) { }
- virtual bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &MF) override;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -177,7 +177,7 @@ namespace llvm {
/// the specified stack slot
void assignVirt2StackSlot(unsigned virtReg, int frameIndex);
- void print(raw_ostream &OS, const Module* M = 0) const;
+ void print(raw_ostream &OS, const Module* M = 0) const override;
void dump() const;
};
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 5c72ad8..ea1e75a 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -212,6 +212,9 @@
/* Define to 1 if you have the 'z' library (-lz). */
#cmakedefine HAVE_LIBZ ${HAVE_LIBZ}
+/* Define to 1 if you have the 'edit' library (-ledit). */
+#cmakedefine HAVE_LIBEDIT ${HAVE_LIBEDIT}
+
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H}
@@ -495,6 +498,9 @@
/* Linker version detected at compile time. */
#undef HOST_LINK_VERSION
+/* Define if we link Polly to the tools */
+#cmakedefine LINK_POLLY_INTO_TOOLS
+
/* Installation directory for binary executables */
#cmakedefine LLVM_BINDIR "${LLVM_BINDIR}"
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index dcec8f8..6b8dbb7 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -3,9 +3,6 @@
#ifndef CONFIG_H
#define CONFIG_H
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
/* Bug report URL. */
#undef BUG_REPORT_URL
@@ -36,27 +33,6 @@
/* Directory where gcc is installed. */
#undef GCC_INSTALL_PREFIX
-/* Define to 1 if you have the `arc4random' function. */
-#undef HAVE_ARC4RANDOM
-
-/* Define to 1 if you have the `argz_append' function. */
-#undef HAVE_ARGZ_APPEND
-
-/* Define to 1 if you have the `argz_create_sep' function. */
-#undef HAVE_ARGZ_CREATE_SEP
-
-/* Define to 1 if you have the <argz.h> header file. */
-#undef HAVE_ARGZ_H
-
-/* Define to 1 if you have the `argz_insert' function. */
-#undef HAVE_ARGZ_INSERT
-
-/* Define to 1 if you have the `argz_next' function. */
-#undef HAVE_ARGZ_NEXT
-
-/* Define to 1 if you have the `argz_stringify' function. */
-#undef HAVE_ARGZ_STRINGIFY
-
/* Define to 1 if you have the `backtrace' function. */
#undef HAVE_BACKTRACE
@@ -66,9 +42,6 @@
/* Define if the neat program is available */
#undef HAVE_CIRCO
-/* Define to 1 if you have the `closedir' function. */
-#undef HAVE_CLOSEDIR
-
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
@@ -78,6 +51,10 @@
/* Define to 1 if you have the <cxxabi.h> header file. */
#undef HAVE_CXXABI_H
+/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
+ don't. */
+#undef HAVE_DECL_ARC4RANDOM
+
/* Define to 1 if you have the declaration of `FE_ALL_EXCEPT', and to 0 if you
don't. */
#undef HAVE_DECL_FE_ALL_EXCEPT
@@ -94,12 +71,6 @@
*/
#undef HAVE_DIRENT_H
-/* Define if you have the GNU dld library. */
-#undef HAVE_DLD
-
-/* Define to 1 if you have the `dlerror' function. */
-#undef HAVE_DLERROR
-
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
@@ -112,15 +83,9 @@
/* Define if the dotty program is available */
#undef HAVE_DOTTY
-/* Define if you have the _dyld_func_lookup function. */
-#undef HAVE_DYLD
-
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
-/* Define to 1 if the system has the type `error_t'. */
-#undef HAVE_ERROR_T
-
/* Define to 1 if you have the <execinfo.h> header file. */
#undef HAVE_EXECINFO_H
@@ -205,8 +170,8 @@
/* Set to 1 if the isnan function is found in <math.h> */
#undef HAVE_ISNAN_IN_MATH_H
-/* Define if you have the libdl library or equivalent. */
-#undef HAVE_LIBDL
+/* Define if libedit is available on this platform. */
+#undef HAVE_LIBEDIT
/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
#undef HAVE_LIBIMAGEHLP
@@ -254,9 +219,6 @@
/* Define to 1 if you have the <mach/mach.h> header file. */
#undef HAVE_MACH_MACH_H
-/* Define to 1 if you have the <mach-o/dyld.h> header file. */
-#undef HAVE_MACH_O_DYLD_H
-
/* Define if mallinfo() is available on this platform. */
#undef HAVE_MALLINFO
@@ -300,9 +262,6 @@
/* Define if the neat program is available */
#undef HAVE_NEATO
-/* Define to 1 if you have the `opendir' function. */
-#undef HAVE_OPENDIR
-
/* Define to 1 if you have the `posix_spawn' function. */
#undef HAVE_POSIX_SPAWN
@@ -312,9 +271,6 @@
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
-/* Define if libtool can extract symbol lists from object files. */
-#undef HAVE_PRELOADED_SYMBOLS
-
/* Define to have the %a format string */
#undef HAVE_PRINTF_A
@@ -333,9 +289,6 @@
/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
#undef HAVE_RAND48
-/* Define to 1 if you have the `readdir' function. */
-#undef HAVE_READDIR
-
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
@@ -363,9 +316,6 @@
/* Define to 1 if you have the `setrlimit' function. */
#undef HAVE_SETRLIMIT
-/* Define if you have the shl_load function. */
-#undef HAVE_SHL_LOAD
-
/* Define to 1 if you have the `siglongjmp' function. */
#undef HAVE_SIGLONGJMP
@@ -641,26 +591,16 @@
/* Minor version of the LLVM API */
#undef LLVM_VERSION_MINOR
-/* Define if the OS needs help to load dependent libraries for dlopen(). */
-#undef LTDL_DLOPEN_DEPLIBS
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LTDL_OBJDIR
+/* Patch version of the LLVM API */
+#undef LLVM_VERSION_PATCH
-/* Define to the extension used for shared libraries, say, ".so". */
+/* The shared library extension */
#undef LTDL_SHLIB_EXT
-/* Define to the system default library search path. */
-#undef LTDL_SYSSEARCHPATH
-
/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
its not necessary */
#undef NEED_DEV_ZERO_FOR_MMAP
-/* Define if dlsym() requires a leading underscore in symbol names. */
-#undef NEED_USCORE
-
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
@@ -673,9 +613,6 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@@ -700,24 +637,6 @@
/* Type of 1st arg on ELM Callback */
#undef WIN32_ELMCB_PCSTR
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-# undef WORDS_BIGENDIAN
-# endif
-#endif
-
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to a type to use for `error_t' if it is not otherwise available. */
-#undef error_t
-
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index 80616ef..65116cb 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -121,7 +121,7 @@
/* Minor version of the LLVM API */
#cmakedefine LLVM_VERSION_MINOR ${LLVM_VERSION_MINOR}
-/* Define to 1 if you have the <sanitizer/msan_interface.h> header file. */
-#cmakedefine HAVE_SANITIZER_MSAN_INTERFACE_H ${HAVE_SANITIZER_MSAN_INTERFACE_H}
+/* Define if we link Polly to the tools */
+#cmakedefine LINK_POLLY_INTO_TOOLS
#endif
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index a1a4642..69a4f8d 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -105,8 +105,11 @@ enum DIDumpType {
DIDT_Info,
DIDT_InfoDwo,
DIDT_Types,
+ DIDT_TypesDwo,
DIDT_Line,
+ DIDT_LineDwo,
DIDT_Loc,
+ DIDT_LocDwo,
DIDT_Ranges,
DIDT_Pubnames,
DIDT_Pubtypes,
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 233084d..4dca870 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -18,11 +18,11 @@
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/ValueMap.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueMap.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <map>
@@ -48,6 +48,11 @@ class RTDyldMemoryManager;
class Triple;
class Type;
+namespace object {
+ class Archive;
+ class ObjectFile;
+}
+
/// \brief Helper class for helping synchronize access to the global address map
/// table.
class ExecutionEngineState {
@@ -106,7 +111,7 @@ class ExecutionEngine {
ExecutionEngineState EEState;
/// The target data for the platform for which execution is being performed.
- const DataLayout *TD;
+ const DataLayout *DL;
/// Whether lazy JIT compilation is enabled.
bool CompilingLazily;
@@ -125,7 +130,7 @@ protected:
/// optimize for the case where there is only one module.
SmallVector<Module*, 1> Modules;
- void setDataLayout(const DataLayout *td) { TD = td; }
+ void setDataLayout(const DataLayout *Val) { DL = Val; }
/// getMemoryforGV - Allocate memory for a global variable.
virtual char *getMemoryForGV(const GlobalVariable *GV);
@@ -204,9 +209,36 @@ public:
Modules.push_back(M);
}
+ /// addObjectFile - Add an ObjectFile to the execution engine.
+ ///
+ /// This method is only supported by MCJIT. MCJIT will immediately load the
+ /// object into memory and adds its symbols to the list used to resolve
+ /// external symbols while preparing other objects for execution.
+ ///
+ /// Objects added using this function will not be made executable until
+ /// needed by another object.
+ ///
+ /// MCJIT will take ownership of the ObjectFile.
+ virtual void addObjectFile(object::ObjectFile *O) {
+ llvm_unreachable(
+ "ExecutionEngine subclass doesn't implement addObjectFile.");
+ }
+
+ /// addArchive - Add an Archive to the execution engine.
+ ///
+ /// This method is only supported by MCJIT. MCJIT will use the archive to
+ /// resolve external symbols in objects it is loading. If a symbol is found
+ /// in the Archive the contained object file will be extracted (in memory)
+ /// and loaded for possible execution.
+ ///
+ /// MCJIT will take ownership of the Archive.
+ virtual void addArchive(object::Archive *A) {
+ llvm_unreachable("ExecutionEngine subclass doesn't implement addArchive.");
+ }
+
//===--------------------------------------------------------------------===//
- const DataLayout *getDataLayout() const { return TD; }
+ const DataLayout *getDataLayout() const { return DL; }
/// removeModule - Remove a Module from the list of modules. Returns true if
/// M is found.
@@ -232,7 +264,7 @@ public:
///
/// This function is deprecated for the MCJIT execution engine.
///
- /// FIXME: the JIT and MCJIT interfaces should be disentangled or united
+ /// FIXME: the JIT and MCJIT interfaces should be disentangled or united
/// again, if possible.
///
virtual void *getPointerToNamedFunction(const std::string &Name,
@@ -430,6 +462,24 @@ public:
llvm_unreachable("No support for an object cache");
}
+ /// setProcessAllSections (MCJIT Only): By default, only sections that are
+ /// "required for execution" are passed to the RTDyldMemoryManager, and other
+ /// sections are discarded. Passing 'true' to this method will cause
+ /// RuntimeDyld to pass all sections to its RTDyldMemoryManager regardless
+ /// of whether they are "required to execute" in the usual sense.
+ ///
+ /// Rationale: Some MCJIT clients want to be able to inspect metadata
+ /// sections (e.g. Dwarf, Stack-maps) to enable functionality or analyze
+ /// performance. Passing these sections to the memory manager allows the
+ /// client to make policy about the relevant sections, rather than having
+ /// MCJIT do it.
+ virtual void setProcessAllSections(bool ProcessAllSections) {
+ llvm_unreachable("No support for ProcessAllSections option");
+ }
+
+ /// Return the target machine (if available).
+ virtual TargetMachine *getTargetMachine() { return NULL; }
+
/// 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
@@ -550,7 +600,7 @@ public:
WhichEngine = w;
return *this;
}
-
+
/// setMCJITMemoryManager - Sets the MCJIT memory manager to use. This allows
/// clients to customize their memory allocation policies for the MCJIT. This
/// is only appropriate for the MCJIT; setting this and configuring the builder
diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h
index ed66102..8daf2bd 100644
--- a/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/include/llvm/ExecutionEngine/JITEventListener.h
@@ -16,8 +16,8 @@
#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
#include "llvm/Config/llvm-config.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/DebugLoc.h"
#include <vector>
namespace llvm {
diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h
index af2a926..071a42b 100644
--- a/include/llvm/ExecutionEngine/ObjectBuffer.h
+++ b/include/llvm/ExecutionEngine/ObjectBuffer.h
@@ -1,6 +1,6 @@
//===---- ObjectBuffer.h - Utility class to wrap object image memory -----===//
//
-// The LLVM Compiler Infrastructure
+// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
@@ -15,7 +15,6 @@
#ifndef LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
#define LLVM_EXECUTIONENGINE_OBJECTBUFFER_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
@@ -49,7 +48,7 @@ public:
protected:
// The memory contained in an ObjectBuffer
- OwningPtr<MemoryBuffer> Buffer;
+ std::unique_ptr<MemoryBuffer> Buffer;
};
/// ObjectBufferStream - This class encapsulates the SmallVector and
@@ -57,7 +56,7 @@ protected:
/// while providing a common ObjectBuffer interface for access to the
/// memory once the object has been generated.
class ObjectBufferStream : public ObjectBuffer {
- virtual void anchor();
+ void anchor() override;
public:
ObjectBufferStream() : OS(SV) {}
virtual ~ObjectBufferStream() {}
@@ -69,13 +68,13 @@ public:
// Make the data accessible via the ObjectBuffer::Buffer
Buffer.reset(MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()),
- "",
- false));
+ "",
+ false));
}
protected:
SmallVector<char, 4096> SV; // Working buffer into which we JIT.
- raw_svector_ostream OS; // streaming wrapper
+ raw_svector_ostream OS; // streaming wrapper
};
} // namespace llvm
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h
index 076f4b1..1a13647 100644
--- a/include/llvm/ExecutionEngine/ObjectImage.h
+++ b/include/llvm/ExecutionEngine/ObjectImage.h
@@ -1,6 +1,6 @@
//===---- ObjectImage.h - Format independent executuable object image -----===//
//
-// The LLVM Compiler Infrastructure
+// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
@@ -28,7 +28,7 @@ class ObjectImage {
virtual void anchor();
protected:
- OwningPtr<ObjectBuffer> Buffer;
+ std::unique_ptr<ObjectBuffer> Buffer;
public:
ObjectImage(ObjectBuffer *Input) : Buffer(Input) {}
@@ -45,9 +45,9 @@ public:
// Subclasses can override these methods to update the image with loaded
// addresses for sections and common symbols
virtual void updateSectionAddress(const object::SectionRef &Sec,
- uint64_t Addr) = 0;
+ uint64_t Addr) = 0;
virtual void updateSymbolAddress(const object::SymbolRef &Sym,
- uint64_t Addr) = 0;
+ uint64_t Addr) = 0;
virtual StringRef getData() const = 0;
@@ -61,4 +61,3 @@ public:
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_OBJECTIMAGE_H
-
diff --git a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
index 3ad2e50..70dd1cb 100644
--- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
+++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
@@ -14,10 +14,10 @@
#ifndef LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H
#define LLVM_EXECUTIONENGINE_RT_DYLD_MEMORY_MANAGER_H
+#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Memory.h"
-#include "llvm-c/ExecutionEngine.h"
namespace llvm {
@@ -52,6 +52,20 @@ public:
uintptr_t Size, unsigned Alignment, unsigned SectionID,
StringRef SectionName, bool IsReadOnly) = 0;
+ /// Inform the memory manager about the total amount of memory required to
+ /// allocate all sections to be loaded:
+ /// \p CodeSize - the total size of all code sections
+ /// \p DataSizeRO - the total size of all read-only data sections
+ /// \p DataSizeRW - the total size of all read-write data sections
+ ///
+ /// Note that by default the callback is disabled. To enable it
+ /// redefine the method needsToReserveAllocationSpace to return true.
+ virtual void reserveAllocationSpace(
+ uintptr_t CodeSize, uintptr_t DataSizeRO, uintptr_t DataSizeRW) { }
+
+ /// Override to return true to enable the reserveAllocationSpace callback.
+ virtual bool needsToReserveAllocationSpace() { return false; }
+
/// Register the EH frames with the runtime so that c++ exceptions work.
///
/// \p Addr parameter provides the local address of the EH frame section
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index b832438..8d7b81b 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -21,6 +21,10 @@
namespace llvm {
+namespace object {
+ class ObjectFile;
+}
+
class RuntimeDyldImpl;
class ObjectImage;
@@ -32,6 +36,7 @@ class RuntimeDyld {
// interface.
RuntimeDyldImpl *Dyld;
RTDyldMemoryManager *MM;
+ bool ProcessAllSections;
protected:
// Change the address associated with a section when resolving relocations.
// Any relocations already associated with the symbol will be re-resolved.
@@ -46,6 +51,12 @@ public:
/// failure, the input buffer will be deleted.
ObjectImage *loadObject(ObjectBuffer *InputBuffer);
+ /// Prepare the referenced object file for execution.
+ /// Ownership of the input object is transferred to the ObjectImage
+ /// instance returned from this function if successful. In the case of load
+ /// failure, the input object will be deleted.
+ ObjectImage *loadObject(object::ObjectFile *InputObject);
+
/// 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).
@@ -73,7 +84,21 @@ public:
void deregisterEHFrames();
+ bool hasError();
StringRef getErrorString();
+
+ /// By default, only sections that are "required for execution" are passed to
+ /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true'
+ /// to this method will cause RuntimeDyld to pass all sections to its
+ /// memory manager regardless of whether they are "required to execute" in the
+ /// usual sense. This is useful for inspecting metadata sections that may not
+ /// contain relocations, E.g. Debug info, stackmaps.
+ ///
+ /// Must be called before the first object file is loaded.
+ void setProcessAllSections(bool ProcessAllSections) {
+ assert(!Dyld && "setProcessAllSections must be called before loadObject.");
+ this->ProcessAllSections = ProcessAllSections;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
index fd6e41f..f68028b 100644
--- a/include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -48,19 +48,18 @@ public:
///
/// The value of \p Alignment must be a power of two. If \p Alignment is zero
/// a default alignment of 16 will be used.
- virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName);
+ uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) override;
/// \brief Allocates a memory block of (at least) the given size suitable for
/// executable code.
///
/// The value of \p Alignment must be a power of two. If \p Alignment is zero
/// a default alignment of 16 will be used.
- virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName,
- bool isReadOnly);
+ uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, StringRef SectionName,
+ bool isReadOnly) override;
/// \brief Update section-specific memory permissions and other attributes.
///
@@ -73,7 +72,7 @@ public:
/// operations needed to reliably use the memory are also performed.
///
/// \returns true if an error occurred, false otherwise.
- virtual bool finalizeMemory(std::string *ErrMsg = 0);
+ bool finalizeMemory(std::string *ErrMsg = 0) override;
/// \brief Invalidate instruction cache for code sections.
///
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
index eb6ed46..7c1ebf6 100644
--- a/include/llvm/IR/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -59,7 +59,12 @@ public:
/// containing function.
bool hasByValAttr() const;
- /// \brief If this is a byval argument, return its alignment.
+ /// \brief Return true if this argument has the byval attribute or inalloca
+ /// attribute on it in its containing function. These attributes both
+ /// represent arguments being passed by value.
+ bool hasByValOrInAllocaAttr() const;
+
+ /// \brief If this is a byval or inalloca argument, return its alignment.
unsigned getParamAlignment() const;
/// \brief Return true if this argument has the nest attribute on it in its
@@ -86,6 +91,9 @@ public:
/// on it in its containing function.
bool onlyReadsMemory() const;
+ /// \brief Return true if this argument has the inalloca attribute on it in
+ /// its containing function.
+ bool hasInAllocaAttr() const;
/// \brief Add a Attribute to an argument.
void addAttr(AttributeSet AS);
diff --git a/include/llvm/Assembly/AssemblyAnnotationWriter.h b/include/llvm/IR/AssemblyAnnotationWriter.h
index 37b47c3..a8d52f6 100644
--- a/include/llvm/Assembly/AssemblyAnnotationWriter.h
+++ b/include/llvm/IR/AssemblyAnnotationWriter.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ASSEMBLY_ASMANNOTATIONWRITER_H
-#define LLVM_ASSEMBLY_ASMANNOTATIONWRITER_H
+#ifndef LLVM_IR_ASMANNOTATIONWRITER_H
+#define LLVM_IR_ASMANNOTATIONWRITER_H
namespace llvm {
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index c23ba0f..9eccf40 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -71,6 +71,7 @@ public:
Builtin, ///< Callee is recognized as a builtin, despite
///< nobuiltin attribute on its declaration.
ByVal, ///< Pass structure by value
+ InAlloca, ///< Pass structure in an alloca
Cold, ///< Marks function as being in a cold path.
InlineHint, ///< Source said inlining was desirable
InReg, ///< Force argument to be passed in register
@@ -201,7 +202,7 @@ public:
/// index `1'.
class AttributeSet {
public:
- enum AttrIndex LLVM_ENUM_INT_TYPE(unsigned) {
+ enum AttrIndex : unsigned {
ReturnIndex = 0U,
FunctionIndex = ~0U
};
@@ -402,10 +403,6 @@ public:
addAttribute(A);
}
AttrBuilder(AttributeSet AS, unsigned Idx);
- AttrBuilder(const AttrBuilder &B)
- : Attrs(B.Attrs),
- TargetDepAttrs(B.TargetDepAttrs.begin(), B.TargetDepAttrs.end()),
- Alignment(B.Alignment), StackAlignment(B.StackAlignment) {}
void clear();
diff --git a/include/llvm/AutoUpgrade.h b/include/llvm/IR/AutoUpgrade.h
index c774782..076ed4a 100644
--- a/include/llvm/AutoUpgrade.h
+++ b/include/llvm/IR/AutoUpgrade.h
@@ -1,4 +1,4 @@
-//===-- llvm/AutoUpgrade.h - AutoUpgrade Helpers ----------------*- C++ -*-===//
+//===- AutoUpgrade.h - AutoUpgrade Helpers ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_AUTOUPGRADE_H
-#define LLVM_AUTOUPGRADE_H
+#ifndef LLVM_IR_AUTOUPGRADE_H
+#define LLVM_IR_AUTOUPGRADE_H
namespace llvm {
class CallInst;
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index 3bdc95d..1adc254 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -116,6 +116,8 @@ public:
const Function *getParent() const { return Parent; }
Function *getParent() { return Parent; }
+ const DataLayout *getDataLayout() const;
+
/// \brief Returns the terminator instruction if the block is well formed or
/// null if the block is not well formed.
TerminatorInst *getTerminator();
diff --git a/include/llvm/Support/CFG.h b/include/llvm/IR/CFG.h
index 74ec726..c8be8bd 100644
--- a/include/llvm/Support/CFG.h
+++ b/include/llvm/IR/CFG.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
+//===- CFG.h - Process LLVM structures as graphs ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_CFG_H
-#define LLVM_SUPPORT_CFG_H
+#ifndef LLVM_IR_CFG_H
+#define LLVM_IR_CFG_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/IR/Function.h"
@@ -34,7 +34,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
USE_iterator It;
inline void advancePastNonTerminators() {
- // Loop to ignore non terminator uses (for example BlockAddresses).
+ // Loop to ignore non-terminator uses (for example BlockAddresses).
while (!It.atEnd() && !isa<TerminatorInst>(*It))
++It;
}
@@ -44,10 +44,10 @@ public:
typedef typename super::reference reference;
PredIterator() {}
- explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
+ explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
advancePastNonTerminators();
}
- inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {}
+ inline PredIterator(Ptr *bb, bool) : It(bb->user_end()) {}
inline bool operator==(const Self& x) const { return It == x.It; }
inline bool operator!=(const Self& x) const { return !operator==(x); }
@@ -81,9 +81,9 @@ public:
}
};
-typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
+typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
typedef PredIterator<const BasicBlock,
- Value::const_use_iterator> const_pred_iterator;
+ Value::const_user_iterator> const_pred_iterator;
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
inline const_pred_iterator pred_begin(const BasicBlock *BB) {
@@ -101,23 +101,45 @@ inline const_pred_iterator pred_end(const BasicBlock *BB) {
//===----------------------------------------------------------------------===//
template <class Term_, class BB_> // Successor Iterator
-class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
- BB_, ptrdiff_t, BB_*, BB_*> {
+class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB_,
+ int, BB_ *, BB_ *> {
+ typedef std::iterator<std::random_access_iterator_tag, BB_, int, BB_ *, BB_ *>
+ super;
+
+public:
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+private:
const Term_ Term;
unsigned idx;
- typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*,
- BB_*> 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;
- typedef typename super::reference reference;
- // TODO: This can be random access iterator, only operator[] missing.
+ /// \brief Proxy object to allow write access in operator[]
+ class SuccessorProxy {
+ Self it;
+
+ public:
+ explicit SuccessorProxy(const Self &it) : it(it) {}
+
+ SuccessorProxy &operator=(SuccessorProxy r) {
+ *this = reference(r);
+ return *this;
+ }
+
+ SuccessorProxy &operator=(reference r) {
+ it.Term->setSuccessor(it.idx, r);
+ return *this;
+ }
+ operator reference() const { return *it; }
+ };
+
+public:
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
}
inline SuccIterator(Term_ T, bool) // end iterator
@@ -186,7 +208,7 @@ public:
return *this;
}
- inline Self operator+(int Right) {
+ inline Self operator+(int Right) const {
Self tmp = *this;
tmp += Right;
return tmp;
@@ -196,25 +218,21 @@ public:
return operator+=(-Right);
}
- inline Self operator-(int Right) {
+ inline Self operator-(int Right) const {
return operator+(-Right);
}
- inline int operator-(const Self& x) {
+ inline int operator-(const Self& x) const {
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*();
- // }
+ inline SuccessorProxy operator[](int offset) {
+ Self tmp = *this;
+ tmp += offset;
+ return SuccessorProxy(tmp);
+ }
/// Get the source BB of this iterator.
inline BB_ *getSource() {
diff --git a/include/llvm/IR/CMakeLists.txt b/include/llvm/IR/CMakeLists.txt
index 2d52a89..dd8e04f 100644
--- a/include/llvm/IR/CMakeLists.txt
+++ b/include/llvm/IR/CMakeLists.txt
@@ -2,6 +2,4 @@ set(LLVM_TARGET_DEFINITIONS Intrinsics.td)
tablegen(LLVM Intrinsics.gen -gen-intrinsic)
-add_custom_target(intrinsics_gen ALL
- DEPENDS ${llvm_builded_incs_dir}/IR/Intrinsics.gen)
-set_target_properties(intrinsics_gen PROPERTIES FOLDER "Tablegenning")
+add_public_tablegen_target(intrinsics_gen)
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/IR/CallSite.h
index 2a1c5ca..ec46103 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
+//===- CallSite.h - Abstract Call & Invoke instrs ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,8 +23,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_CALLSITE_H
-#define LLVM_SUPPORT_CALLSITE_H
+#ifndef LLVM_IR_CALLSITE_H
+#define LLVM_IR_CALLSITE_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/IR/Attributes.h"
@@ -103,11 +103,13 @@ public:
/// 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();
+ bool isCallee(Value::const_user_iterator UI) const {
+ return isCallee(&UI.getUse());
}
+ /// Determine whether this Use is the callee operand's Use.
+ bool isCallee(const Use *U) const { return getCallee() == U; }
+
ValTy *getArgument(unsigned ArgNo) const {
assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
return *(arg_begin() + ArgNo);
@@ -121,11 +123,17 @@ public:
/// 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 {
+ unsigned getArgumentNo(Value::const_user_iterator I) const {
+ return getArgumentNo(&I.getUse());
+ }
+
+ /// Given a use for an argument, get the argument number that corresponds to
+ /// it.
+ unsigned getArgumentNo(const Use *U) const {
assert(getInstruction() && "Not a call or invoke instruction!");
- assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end()
+ assert(arg_begin() <= U && U < arg_end()
&& "Argument # out of range!");
- return &I.getUse() - arg_begin();
+ return U - arg_begin();
}
/// arg_iterator - The type of iterator to use when looping over actual
@@ -257,6 +265,23 @@ public:
return paramHasAttr(ArgNo + 1, Attribute::ByVal);
}
+ /// @brief Determine whether this argument is passed in an alloca.
+ bool isInAllocaArgument(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::InAlloca);
+ }
+
+ /// @brief Determine whether this argument is passed by value or in an alloca.
+ bool isByValOrInAllocaArgument(unsigned ArgNo) const {
+ return paramHasAttr(ArgNo + 1, Attribute::ByVal) ||
+ paramHasAttr(ArgNo + 1, Attribute::InAlloca);
+ }
+
+ /// @brief Determine if there are is an inalloca argument. Only the last
+ /// argument can have the inalloca attribute.
+ bool hasInAllocaArgument() const {
+ return paramHasAttr(arg_size(), Attribute::InAlloca);
+ }
+
bool doesNotAccessMemory(unsigned ArgNo) const {
return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
}
diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h
index 4437af2..af44e8a 100644
--- a/include/llvm/IR/CallingConv.h
+++ b/include/llvm/IR/CallingConv.h
@@ -58,6 +58,14 @@ namespace CallingConv {
// stackmap and patchpoint intrinsics).
AnyReg = 13,
+ // PreserveMost - Calling convention for runtime calls that preserves most
+ // registers.
+ PreserveMost = 14,
+
+ // PreserveAll - Calling convention for runtime calls that preserves
+ // (almost) all registers.
+ PreserveAll = 15,
+
// Target - This is the start of the target-specific calling conventions,
// e.g. fastcall and thiscall on X86.
FirstTargetCC = 64,
@@ -129,7 +137,13 @@ namespace CallingConv {
/// convention differs from the more common \c X86_64_SysV convention
/// in a number of ways, most notably in that XMM registers used to pass
/// arguments are shadowed by GPRs, and vice versa.
- X86_64_Win64 = 79
+ X86_64_Win64 = 79,
+
+ /// \brief The calling convention used for __cdecl methods on win32.
+ /// Differs from the C calling convention only in that the order of the
+ /// first parameter and the sret parameter are swapped.
+ X86_CDeclMethod = 80
+
};
} // End CallingConv namespace
diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h
index 26bad1d..f03e3dd 100644
--- a/include/llvm/IR/Constant.h
+++ b/include/llvm/IR/Constant.h
@@ -41,8 +41,8 @@ namespace llvm {
class Constant : public User {
void operator=(const Constant &) LLVM_DELETED_FUNCTION;
Constant(const Constant &) LLVM_DELETED_FUNCTION;
- virtual void anchor();
-
+ void anchor() override;
+
protected:
Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/IR/ConstantFolder.h
index 4aad952..86668f7 100644
--- a/include/llvm/Support/ConstantFolder.h
+++ b/include/llvm/IR/ConstantFolder.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/ConstantFolder.h - Constant folding helper -*- C++ -*-===//
+//===- ConstantFolder.h - Constant folding helper ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H
-#define LLVM_SUPPORT_CONSTANTFOLDER_H
+#ifndef LLVM_IR_CONSTANTFOLDER_H
+#define LLVM_IR_CONSTANTFOLDER_H
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/IR/ConstantRange.h
index f757c6e..86988de 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/IR/ConstantRange.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
+//===- ConstantRange.h - Represent a range ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -42,13 +42,8 @@ namespace llvm {
class ConstantRange {
APInt Lower, Upper;
-#if LLVM_HAS_RVALUE_REFERENCES
// If we have move semantics, pass APInts by value and move them into place.
typedef APInt APIntMoveTy;
-#else
- // Otherwise pass by const ref to save one copy.
- typedef const APInt &APIntMoveTy;
-#endif
public:
/// Initialize a full (the default) or empty set for the specified bit width.
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index dac20c9..ed7a70f 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -25,8 +25,8 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Constant.h"
-#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/OperandTraits.h"
namespace llvm {
@@ -49,7 +49,7 @@ struct ConvertConstantType;
/// represents both boolean and integral constants.
/// @brief Class for constant integers.
class ConstantInt : public Constant {
- virtual void anchor();
+ void anchor() override;
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
ConstantInt(const ConstantInt &) LLVM_DELETED_FUNCTION;
ConstantInt(IntegerType *Ty, const APInt& V);
@@ -231,7 +231,7 @@ public:
///
class ConstantFP : public Constant {
APFloat Val;
- virtual void anchor();
+ void anchor() override;
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
ConstantFP(const ConstantFP &) LLVM_DELETED_FUNCTION;
friend class LLVMContextImpl;
@@ -255,8 +255,8 @@ public:
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);
+ static Constant *getNegativeZero(Type *Ty);
+ static Constant *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);
@@ -308,7 +308,7 @@ protected:
public:
static ConstantAggregateZero *get(Type *Ty);
- virtual void destroyConstant();
+ void destroyConstant() override;
/// getSequentialElement - If this CAZ has array or vector type, return a zero
/// with the right element type.
@@ -356,8 +356,8 @@ public:
return cast<ArrayType>(Value::getType());
}
- virtual void destroyConstant();
- virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+ void destroyConstant() override;
+ void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
@@ -414,8 +414,8 @@ public:
return cast<StructType>(Value::getType());
}
- virtual void destroyConstant();
- virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+ void destroyConstant() override;
+ void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
@@ -461,8 +461,8 @@ public:
/// 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);
+ void destroyConstant() override;
+ void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
@@ -497,7 +497,7 @@ public:
/// get() - Static factory methods - Return objects of the specified value
static ConstantPointerNull *get(PointerType *T);
- virtual void destroyConstant();
+ void destroyConstant() override;
/// getType - Specialize the getType() method to always return an PointerType,
/// which reduces the amount of casting needed in parts of the compiler.
@@ -624,7 +624,7 @@ public:
/// host endianness of the data elements.
StringRef getRawDataValues() const;
- virtual void destroyConstant();
+ void destroyConstant() override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
///
@@ -645,7 +645,7 @@ private:
class ConstantDataArray : public ConstantDataSequential {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
ConstantDataArray(const ConstantDataArray &) LLVM_DELETED_FUNCTION;
- virtual void anchor();
+ void anchor() override;
friend class ConstantDataSequential;
explicit ConstantDataArray(Type *ty, const char *Data)
: ConstantDataSequential(ty, ConstantDataArrayVal, Data) {}
@@ -697,7 +697,7 @@ public:
class ConstantDataVector : public ConstantDataSequential {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
ConstantDataVector(const ConstantDataVector &) LLVM_DELETED_FUNCTION;
- virtual void anchor();
+ void anchor() override;
friend class ConstantDataSequential;
explicit ConstantDataVector(Type *ty, const char *Data)
: ConstantDataSequential(ty, ConstantDataVectorVal, Data) {}
@@ -757,14 +757,20 @@ public:
/// block must be embedded into a function.
static BlockAddress *get(BasicBlock *BB);
+ /// \brief Lookup an existing \c BlockAddress constant for the given
+ /// BasicBlock.
+ ///
+ /// \returns 0 if \c !BB->hasAddressTaken(), otherwise the \c BlockAddress.
+ static BlockAddress *lookup(const 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);
+ void destroyConstant() override;
+ void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
@@ -1093,8 +1099,8 @@ public:
/// would make it harder to remove ConstantExprs altogether.
Instruction *getAsInstruction();
- virtual void destroyConstant();
- virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+ void destroyConstant() override;
+ void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
@@ -1158,7 +1164,7 @@ public:
/// index.
UndefValue *getElementValue(unsigned Idx) const;
- virtual void destroyConstant();
+ void destroyConstant() override;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
diff --git a/include/llvm/DIBuilder.h b/include/llvm/IR/DIBuilder.h
index bac1679..7d87a69 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/IR/DIBuilder.h
@@ -1,4 +1,4 @@
-//===--- llvm/DIBuilder.h - Debug Information Builder -----------*- C++ -*-===//
+//===- DIBuilder.h - Debug Information Builder ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,14 +12,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DIBUILDER_H
-#define LLVM_DIBUILDER_H
+#ifndef LLVM_IR_DIBUILDER_H
+#define LLVM_IR_DIBUILDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
class BasicBlock;
@@ -55,7 +55,7 @@ namespace llvm {
class DIBuilder {
private:
Module &M;
- LLVMContext & VMContext;
+ LLVMContext &VMContext;
MDNode *TempEnumTypes;
MDNode *TempRetainTypes;
@@ -72,8 +72,9 @@ namespace llvm {
SmallVector<TrackingVH<MDNode>, 4> AllRetainTypes;
SmallVector<Value *, 4> AllSubprograms;
SmallVector<Value *, 4> AllGVs;
- SmallVector<Value *, 4> AllImportedModules;
+ SmallVector<TrackingVH<MDNode>, 4> AllImportedModules;
+ // Private use for multiple types of template parameters.
DITemplateValueParameter
createTemplateValueParameter(unsigned Tag, DIDescriptor Scope,
StringRef Name, DIType Ty, Value *Val,
@@ -86,6 +87,7 @@ namespace llvm {
public:
explicit DIBuilder(Module &M);
enum ComplexAddrKind { OpPlus=1, OpDeref };
+ enum DebugEmissionKind { FullDebug=1, LineTablesOnly };
/// finalize - Construct any deferred debug info descriptors.
void finalize();
@@ -95,8 +97,8 @@ namespace llvm {
/// @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 Producer Identify the producer of debugging information and code.
+ /// Usually 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
@@ -110,7 +112,8 @@ namespace llvm {
StringRef Dir, StringRef Producer,
bool isOptimized, StringRef Flags,
unsigned RV,
- StringRef SplitName = StringRef());
+ StringRef SplitName = StringRef(),
+ DebugEmissionKind Kind = FullDebug);
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
@@ -415,10 +418,13 @@ namespace llvm {
StringRef UniqueIdentifier = StringRef());
/// createSubroutineType - Create subroutine type.
- /// @param File File in which this subroutine is defined.
- /// @param ParameterTypes An array of subroutine parameter types. This
- /// includes return type at 0th index.
- DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes);
+ /// @param File File in which this subroutine is defined.
+ /// @param ParameterTypes An array of subroutine parameter types. This
+ /// includes return type at 0th index.
+ /// @param Flags E.g.: LValueReference.
+ /// These flags are used to emit dwarf attributes.
+ DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes,
+ unsigned Flags = 0);
/// createArtificialType - Create a new DIType with "artificial" flag set.
DIType createArtificialType(DIType Ty);
@@ -439,7 +445,7 @@ namespace llvm {
/// through debug info anchors.
void retainType(DIType T);
- /// createUnspecifiedParameter - Create unspeicified type descriptor
+ /// createUnspecifiedParameter - Create unspecified type descriptor
/// for a subroutine type.
DIDescriptor createUnspecifiedParameter();
@@ -460,7 +466,7 @@ namespace llvm {
/// @param Val llvm::Value of the variable.
DIGlobalVariable
createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo,
- DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+ DITypeRef Ty, bool isLocalToUnit, llvm::Value *Val);
/// \brief Create a new descriptor for the specified global.
/// @param Name Name of the variable.
@@ -473,7 +479,7 @@ namespace llvm {
/// @param Val llvm::Value of the variable.
DIGlobalVariable
createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File,
- unsigned LineNo, DIType Ty, bool isLocalToUnit,
+ unsigned LineNo, DITypeRef Ty, bool isLocalToUnit,
llvm::Value *Val);
/// createStaticVariable - Create a new descriptor for the specified
@@ -491,7 +497,7 @@ namespace llvm {
DIGlobalVariable
createStaticVariable(DIDescriptor Context, StringRef Name,
StringRef LinkageName, DIFile File, unsigned LineNo,
- DIType Ty, bool isLocalToUnit, llvm::Value *Val,
+ DITypeRef Ty, bool isLocalToUnit, llvm::Value *Val,
MDNode *Decl = NULL);
@@ -506,13 +512,13 @@ namespace llvm {
/// @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 Flags Flags, e.g. artificial variable.
/// @param ArgNo If this variable is an argument 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,
+ DITypeRef Ty, bool AlwaysPreserve = false,
unsigned Flags = 0,
unsigned ArgNo = 0);
@@ -531,7 +537,7 @@ namespace llvm {
/// number. 1 indicates 1st argument.
DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, DIFile F, unsigned LineNo,
- DIType Ty, ArrayRef<Value *> Addr,
+ DITypeRef Ty, ArrayRef<Value *> Addr,
unsigned ArgNo = 0);
/// createFunction - Create a new descriptor for the specified subprogram.
@@ -542,11 +548,11 @@ namespace llvm {
/// @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 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.
+ /// These flags are used to emit dwarf attributes.
/// @param isOptimized True if optimization is ON.
/// @param Fn llvm::Function pointer.
/// @param TParam Function template parameters.
@@ -627,12 +633,14 @@ namespace llvm {
/// 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
+ /// @param Scope Parent lexical scope.
+ /// @param File Source file.
+ /// @param Line Line number.
+ /// @param Col Column number.
+ /// @param Discriminator DWARF path discriminator value.
DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File,
- unsigned Line, unsigned Col);
+ unsigned Line, unsigned Col,
+ unsigned Discriminator);
/// \brief Create a descriptor for an imported module.
/// @param Context The scope this module is imported into
@@ -655,7 +663,7 @@ namespace llvm {
/// variable
/// @param Line Line number
DIImportedEntity createImportedDeclaration(DIScope Context,
- DIDescriptor Decl,
+ DIScope Decl,
unsigned Line);
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index 10630a2..59dca63 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -34,6 +34,7 @@ class Type;
class IntegerType;
class StructType;
class StructLayout;
+class Triple;
class GlobalVariable;
class LLVMContext;
template<typename T>
@@ -45,8 +46,7 @@ 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
+ AGGREGATE_ALIGN = 'a' ///< Aggregate alignment
};
/// Layout alignment element.
@@ -78,38 +78,52 @@ struct LayoutAlignElem {
struct PointerAlignElem {
unsigned ABIAlign; ///< ABI alignment for this type/bitw
unsigned PrefAlign; ///< Pref. alignment for this type/bitw
- uint32_t TypeBitWidth; ///< Type bit width
+ uint32_t TypeByteWidth; ///< Type byte width
uint32_t AddressSpace; ///< Address space for the pointer type
/// Initializer
- static PointerAlignElem get(uint32_t addr_space, unsigned abi_align,
- unsigned pref_align, uint32_t bit_width);
+ static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
+ unsigned PrefAlign, uint32_t TypeByteWidth);
/// Equality predicate
bool operator==(const PointerAlignElem &rhs) const;
};
-
-/// DataLayout - This class holds a parsed version of the target data layout
-/// string in a module and provides methods for querying it. The target data
-/// layout string is specified *by the target* - a frontend generating LLVM IR
-/// is required to generate the right target data for the target being codegen'd
-/// to. If some measure of portability is desired, an empty string may be
-/// specified in the module.
-class DataLayout : public ImmutablePass {
+/// 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.
+class DataLayout {
private:
bool LittleEndian; ///< Defaults to false
unsigned StackNaturalAlign; ///< Stack natural alignment
+ enum ManglingModeT {
+ MM_None,
+ MM_ELF,
+ MM_MachO,
+ MM_WINCOFF,
+ MM_Mips
+ };
+ ManglingModeT ManglingMode;
+
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
/// Alignments - Where the primitive type alignment data is stored.
///
- /// @sa init().
+ /// @sa reset().
/// @note Could support multiple size pointer alignments, e.g., 32-bit
/// pointers vs. 64-bit pointers by extending LayoutAlignment, but for now,
/// we don't.
SmallVector<LayoutAlignElem, 16> Alignments;
- DenseMap<unsigned, PointerAlignElem> Pointers;
+ typedef SmallVector<PointerAlignElem, 8> PointersTy;
+ PointersTy Pointers;
+
+ PointersTy::const_iterator
+ findPointerLowerBound(uint32_t AddressSpace) const {
+ return const_cast<DataLayout *>(this)->findPointerLowerBound(AddressSpace);
+ }
+
+ PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace);
/// InvalidAlignmentElem - This member is a signal that a requested alignment
/// type and bit width were not found in the SmallVector.
@@ -129,8 +143,8 @@ private:
bool ABIAlign, Type *Ty) const;
//! Set/initialize pointer alignments
- void setPointerAlignment(uint32_t addr_space, unsigned abi_align,
- unsigned pref_align, uint32_t bit_width);
+ void setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
+ unsigned PrefAlign, uint32_t TypeByteWidth);
//! Internal helper method that returns requested alignment for type.
unsigned getAlignment(Type *Ty, bool abi_or_pref) const;
@@ -155,41 +169,38 @@ private:
/// malformed.
void parseSpecifier(StringRef LayoutDescription);
+ // Free all internal data structures.
+ void clear();
+
public:
- /// Default ctor.
- ///
- /// @note This has to exist, because this is a pass, but it should never be
- /// used.
- DataLayout();
-
- /// Constructs a DataLayout from a specification string. See init().
- explicit DataLayout(StringRef LayoutDescription)
- : ImmutablePass(ID) {
- init(LayoutDescription);
+ /// Constructs a DataLayout from a specification string. See reset().
+ explicit DataLayout(StringRef LayoutDescription) : LayoutMap(0) {
+ reset(LayoutDescription);
}
/// Initialize target data from properties stored in the module.
explicit DataLayout(const Module *M);
- DataLayout(const DataLayout &DL) :
- ImmutablePass(ID),
- LittleEndian(DL.isLittleEndian()),
- StackNaturalAlign(DL.StackNaturalAlign),
- LegalIntWidths(DL.LegalIntWidths),
- Alignments(DL.Alignments),
- Pointers(DL.Pointers),
- LayoutMap(0)
- { }
+ DataLayout(const DataLayout &DL) : LayoutMap(0) { *this = DL; }
+
+ DataLayout &operator=(const DataLayout &DL) {
+ clear();
+ LittleEndian = DL.isLittleEndian();
+ StackNaturalAlign = DL.StackNaturalAlign;
+ ManglingMode = DL.ManglingMode;
+ LegalIntWidths = DL.LegalIntWidths;
+ Alignments = DL.Alignments;
+ Pointers = DL.Pointers;
+ return *this;
+ }
- ~DataLayout(); // Not virtual, do not subclass this class
+ bool operator==(const DataLayout &Other) const;
+ bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
- /// DataLayout is an immutable pass, but holds state. This allows the pass
- /// manager to clear its mutable state.
- bool doFinalization(Module &M);
+ ~DataLayout(); // Not virtual, do not subclass this class
- /// Parse a data layout string (with fallback to default values). Ensure that
- /// the data layout pass is registered.
- void init(StringRef LayoutDescription);
+ /// Parse a data layout string (with fallback to default values).
+ void reset(StringRef LayoutDescription);
/// Layout endianness...
bool isLittleEndian() const { return LittleEndian; }
@@ -208,8 +219,8 @@ public:
/// 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)
+ for (unsigned LegalIntWidth : LegalIntWidths)
+ if (LegalIntWidth == Width)
return true;
return false;
}
@@ -223,13 +234,57 @@ public:
return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
}
+ bool hasMicrosoftFastStdCallMangling() const {
+ return ManglingMode == MM_WINCOFF;
+ }
+
+ bool hasLinkerPrivateGlobalPrefix() const {
+ return ManglingMode == MM_MachO;
+ }
+
+ const char *getLinkerPrivateGlobalPrefix() const {
+ if (ManglingMode == MM_MachO)
+ return "l";
+ return getPrivateGlobalPrefix();
+ }
+
+ char getGlobalPrefix() const {
+ switch (ManglingMode) {
+ case MM_None:
+ case MM_ELF:
+ case MM_Mips:
+ return '\0';
+ case MM_MachO:
+ case MM_WINCOFF:
+ return '_';
+ }
+ llvm_unreachable("invalid mangling mode");
+ }
+
+ const char *getPrivateGlobalPrefix() const {
+ switch (ManglingMode) {
+ case MM_None:
+ return "";
+ case MM_ELF:
+ return ".L";
+ case MM_Mips:
+ return "$";
+ case MM_MachO:
+ case MM_WINCOFF:
+ return "L";
+ }
+ llvm_unreachable("invalid mangling mode");
+ }
+
+ static const char *getManglingComponent(const Triple &T);
+
/// 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.
+ /// 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])
+ for (unsigned LegalIntWidth : LegalIntWidths)
+ if (Width <= LegalIntWidth)
return true;
return false;
}
@@ -237,34 +292,18 @@ public:
/// Layout pointer alignment
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
- unsigned getPointerABIAlignment(unsigned AS = 0) const {
- DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
- if (val == Pointers.end()) {
- val = Pointers.find(0);
- }
- return val->second.ABIAlign;
- }
+ unsigned getPointerABIAlignment(unsigned AS = 0) const;
/// Return target's alignment for stack-based pointers
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
- unsigned getPointerPrefAlignment(unsigned AS = 0) const {
- DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
- if (val == Pointers.end()) {
- val = Pointers.find(0);
- }
- return val->second.PrefAlign;
- }
+ unsigned getPointerPrefAlignment(unsigned AS = 0) const;
+
/// Layout pointer size
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
- unsigned getPointerSize(unsigned AS = 0) const {
- DenseMap<unsigned, PointerAlignElem>::const_iterator val = Pointers.find(AS);
- if (val == Pointers.end()) {
- val = Pointers.find(0);
- }
- return val->second.TypeBitWidth;
- }
+ unsigned getPointerSize(unsigned AS = 0) const;
+
/// Layout pointer size, in bits
/// FIXME: The defaults need to be removed once all of
/// the backends/clients are updated.
@@ -344,10 +383,6 @@ public:
/// 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;
@@ -408,6 +443,23 @@ public:
assert((Alignment & (Alignment-1)) == 0 && "Alignment must be power of 2!");
return (Val + (Alignment-1)) & ~UIntTy(Alignment-1);
}
+};
+
+class DataLayoutPass : public ImmutablePass {
+ DataLayout DL;
+
+public:
+ /// This has to exist, because this is a pass, but it should never be used.
+ DataLayoutPass();
+ ~DataLayoutPass();
+
+ const DataLayout &getDataLayout() const { return DL; }
+
+ // For use with the C API. C++ code should always use the constructor that
+ // takes a module.
+ explicit DataLayoutPass(const DataLayout &DL);
+
+ explicit DataLayoutPass(const Module *M);
static char ID; // Pass identification, replacement for typeid
};
diff --git a/include/llvm/DebugInfo.h b/include/llvm/IR/DebugInfo.h
index 768cf4e..f7244b8 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/IR/DebugInfo.h
@@ -1,4 +1,4 @@
-//===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- C++ -*-===//
+//===- DebugInfo.h - Debug Information Helpers ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,15 +14,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DEBUGINFO_H
-#define LLVM_DEBUGINFO_H
+#ifndef LLVM_IR_DEBUGINFO_H
+#define LLVM_IR_DEBUGINFO_H
-#include "llvm/Support/Casting.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Dwarf.h"
namespace llvm {
@@ -64,20 +65,22 @@ 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,
+ 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,
- FlagObjectPointer = 1 << 10,
- FlagVector = 1 << 11,
- FlagStaticMember = 1 << 12,
- FlagIndirectVariable = 1 << 13
+ FlagObjectPointer = 1 << 10,
+ FlagVector = 1 << 11,
+ FlagStaticMember = 1 << 12,
+ FlagIndirectVariable = 1 << 13,
+ FlagLValueReference = 1 << 14,
+ FlagRValueReference = 1 << 15
};
protected:
@@ -194,6 +197,13 @@ typedef DIRef<DIScope> DIScopeRef;
typedef DIRef<DIType> DITypeRef;
/// DIScope - A base class for various scopes.
+///
+/// Although, implementation-wise, DIScope is the parent class of most
+/// other DIxxx classes, including DIType and its descendants, most of
+/// DIScope's descendants are not a substitutable subtype of
+/// DIScope. The DIDescriptor::isScope() method only is true for
+/// DIScopes that are scopes in the strict lexical scope sense
+/// (DICompileUnit, DISubprogram, etc.), but not for, e.g., a DIType.
class DIScope : public DIDescriptor {
protected:
friend class DIDescriptor;
@@ -222,6 +232,7 @@ template <typename T> class DIRef {
friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
friend DIScopeRef DIScope::getContext() const;
friend DIScopeRef DIScope::getRef() const;
+ friend class DIType;
/// Val can be either a MDNode or a MDString, in the latter,
/// MDString specifies the type identifier.
@@ -282,6 +293,11 @@ protected:
public:
explicit DIType(const MDNode *N = 0) : DIScope(N) {}
+ operator DITypeRef () const {
+ assert(isType() &&
+ "constructing DITypeRef from an MDNode that is not a type");
+ return DITypeRef(&*getRef());
+ }
/// Verify - Verify that a type descriptor is well formed.
bool Verify() const;
@@ -313,6 +329,12 @@ public:
}
bool isVector() const { return (getFlags() & FlagVector) != 0; }
bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
+ bool isLValueReference() const {
+ return (getFlags() & FlagLValueReference) != 0;
+ }
+ bool isRValueReference() const {
+ return (getFlags() & FlagRValueReference) != 0;
+ }
bool isValid() const { return DbgNode && isType(); }
/// replaceAllUsesWith - Replace all uses of debug info referenced by
@@ -377,7 +399,6 @@ public:
DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
- void addMember(DIDescriptor D);
unsigned getRunTimeLang() const { return getUnsignedField(11); }
DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
void setContainingType(DICompositeType ContainingType);
@@ -420,6 +441,7 @@ public:
DIArray getImportedEntities() const;
StringRef getSplitDebugFilename() const { return getStringField(12); }
+ unsigned getEmissionKind() const { return getUnsignedField(13); }
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
@@ -470,6 +492,19 @@ public:
return (getUnsignedField(13) & FlagPrototyped) != 0;
}
+ /// Return true if this subprogram is a C++11 reference-qualified
+ /// non-static member function (void foo() &).
+ unsigned isLValueReference() const {
+ return (getUnsignedField(13) & FlagLValueReference) != 0;
+ }
+
+ /// Return true if this subprogram is a C++11
+ /// rvalue-reference-qualified non-static member function
+ /// (void foo() &&).
+ unsigned isRValueReference() const {
+ return (getUnsignedField(13) & FlagRValueReference) != 0;
+ }
+
unsigned isOptimized() const;
/// Verify - Verify that a subprogram descriptor is well formed.
@@ -501,6 +536,7 @@ public:
DIScope getContext() const { return getFieldAs<DIScope>(2); }
unsigned getLineNumber() const { return getUnsignedField(3); }
unsigned getColumnNumber() const { return getUnsignedField(4); }
+ unsigned getDiscriminator() const { return getUnsignedField(5); }
bool Verify() const;
};
@@ -533,6 +569,13 @@ public:
bool Verify() const;
};
+/// DIUnspecifiedParameter - This is a wrapper for unspecified parameters.
+class DIUnspecifiedParameter : public DIDescriptor {
+public:
+ explicit DIUnspecifiedParameter(const MDNode *N = 0) : DIDescriptor(N) {}
+ bool Verify() const;
+};
+
/// DITemplateTypeParameter - This is a wrapper for template type parameter.
class DITemplateTypeParameter : public DIDescriptor {
public:
@@ -586,7 +629,7 @@ public:
}
unsigned getLineNumber() const { return getUnsignedField(7); }
- DIType getType() const { return getFieldAs<DIType>(8); }
+ DITypeRef getType() const { return getFieldAs<DITypeRef>(8); }
unsigned isLocalToUnit() const { return getUnsignedField(9); }
unsigned isDefinition() const { return getUnsignedField(10); }
@@ -617,7 +660,7 @@ public:
unsigned L = getUnsignedField(4);
return L >> 24;
}
- DIType getType() const { return getFieldAs<DIType>(5); }
+ DITypeRef getType() const { return getFieldAs<DITypeRef>(5); }
/// isArtificial - Return true if this variable is marked as "artificial".
bool isArtificial() const {
@@ -650,7 +693,9 @@ public:
/// isBlockByrefVariable - Return true if the variable was declared as
/// a "__block" variable (Apple Blocks).
- bool isBlockByrefVariable() const { return getType().isBlockByrefStruct(); }
+ bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
+ return (getType().resolve(Map)).isBlockByrefStruct();
+ }
/// isInlinedFnArgument - Return true if this variable provides debugging
/// information for an inlined function arguments.
@@ -672,6 +717,27 @@ public:
StringRef getFilename() const { return getScope().getFilename(); }
StringRef getDirectory() const { return getScope().getDirectory(); }
bool Verify() const;
+ bool atSameLineAs(const DILocation &Other) const {
+ return (getLineNumber() == Other.getLineNumber() &&
+ getFilename() == Other.getFilename());
+ }
+ /// getDiscriminator - DWARF discriminators are used to distinguish
+ /// identical file locations for instructions that are on different
+ /// basic blocks. If two instructions are inside the same lexical block
+ /// and are in different basic blocks, we create a new lexical block
+ /// with identical location as the original but with a different
+ /// discriminator value (lib/Transforms/Util/AddDiscriminators.cpp
+ /// for details).
+ unsigned getDiscriminator() const {
+ // Since discriminators are associated with lexical blocks, make
+ // sure this location is a lexical block before retrieving its
+ // value.
+ return getScope().isLexicalBlock()
+ ? getFieldAs<DILexicalBlock>(2).getDiscriminator()
+ : 0;
+ }
+ unsigned computeNewDiscriminator(LLVMContext &Ctx);
+ DILocation copyWithNewScope(LLVMContext &Ctx, DILexicalBlock NewScope);
};
class DIObjCProperty : public DIDescriptor {
@@ -706,6 +772,8 @@ public:
return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
}
+ /// Objective-C doesn't have an ODR, so there is no benefit in storing
+ /// the type as a DITypeRef here.
DIType getType() const { return getFieldAs<DIType>(7); }
/// Verify - Verify that a derived type descriptor is well formed.
@@ -720,7 +788,7 @@ class DIImportedEntity : public DIDescriptor {
public:
explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
DIScope getContext() const { return getFieldAs<DIScope>(1); }
- DIDescriptor getEntity() const { return getFieldAs<DIDescriptor>(2); }
+ DIScopeRef getEntity() const { return getFieldAs<DIScopeRef>(2); }
unsigned getLineNumber() const { return getUnsignedField(3); }
StringRef getName() const { return getStringField(4); }
bool Verify() const;
@@ -793,9 +861,6 @@ private:
/// processType - Process DIType.
void processType(DIType DT);
- /// processLexicalBlock - Process DILexicalBlock.
- void processLexicalBlock(DILexicalBlock LB);
-
/// processSubprogram - Process DISubprogram.
void processSubprogram(DISubprogram SP);
@@ -816,17 +881,31 @@ private:
bool addScope(DIScope Scope);
public:
- typedef SmallVectorImpl<MDNode *>::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(); }
- iterator scope_begin() const { return Scopes.begin(); }
- iterator scope_end() const { return Scopes.end(); }
+ typedef SmallVectorImpl<DICompileUnit>::const_iterator compile_unit_iterator;
+ typedef SmallVectorImpl<DISubprogram>::const_iterator subprogram_iterator;
+ typedef SmallVectorImpl<DIGlobalVariable>::const_iterator global_variable_iterator;
+ typedef SmallVectorImpl<DIType>::const_iterator type_iterator;
+ typedef SmallVectorImpl<DIScope>::const_iterator scope_iterator;
+
+ iterator_range<compile_unit_iterator> compile_units() const {
+ return iterator_range<compile_unit_iterator>(CUs.begin(), CUs.end());
+ }
+
+ iterator_range<subprogram_iterator> subprograms() const {
+ return iterator_range<subprogram_iterator>(SPs.begin(), SPs.end());
+ }
+
+ iterator_range<global_variable_iterator> global_variables() const {
+ return iterator_range<global_variable_iterator>(GVs.begin(), GVs.end());
+ }
+
+ iterator_range<type_iterator> types() const {
+ return iterator_range<type_iterator>(TYs.begin(), TYs.end());
+ }
+
+ iterator_range<scope_iterator> scopes() const {
+ return iterator_range<scope_iterator>(Scopes.begin(), Scopes.end());
+ }
unsigned compile_unit_count() const { return CUs.size(); }
unsigned global_variable_count() const { return GVs.size(); }
@@ -835,11 +914,11 @@ public:
unsigned scope_count() const { return Scopes.size(); }
private:
- SmallVector<MDNode *, 8> CUs; // Compile Units
- SmallVector<MDNode *, 8> SPs; // Subprograms
- SmallVector<MDNode *, 8> GVs; // Global Variables;
- SmallVector<MDNode *, 8> TYs; // Types
- SmallVector<MDNode *, 8> Scopes; // Scopes
+ SmallVector<DICompileUnit, 8> CUs; // Compile Units
+ SmallVector<DISubprogram, 8> SPs; // Subprograms
+ SmallVector<DIGlobalVariable, 8> GVs; // Global Variables;
+ SmallVector<DIType, 8> TYs; // Types
+ SmallVector<DIScope, 8> Scopes; // Scopes
SmallPtrSet<MDNode *, 64> NodesSeen;
DITypeIdentifierMap TypeIdentifierMap;
/// Specify if TypeIdentifierMap is initialized.
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/IR/DebugLoc.h
index 05f31d7..50b5d54 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/IR/DebugLoc.h
@@ -1,4 +1,4 @@
-//===---- llvm/Support/DebugLoc.h - Debug Location Information --*- C++ -*-===//
+//===- DebugLoc.h - Debug Location Information ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,10 +12,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_DEBUGLOC_H
-#define LLVM_SUPPORT_DEBUGLOC_H
+#ifndef LLVM_IR_DEBUGLOC_H
+#define LLVM_IR_DEBUGLOC_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
template <typename T> struct DenseMapInfo;
@@ -89,6 +89,12 @@ namespace llvm {
void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,
const LLVMContext &Ctx) const;
+ /// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.
+ MDNode *getScopeNode(const LLVMContext &Ctx) const;
+
+ // getFnDebugLoc - Walk up the scope chain of given debug loc and find line
+ // number info for the function.
+ DebugLoc getFnDebugLoc(const LLVMContext &Ctx);
/// getAsMDNode - This method converts the compressed DebugLoc node into a
/// DILocation compatible MDNode.
diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
index e279e60..71d9973 100644
--- a/include/llvm/IR/DerivedTypes.h
+++ b/include/llvm/IR/DerivedTypes.h
@@ -249,7 +249,7 @@ public:
bool isOpaque() const { return (getSubclassData() & SCDB_HasBody) == 0; }
/// isSized - Return true if this is a sized type.
- bool isSized() const;
+ bool isSized(SmallPtrSet<const Type*, 4> *Visited = 0) const;
/// hasName - Return true if this is a named struct that has a non-empty name.
bool hasName() const { return SymbolTableEntry != 0; }
@@ -400,6 +400,26 @@ public:
return VectorType::get(EltTy, VTy->getNumElements());
}
+ /// VectorType::getHalfElementsVectorType - This static method returns
+ /// a VectorType with half as many elements as the input type and the
+ /// same element type.
+ ///
+ static VectorType *getHalfElementsVectorType(VectorType *VTy) {
+ unsigned NumElts = VTy->getNumElements();
+ assert ((NumElts & 1) == 0 &&
+ "Cannot halve vector with odd number of elements.");
+ return VectorType::get(VTy->getElementType(), NumElts/2);
+ }
+
+ /// VectorType::getDoubleElementsVectorType - This static method returns
+ /// a VectorType with twice as many elements as the input type and the
+ /// same element type.
+ ///
+ static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
+ unsigned NumElts = VTy->getNumElements();
+ return VectorType::get(VTy->getElementType(), NumElts*2);
+ }
+
/// isValidElementType - Return true if the specified type is valid as a
/// element type.
static bool isValidElementType(Type *ElemTy);
diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h
new file mode 100644
index 0000000..49eb1b0
--- /dev/null
+++ b/include/llvm/IR/DiagnosticInfo.h
@@ -0,0 +1,240 @@
+//===- llvm/Support/DiagnosticInfo.h - Diagnostic 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 declares the different classes involved in low level diagnostics.
+//
+// Diagnostics reporting is still done as part of the LLVMContext.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DIAGNOSTICINFO_H
+#define LLVM_SUPPORT_DIAGNOSTICINFO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+
+// Forward declarations.
+class DiagnosticPrinter;
+class Function;
+class Instruction;
+class Twine;
+class Value;
+
+/// \brief Defines the different supported severity of a diagnostic.
+enum DiagnosticSeverity {
+ DS_Error,
+ DS_Warning,
+ DS_Remark,
+ // A note attaches additional information to one of the previous diagnostic
+ // types.
+ DS_Note
+};
+
+/// \brief Defines the different supported kind of a diagnostic.
+/// This enum should be extended with a new ID for each added concrete subclass.
+enum DiagnosticKind {
+ DK_InlineAsm,
+ DK_StackSize,
+ DK_DebugMetadataVersion,
+ DK_SampleProfile,
+ DK_FirstPluginKind
+};
+
+/// \brief Get the next available kind ID for a plugin diagnostic.
+/// Each time this function is called, it returns a different number.
+/// Therefore, a plugin that wants to "identify" its own classes
+/// with a dynamic identifier, just have to use this method to get a new ID
+/// and assign it to each of its classes.
+/// The returned ID will be greater than or equal to DK_FirstPluginKind.
+/// Thus, the plugin identifiers will not conflict with the
+/// DiagnosticKind values.
+int getNextAvailablePluginDiagnosticKind();
+
+/// \brief This is the base abstract class for diagnostic reporting in
+/// the backend.
+/// The print method must be overloaded by the subclasses to print a
+/// user-friendly message in the client of the backend (let us call it a
+/// frontend).
+class DiagnosticInfo {
+private:
+ /// Kind defines the kind of report this is about.
+ const /* DiagnosticKind */ int Kind;
+ /// Severity gives the severity of the diagnostic.
+ const DiagnosticSeverity Severity;
+
+public:
+ DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
+ : Kind(Kind), Severity(Severity) {}
+
+ virtual ~DiagnosticInfo() {}
+
+ /* DiagnosticKind */ int getKind() const { return Kind; }
+ DiagnosticSeverity getSeverity() const { return Severity; }
+
+ /// Print using the given \p DP a user-friendly message.
+ /// This is the default message that will be printed to the user.
+ /// It is used when the frontend does not directly take advantage
+ /// of the information contained in fields of the subclasses.
+ /// The printed message must not end with '.' nor start with a severity
+ /// keyword.
+ virtual void print(DiagnosticPrinter &DP) const = 0;
+};
+
+/// Diagnostic information for inline asm reporting.
+/// This is basically a message and an optional location.
+class DiagnosticInfoInlineAsm : public DiagnosticInfo {
+private:
+ /// Optional line information. 0 if not set.
+ unsigned LocCookie;
+ /// Message to be reported.
+ const Twine &MsgStr;
+ /// Optional origin of the problem.
+ const Instruction *Instr;
+
+public:
+ /// \p MsgStr is the message to be reported to the frontend.
+ /// This class does not copy \p MsgStr, therefore the reference must be valid
+ /// for the whole life time of the Diagnostic.
+ DiagnosticInfoInlineAsm(const Twine &MsgStr,
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
+ Instr(NULL) {}
+
+ /// \p LocCookie if non-zero gives the line number for this report.
+ /// \p MsgStr gives the message.
+ /// This class does not copy \p MsgStr, therefore the reference must be valid
+ /// for the whole life time of the Diagnostic.
+ DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
+ MsgStr(MsgStr), Instr(NULL) {}
+
+ /// \p Instr gives the original instruction that triggered the diagnostic.
+ /// \p MsgStr gives the message.
+ /// This class does not copy \p MsgStr, therefore the reference must be valid
+ /// for the whole life time of the Diagnostic.
+ /// Same for \p I.
+ DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
+ DiagnosticSeverity Severity = DS_Error);
+
+ unsigned getLocCookie() const { return LocCookie; }
+ const Twine &getMsgStr() const { return MsgStr; }
+ const Instruction *getInstruction() const { return Instr; }
+
+ /// \see DiagnosticInfo::print.
+ void print(DiagnosticPrinter &DP) const override;
+
+ /// Hand rolled RTTI.
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_InlineAsm;
+ }
+};
+
+/// Diagnostic information for stack size reporting.
+/// This is basically a function and a size.
+class DiagnosticInfoStackSize : public DiagnosticInfo {
+private:
+ /// The function that is concerned by this stack size diagnostic.
+ const Function &Fn;
+ /// The computed stack size.
+ unsigned StackSize;
+
+public:
+ /// \p The function that is concerned by this stack size diagnostic.
+ /// \p The computed stack size.
+ DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize,
+ DiagnosticSeverity Severity = DS_Warning)
+ : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {}
+
+ const Function &getFunction() const { return Fn; }
+ unsigned getStackSize() const { return StackSize; }
+
+ /// \see DiagnosticInfo::print.
+ void print(DiagnosticPrinter &DP) const override;
+
+ /// Hand rolled RTTI.
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_StackSize;
+ }
+};
+
+/// Diagnostic information for debug metadata version reporting.
+/// This is basically a module and a version.
+class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
+private:
+ /// The module that is concerned by this debug metadata version diagnostic.
+ const Module &M;
+ /// The actual metadata version.
+ unsigned MetadataVersion;
+
+public:
+ /// \p The module that is concerned by this debug metadata version diagnostic.
+ /// \p The actual metadata version.
+ DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
+ DiagnosticSeverity Severity = DS_Warning)
+ : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
+ MetadataVersion(MetadataVersion) {}
+
+ const Module &getModule() const { return M; }
+ unsigned getMetadataVersion() const { return MetadataVersion; }
+
+ /// \see DiagnosticInfo::print.
+ void print(DiagnosticPrinter &DP) const override;
+
+ /// Hand rolled RTTI.
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_DebugMetadataVersion;
+ }
+};
+
+/// Diagnostic information for the sample profiler.
+class DiagnosticInfoSampleProfile : public DiagnosticInfo {
+public:
+ DiagnosticInfoSampleProfile(const char *FileName, unsigned LineNum,
+ const Twine &Msg,
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
+ LineNum(LineNum), Msg(Msg) {}
+ DiagnosticInfoSampleProfile(const char *FileName, const Twine &Msg,
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
+ LineNum(0), Msg(Msg) {}
+ DiagnosticInfoSampleProfile(const Twine &Msg,
+ DiagnosticSeverity Severity = DS_Error)
+ : DiagnosticInfo(DK_SampleProfile, Severity), FileName(NULL),
+ LineNum(0), Msg(Msg) {}
+
+ /// \see DiagnosticInfo::print.
+ void print(DiagnosticPrinter &DP) const override;
+
+ /// Hand rolled RTTI.
+ static bool classof(const DiagnosticInfo *DI) {
+ return DI->getKind() == DK_SampleProfile;
+ }
+
+ const char *getFileName() const { return FileName; }
+ unsigned getLineNum() const { return LineNum; }
+ const Twine &getMsg() const { return Msg; }
+
+private:
+ /// Name of the input file associated with this diagnostic.
+ const char *FileName;
+
+ /// Line number where the diagnostic occured. If 0, no line number will
+ /// be emitted in the message.
+ unsigned LineNum;
+
+ /// Message to report.
+ const Twine &Msg;
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/IR/DiagnosticPrinter.h b/include/llvm/IR/DiagnosticPrinter.h
new file mode 100644
index 0000000..411c781
--- /dev/null
+++ b/include/llvm/IR/DiagnosticPrinter.h
@@ -0,0 +1,87 @@
+//===- llvm/Support/DiagnosticPrinter.h - Diagnostic Printer ----*- 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 main interface for printer backend diagnostic.
+//
+// Clients of the backend diagnostics should overload this interface based
+// on their needs.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DIAGNOSTICPRINTER_H
+#define LLVM_SUPPORT_DIAGNOSTICPRINTER_H
+
+#include <string>
+
+namespace llvm {
+// Forward declarations.
+class Module;
+class raw_ostream;
+class StringRef;
+class Twine;
+class Value;
+
+/// \brief Interface for custom diagnostic printing.
+class DiagnosticPrinter {
+public:
+ virtual ~DiagnosticPrinter() {}
+
+ // Simple types.
+ virtual DiagnosticPrinter &operator<<(char C) = 0;
+ virtual DiagnosticPrinter &operator<<(unsigned char C) = 0;
+ virtual DiagnosticPrinter &operator<<(signed char C) = 0;
+ virtual DiagnosticPrinter &operator<<(StringRef Str) = 0;
+ virtual DiagnosticPrinter &operator<<(const char *Str) = 0;
+ virtual DiagnosticPrinter &operator<<(const std::string &Str) = 0;
+ virtual DiagnosticPrinter &operator<<(unsigned long N) = 0;
+ virtual DiagnosticPrinter &operator<<(long N) = 0;
+ virtual DiagnosticPrinter &operator<<(unsigned long long N) = 0;
+ virtual DiagnosticPrinter &operator<<(long long N) = 0;
+ virtual DiagnosticPrinter &operator<<(const void *P) = 0;
+ virtual DiagnosticPrinter &operator<<(unsigned int N) = 0;
+ virtual DiagnosticPrinter &operator<<(int N) = 0;
+ virtual DiagnosticPrinter &operator<<(double N) = 0;
+ virtual DiagnosticPrinter &operator<<(const Twine &Str) = 0;
+
+ // IR related types.
+ virtual DiagnosticPrinter &operator<<(const Value &V) = 0;
+ virtual DiagnosticPrinter &operator<<(const Module &M) = 0;
+};
+
+/// \brief Basic diagnostic printer that uses an underlying raw_ostream.
+class DiagnosticPrinterRawOStream : public DiagnosticPrinter {
+protected:
+ raw_ostream &Stream;
+
+public:
+ DiagnosticPrinterRawOStream(raw_ostream &Stream) : Stream(Stream) {};
+
+ // Simple types.
+ DiagnosticPrinter &operator<<(char C) override;
+ DiagnosticPrinter &operator<<(unsigned char C) override;
+ DiagnosticPrinter &operator<<(signed char C) override;
+ DiagnosticPrinter &operator<<(StringRef Str) override;
+ DiagnosticPrinter &operator<<(const char *Str) override;
+ DiagnosticPrinter &operator<<(const std::string &Str) override;
+ DiagnosticPrinter &operator<<(unsigned long N) override;
+ DiagnosticPrinter &operator<<(long N) override;
+ DiagnosticPrinter &operator<<(unsigned long long N) override;
+ DiagnosticPrinter &operator<<(long long N) override;
+ DiagnosticPrinter &operator<<(const void *P) override;
+ DiagnosticPrinter &operator<<(unsigned int N) override;
+ DiagnosticPrinter &operator<<(int N) override;
+ DiagnosticPrinter &operator<<(double N) override;
+ DiagnosticPrinter &operator<<(const Twine &Str) override;
+
+ // IR related types.
+ DiagnosticPrinter &operator<<(const Value &V) override;
+ DiagnosticPrinter &operator<<(const Module &M) override;
+};
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h
new file mode 100644
index 0000000..86bbe39
--- /dev/null
+++ b/include/llvm/IR/Dominators.h
@@ -0,0 +1,190 @@
+//===- 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_IR_DOMINATORS_H
+#define LLVM_IR_DOMINATORS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+namespace llvm {
+
+EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
+EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
+
+#define LLVM_COMMA ,
+EXTERN_TEMPLATE_INSTANTIATION(void Calculate<Function LLVM_COMMA BasicBlock *>(
+ DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT LLVM_COMMA
+ Function &F));
+EXTERN_TEMPLATE_INSTANTIATION(
+ void Calculate<Function LLVM_COMMA Inverse<BasicBlock *> >(
+ DominatorTreeBase<GraphTraits<Inverse<BasicBlock *> >::NodeType> &DT
+ LLVM_COMMA Function &F));
+#undef LLVM_COMMA
+
+typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
+
+class BasicBlockEdge {
+ const BasicBlock *Start;
+ const BasicBlock *End;
+public:
+ BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
+ Start(Start_), End(End_) { }
+ const BasicBlock *getStart() const {
+ return Start;
+ }
+ const BasicBlock *getEnd() const {
+ return End;
+ }
+ bool isSingleEdge() const;
+};
+
+/// \brief Concrete subclass of DominatorTreeBase that is used to compute a
+/// normal dominator tree.
+class DominatorTree : public DominatorTreeBase<BasicBlock> {
+public:
+ typedef DominatorTreeBase<BasicBlock> Base;
+
+ DominatorTree() : DominatorTreeBase<BasicBlock>(false) {}
+
+ /// \brief Returns *false* if the other dominator tree matches this dominator
+ /// tree.
+ inline bool compare(const DominatorTree &Other) const {
+ const DomTreeNode *R = getRootNode();
+ const DomTreeNode *OtherR = Other.getRootNode();
+
+ if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
+ return true;
+
+ if (Base::compare(Other))
+ return true;
+
+ return false;
+ }
+
+ // Ensure base-class overloads are visible.
+ using Base::dominates;
+
+ /// \brief 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 dominates(const BasicBlockEdge &BBE, const Use &U) const;
+ bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
+
+ inline DomTreeNode *operator[](BasicBlock *BB) const {
+ return getNode(BB);
+ }
+
+ // Ensure base class overloads are visible.
+ using Base::isReachableFromEntry;
+
+ /// \brief Provide an overload for a Use.
+ bool isReachableFromEntry(const Use &U) const;
+
+ /// \brief Verify the correctness of the domtree by re-computing it.
+ ///
+ /// This should only be used for debugging as it aborts the program if the
+ /// verification fails.
+ void verifyDomTree() const;
+};
+
+//===-------------------------------------
+// DominatorTree GraphTraits specializations 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));
+ }
+};
+
+/// \brief Analysis pass which computes a \c DominatorTree.
+class DominatorTreeWrapperPass : public FunctionPass {
+ DominatorTree DT;
+
+public:
+ static char ID;
+
+ DominatorTreeWrapperPass() : FunctionPass(ID) {
+ initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ DominatorTree &getDomTree() { return DT; }
+ const DominatorTree &getDomTree() const { return DT; }
+
+ bool runOnFunction(Function &F) override;
+
+ void verifyAnalysis() const override;
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+
+ void releaseMemory() override { DT.releaseMemory(); }
+
+ void print(raw_ostream &OS, const Module *M = 0) const override;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index bba7ecd..cb43bba 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -18,6 +18,7 @@
#ifndef LLVM_IR_FUNCTION_H
#define LLVM_IR_FUNCTION_H
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -335,7 +336,7 @@ public:
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a Function) from the Function Src to this one.
- void copyAttributesFrom(const GlobalValue *Src);
+ void copyAttributesFrom(const GlobalValue *Src) override;
/// deleteBody - This method deletes the body of the function, and converts
/// the linkage to external.
@@ -348,12 +349,12 @@ public:
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- virtual void removeFromParent();
+ void removeFromParent() override;
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- virtual void eraseFromParent();
+ void eraseFromParent() override;
/// Get the underlying elements of the Function... the basic block list is
@@ -404,9 +405,9 @@ public:
const BasicBlock &back() const { return BasicBlocks.back(); }
BasicBlock &back() { return BasicBlocks.back(); }
- //===--------------------------------------------------------------------===//
- // Argument iterator forwarding functions
- //
+/// @name Function Argument Iteration
+/// @{
+
arg_iterator arg_begin() {
CheckLazyArguments();
return ArgumentList.begin();
@@ -424,6 +425,16 @@ public:
return ArgumentList.end();
}
+ iterator_range<arg_iterator> args() {
+ return iterator_range<arg_iterator>(arg_begin(), arg_end());
+ }
+
+ iterator_range<const_arg_iterator> args() const {
+ return iterator_range<const_arg_iterator>(arg_begin(), arg_end());
+ }
+
+/// @}
+
size_t arg_size() const;
bool arg_empty() const;
diff --git a/include/llvm/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
index 8efe50a..6717bc8 100644
--- a/include/llvm/GVMaterializer.h
+++ b/include/llvm/IR/GVMaterializer.h
@@ -1,4 +1,4 @@
-//===-- llvm/GVMaterializer.h - Interface for GV materializers --*- C++ -*-===//
+//===- GVMaterializer.h - Interface for GV materializers --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_GVMATERIALIZER_H
-#define LLVM_GVMATERIALIZER_H
+#ifndef LLVM_IR_GVMATERIALIZER_H
+#define LLVM_IR_GVMATERIALIZER_H
#include "llvm/Support/system_error.h"
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h
index aacb531..f2722d6 100644
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ b/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
+//===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
-#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
+#ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
+#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/User.h"
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index fec61a7..2ca481a 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -49,12 +49,12 @@ public:
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- virtual void removeFromParent();
+ void removeFromParent() override;
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- virtual void eraseFromParent();
+ void eraseFromParent() override;
/// set/getAliasee - These methods retrive and set alias target.
void setAliasee(Constant *GV);
@@ -64,23 +64,15 @@ public:
Constant *getAliasee() {
return getOperand(0);
}
- /// getAliasedGlobal() - Aliasee can be either global or bitcast of
- /// global. This method retrives the global for both aliasee flavours.
+
+ /// 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.
GlobalValue *getAliasedGlobal();
const GlobalValue *getAliasedGlobal() const {
return const_cast<GlobalAlias *>(this)->getAliasedGlobal();
}
- /// 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.
- GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true);
- const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const {
- return const_cast<GlobalAlias *>(this)->resolveAliasedGlobal(stopOnWeak);
- }
-
static bool isValidLinkage(LinkageTypes L) {
return isExternalLinkage(L) || isLocalLinkage(L) ||
isWeakLinkage(L) || isLinkOnceLinkage(L);
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 4f20a31..59c320d 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -40,10 +40,6 @@ public:
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.
- DLLImportLinkage, ///< Function to be imported from DLL
- DLLExportLinkage, ///< Function to be accessible from DLL.
ExternalWeakLinkage,///< ExternalWeak linkage description.
CommonLinkage ///< Tentative definitions.
};
@@ -55,11 +51,19 @@ public:
ProtectedVisibility ///< The GV is protected
};
+ /// @brief Storage classes of global values for PE targets.
+ enum DLLStorageClassTypes {
+ DefaultStorageClass = 0,
+ DLLImportStorageClass = 1, ///< Function to be imported from DLL
+ DLLExportStorageClass = 2 ///< Function to be accessible from DLL.
+ };
+
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) {
+ Visibility(DefaultVisibility), Alignment(0), UnnamedAddr(0),
+ DllStorageClass(DefaultStorageClass), Parent(0) {
setName(Name);
}
@@ -69,6 +73,7 @@ protected:
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
+ unsigned DllStorageClass : 2; // DLL storage class
Module *Parent; // The containing module.
std::string Section; // Section to emit this into, empty mean default
public:
@@ -91,11 +96,26 @@ public:
return Visibility == ProtectedVisibility;
}
void setVisibility(VisibilityTypes V) { Visibility = V; }
-
+
+ DLLStorageClassTypes getDLLStorageClass() const {
+ return DLLStorageClassTypes(DllStorageClass);
+ }
+ bool hasDLLImportStorageClass() const {
+ return DllStorageClass == DLLImportStorageClass;
+ }
+ bool hasDLLExportStorageClass() const {
+ return DllStorageClass == DLLExportStorageClass;
+ }
+ void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
+
bool hasSection() const { return !Section.empty(); }
const std::string &getSection() const { return Section; }
- void setSection(StringRef S) { Section = S; }
-
+ void setSection(StringRef S) {
+ assert((getValueID() != Value::GlobalAliasVal || S.empty()) &&
+ "GlobalAlias should not have a section!");
+ 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.
@@ -136,21 +156,8 @@ public:
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 isLocalLinkage(LinkageTypes Linkage) {
- return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) ||
- isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage);
- }
- static bool isDLLImportLinkage(LinkageTypes Linkage) {
- return Linkage == DLLImportLinkage;
- }
- static bool isDLLExportLinkage(LinkageTypes Linkage) {
- return Linkage == DLLExportLinkage;
+ return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage);
}
static bool isExternalWeakLinkage(LinkageTypes Linkage) {
return Linkage == ExternalWeakLinkage;
@@ -169,11 +176,8 @@ public:
/// 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;
+ return Linkage == WeakAnyLinkage || Linkage == LinkOnceAnyLinkage ||
+ Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
}
/// isWeakForLinker - Whether the definition of this global may be replaced at
@@ -181,14 +185,10 @@ public:
/// 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;
+ return Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage ||
+ Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage ||
+ Linkage == LinkOnceODRLinkage || Linkage == CommonLinkage ||
+ Linkage == ExternalWeakLinkage;
}
bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
@@ -204,13 +204,7 @@ public:
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 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); }
@@ -267,7 +261,7 @@ public:
/// @}
/// Override from Constant class.
- virtual void destroyConstant();
+ void destroyConstant() override;
/// isDeclaration - Return true if the primary definition of this global
/// value is outside of the current translation unit.
@@ -286,6 +280,8 @@ public:
inline Module *getParent() { return Parent; }
inline const Module *getParent() const { return Parent; }
+ const DataLayout *getDataLayout() const;
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index 660092d..a82740f 100644
--- a/include/llvm/IR/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -174,21 +174,21 @@ public:
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
- void copyAttributesFrom(const GlobalValue *Src);
+ void copyAttributesFrom(const GlobalValue *Src) override;
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- virtual void removeFromParent();
+ void removeFromParent() override;
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- virtual void eraseFromParent();
+ void eraseFromParent() override;
/// Override Constant's implementation of this method so we can
/// replace constant initializers.
- virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+ void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) override;
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 8d1432d..79ee7b7 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -19,13 +19,13 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ConstantFolder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm/Support/ConstantFolder.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
class MDNode;
@@ -282,6 +282,12 @@ public:
return ConstantInt::get(getInt64Ty(), C);
}
+ /// \brief Get a constant N-bit value, zero extended or truncated from
+ /// a 64-bit value.
+ ConstantInt *getIntN(unsigned N, uint64_t C) {
+ return ConstantInt::get(getIntNTy(N), C);
+ }
+
/// \brief Get a constant integer value.
ConstantInt *getInt(const APInt &AI) {
return ConstantInt::get(Context, AI);
@@ -316,6 +322,11 @@ public:
return Type::getInt64Ty(Context);
}
+ /// \brief Fetch the type representing an N-bit integer.
+ IntegerType *getIntNTy(unsigned N) {
+ return Type::getIntNTy(Context, N);
+ }
+
/// \brief Fetch the type representing a 32-bit floating point value.
Type *getFloatTy() {
return Type::getFloatTy(Context);
@@ -638,7 +649,7 @@ public:
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 Insert(Folder.CreateSub(LC, RC, HasNUW, HasNSW), Name);
return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name,
HasNUW, HasNSW);
}
@@ -660,7 +671,7 @@ public:
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 Insert(Folder.CreateMul(LC, RC, HasNUW, HasNSW), Name);
return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name,
HasNUW, HasNSW);
}
@@ -832,11 +843,15 @@ public:
}
Value *CreateBinOp(Instruction::BinaryOps Opc,
- Value *LHS, Value *RHS, const Twine &Name = "") {
+ 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.CreateBinOp(Opc, LC, RC), Name);
- return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
+ llvm::Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS);
+ if (isa<FPMathOperator>(BinOp))
+ BinOp = AddFPMathAttributes(BinOp, FPMathTag, FMF);
+ return Insert(BinOp, Name);
}
Value *CreateNeg(Value *V, const Twine &Name = "",
@@ -915,13 +930,17 @@ public:
return SI;
}
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));
+ SynchronizationScope SynchScope = CrossThread,
+ const Twine &Name = "") {
+ return Insert(new FenceInst(Context, Ordering, SynchScope), Name);
+ }
+ AtomicCmpXchgInst *
+ CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope = CrossThread) {
+ return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering,
+ FailureOrdering, SynchScope));
}
AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
AtomicOrdering Ordering,
diff --git a/include/llvm/IR/IRPrintingPasses.h b/include/llvm/IR/IRPrintingPasses.h
new file mode 100644
index 0000000..2f78c83
--- /dev/null
+++ b/include/llvm/IR/IRPrintingPasses.h
@@ -0,0 +1,85 @@
+//===- IRPrintingPasses.h - Passes to print out IR constructs ---*- 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 defines passes to print out IR in various granularities. 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_IR_IR_PRINTING_PASSES_H
+#define LLVM_IR_IR_PRINTING_PASSES_H
+
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+class BasicBlockPass;
+class Function;
+class FunctionPass;
+class Module;
+class ModulePass;
+class PreservedAnalyses;
+class raw_ostream;
+
+/// \brief Create and return a pass that writes the module to the specified
+/// \c raw_ostream.
+ModulePass *createPrintModulePass(raw_ostream &OS,
+ const std::string &Banner = "");
+
+/// \brief Create and return a pass that prints functions to the specified
+/// \c raw_ostream as they are processed.
+FunctionPass *createPrintFunctionPass(raw_ostream &OS,
+ const std::string &Banner = "");
+
+/// \brief Create and return a pass that writes the BB to the specified
+/// \c raw_ostream.
+BasicBlockPass *createPrintBasicBlockPass(raw_ostream &OS,
+ const std::string &Banner = "");
+
+/// \brief Pass for printing a Module as LLVM's text IR assembly.
+///
+/// Note: This pass is for use with the new pass manager. Use the create...Pass
+/// functions above to create passes for use with the legacy pass manager.
+class PrintModulePass {
+ raw_ostream &OS;
+ std::string Banner;
+
+public:
+ PrintModulePass();
+ PrintModulePass(raw_ostream &OS, const std::string &Banner = "");
+
+ PreservedAnalyses run(Module *M);
+
+ static StringRef name() { return "PrintModulePass"; }
+};
+
+/// \brief Pass for printing a Function as LLVM's text IR assembly.
+///
+/// Note: This pass is for use with the new pass manager. Use the create...Pass
+/// functions above to create passes for use with the legacy pass manager.
+class PrintFunctionPass {
+ raw_ostream &OS;
+ std::string Banner;
+
+public:
+ PrintFunctionPass();
+ PrintFunctionPass(raw_ostream &OS, const std::string &Banner = "");
+
+ PreservedAnalyses run(Function *F);
+
+ static StringRef name() { return "PrintFunctionPass"; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index 3398a83..ac19089 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -164,9 +164,6 @@ public:
///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.
@@ -197,7 +194,7 @@ public:
// These are helper methods for dealing with flags in the INLINEASM SDNode
// in the backend.
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Fixed operands on an INLINEASM SDNode.
Op_InputChain = 0,
Op_AsmString = 1,
diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/IR/InstIterator.h
index ac936a1..75e93bd 100644
--- a/include/llvm/Support/InstIterator.h
+++ b/include/llvm/IR/InstIterator.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
+//===- InstIterator.h - Classes for inst iteration --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_INSTITERATOR_H
-#define LLVM_SUPPORT_INSTITERATOR_H
+#ifndef LLVM_IR_INSTITERATOR_H
+#define LLVM_IR_INSTITERATOR_H
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
diff --git a/include/llvm/InstVisitor.h b/include/llvm/IR/InstVisitor.h
index de7206d..1cdcd55 100644
--- a/include/llvm/InstVisitor.h
+++ b/include/llvm/IR/InstVisitor.h
@@ -1,4 +1,4 @@
-//===- llvm/InstVisitor.h - Instruction visitor templates -------*- C++ -*-===//
+//===- InstVisitor.h - Instruction visitor templates ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,15 +8,15 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INSTVISITOR_H
-#define LLVM_INSTVISITOR_H
+#ifndef LLVM_IR_INSTVISITOR_H
+#define LLVM_IR_INSTVISITOR_H
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index e12bb03..e1a5130 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -51,7 +51,7 @@ protected:
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;
+ TerminatorInst *clone_impl() const override = 0;
public:
/// getNumSuccessors - Return the number of successors that this terminator
@@ -143,7 +143,7 @@ protected:
const Twine &Name, Instruction *InsertBefore);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, BasicBlock *InsertAtEnd);
- virtual BinaryOperator *clone_impl() const LLVM_OVERRIDE;
+ BinaryOperator *clone_impl() const override;
public:
// allocate space for exactly two operands
void *operator new(size_t s) {
@@ -385,7 +385,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
/// if (isa<CastInst>(Instr)) { ... }
/// @brief Base class of casting instructions.
class CastInst : public UnaryInstruction {
- virtual void anchor() LLVM_OVERRIDE;
+ void anchor() override;
protected:
/// @brief Constructor with insert-before-instruction semantics for subclasses
CastInst(Type *Ty, unsigned iType, Value *S,
@@ -582,6 +582,11 @@ public:
Type *IntPtrTy ///< Integer type corresponding to pointer
) const;
+ /// @brief Determine if this cast is a no-op cast.
+ bool isNoopCast(
+ const DataLayout *DL ///< DataLayout to get the Int Ptr type from.
+ ) 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, otherwise
@@ -642,7 +647,7 @@ protected:
Value *LHS, Value *RHS, const Twine &Name,
BasicBlock *InsertAtEnd);
- virtual void anchor() LLVM_OVERRIDE; // Out of line virtual method.
+ void anchor() override; // Out of line virtual method.
public:
/// This enumeration lists the possible predicates for CmpInst subclasses.
/// Values in the range 0-31 are reserved for FCmpInst, while values in the
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index 5721d8f..928dc07 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -15,9 +15,10 @@
#ifndef LLVM_IR_INSTRUCTION_H
#define LLVM_IR_INSTRUCTION_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/User.h"
-#include "llvm/Support/DebugLoc.h"
namespace llvm {
@@ -44,14 +45,16 @@ 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
+ /// user_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());}
+ Instruction *user_back() { return cast<Instruction>(*user_begin());}
+ const Instruction *user_back() const { return cast<Instruction>(*user_begin());}
inline const BasicBlock *getParent() const { return Parent; }
inline BasicBlock *getParent() { return Parent; }
+ const DataLayout *getDataLayout() const;
+
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, but does not delete it.
///
@@ -171,6 +174,21 @@ public:
void setMetadata(unsigned KindID, MDNode *Node);
void setMetadata(StringRef Kind, MDNode *Node);
+ /// \brief Drop unknown metadata.
+ /// Passes are required to drop metadata they don't understand. This is a
+ /// convenience method for passes to do so.
+ void dropUnknownMetadata(ArrayRef<unsigned> KnownIDs);
+ void dropUnknownMetadata() {
+ return dropUnknownMetadata(ArrayRef<unsigned>());
+ }
+ void dropUnknownMetadata(unsigned ID1) {
+ return dropUnknownMetadata(makeArrayRef(ID1));
+ }
+ void dropUnknownMetadata(unsigned ID1, unsigned ID2) {
+ unsigned IDs[] = {ID1, ID2};
+ return dropUnknownMetadata(IDs);
+ }
+
/// setDebugLoc - Set the debug location information for this instruction.
void setDebugLoc(const DebugLoc &Loc) { DbgLoc = Loc; }
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 0843d8f..06d7287 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -17,6 +17,7 @@
#define LLVM_IR_INSTRUCTIONS_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CallingConv.h"
@@ -57,7 +58,7 @@ enum SynchronizationScope {
///
class AllocaInst : public UnaryInstruction {
protected:
- virtual AllocaInst *clone_impl() const;
+ AllocaInst *clone_impl() const override;
public:
explicit AllocaInst(Type *Ty, Value *ArraySize = 0,
const Twine &Name = "", Instruction *InsertBefore = 0);
@@ -101,7 +102,7 @@ public:
/// by the instruction.
///
unsigned getAlignment() const {
- return (1u << getSubclassDataFromInstruction()) >> 1;
+ return (1u << (getSubclassDataFromInstruction() & 31)) >> 1;
}
void setAlignment(unsigned Align);
@@ -110,6 +111,20 @@ public:
/// into the prolog/epilog code, so it is basically free.
bool isStaticAlloca() const;
+ /// \brief Return true if this alloca is used as an inalloca argument to a
+ /// call. Such allocas are never considered static even if they are in the
+ /// entry block.
+ bool isUsedWithInAlloca() const {
+ return getSubclassDataFromInstruction() & 32;
+ }
+
+ /// \brief Specify whether this alloca is used to represent a the arguments to
+ /// a call.
+ void setUsedWithInAlloca(bool V) {
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~32) |
+ (V ? 32 : 0));
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::Alloca);
@@ -136,7 +151,7 @@ private:
class LoadInst : public UnaryInstruction {
void AssertOK();
protected:
- virtual LoadInst *clone_impl() const;
+ LoadInst *clone_impl() const override;
public:
LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore);
LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
@@ -256,7 +271,7 @@ class StoreInst : public Instruction {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void AssertOK();
protected:
- virtual StoreInst *clone_impl() const;
+ StoreInst *clone_impl() const override;
public:
// allocate space for exactly two operands
void *operator new(size_t s) {
@@ -383,7 +398,7 @@ class FenceInst : public Instruction {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope);
protected:
- virtual FenceInst *clone_impl() const;
+ FenceInst *clone_impl() const override;
public:
// allocate space for exactly zero operands
void *operator new(size_t s) {
@@ -449,19 +464,24 @@ private:
class AtomicCmpXchgInst : public Instruction {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void Init(Value *Ptr, Value *Cmp, Value *NewVal,
- AtomicOrdering Ordering, SynchronizationScope SynchScope);
+ AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope);
protected:
- virtual AtomicCmpXchgInst *clone_impl() const;
+ AtomicCmpXchgInst *clone_impl() const override;
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,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope,
Instruction *InsertBefore = 0);
AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
- AtomicOrdering Ordering, SynchronizationScope SynchScope,
+ AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope,
BasicBlock *InsertAtEnd);
/// isVolatile - Return true if this is a cmpxchg from a volatile memory
@@ -482,13 +502,20 @@ public:
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Set the ordering constraint on this cmpxchg.
- void setOrdering(AtomicOrdering Ordering) {
+ void setSuccessOrdering(AtomicOrdering Ordering) {
assert(Ordering != NotAtomic &&
"CmpXchg instructions can only be atomic.");
- setInstructionSubclassData((getSubclassDataFromInstruction() & 3) |
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x1c) |
(Ordering << 2));
}
+ void setFailureOrdering(AtomicOrdering Ordering) {
+ assert(Ordering != NotAtomic &&
+ "CmpXchg instructions can only be atomic.");
+ setInstructionSubclassData((getSubclassDataFromInstruction() & ~0xe0) |
+ (Ordering << 5));
+ }
+
/// 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.
@@ -498,8 +525,13 @@ public:
}
/// Returns the ordering constraint on this cmpxchg.
- AtomicOrdering getOrdering() const {
- return AtomicOrdering(getSubclassDataFromInstruction() >> 2);
+ AtomicOrdering getSuccessOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+ }
+
+ /// Returns the ordering constraint on this cmpxchg.
+ AtomicOrdering getFailureOrdering() const {
+ return AtomicOrdering((getSubclassDataFromInstruction() >> 5) & 7);
}
/// Returns whether this cmpxchg is atomic between threads or only within a
@@ -523,6 +555,28 @@ public:
return getPointerOperand()->getType()->getPointerAddressSpace();
}
+ /// \brief Returns the strongest permitted ordering on failure, given the
+ /// desired ordering on success.
+ ///
+ /// If the comparison in a cmpxchg operation fails, there is no atomic store
+ /// so release semantics cannot be provided. So this function drops explicit
+ /// Release requests from the AtomicOrdering. A SequentiallyConsistent
+ /// operation would remain SequentiallyConsistent.
+ static AtomicOrdering
+ getStrongestFailureOrdering(AtomicOrdering SuccessOrdering) {
+ switch (SuccessOrdering) {
+ default: llvm_unreachable("invalid cmpxchg success ordering");
+ case Release:
+ case Monotonic:
+ return Monotonic;
+ case AcquireRelease:
+ case Acquire:
+ return Acquire;
+ case SequentiallyConsistent:
+ return SequentiallyConsistent;
+ }
+ }
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::AtomicCmpXchg;
@@ -556,7 +610,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value)
class AtomicRMWInst : public Instruction {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
protected:
- virtual AtomicRMWInst *clone_impl() const;
+ AtomicRMWInst *clone_impl() const override;
public:
/// This enumeration lists the possible modifications atomicrmw can make. In
/// the descriptions, 'p' is the pointer to the instruction's memory location,
@@ -721,7 +775,7 @@ class GetElementPtrInst : public Instruction {
unsigned Values, const Twine &NameStr,
BasicBlock *InsertAtEnd);
protected:
- virtual GetElementPtrInst *clone_impl() const;
+ GetElementPtrInst *clone_impl() const override;
public:
static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
@@ -923,7 +977,7 @@ class ICmpInst: public CmpInst {
protected:
/// \brief Clone an identical ICmpInst
- virtual ICmpInst *clone_impl() const;
+ ICmpInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics.
ICmpInst(
@@ -1055,7 +1109,7 @@ public:
class FCmpInst: public CmpInst {
protected:
/// \brief Clone an identical FCmpInst
- virtual FCmpInst *clone_impl() const;
+ FCmpInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics.
FCmpInst(
@@ -1174,15 +1228,11 @@ class CallInst : public Instruction {
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;
+ CallInst *clone_impl() const override;
public:
static CallInst *Create(Value *Func,
ArrayRef<Value *> Args,
@@ -1245,6 +1295,22 @@ public:
Value *getArgOperand(unsigned i) const { return getOperand(i); }
void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<op_iterator> arg_operands() {
+ // The last operand in the op list is the callee - it's not one of the args
+ // so we don't want to iterate over it.
+ return iterator_range<op_iterator>(op_begin(), op_end() - 1);
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<const_op_iterator> arg_operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), op_end() - 1);
+ }
+
+ /// \brief Wrappers for getting the \c Use of a call argument.
+ const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+ Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
/// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call.
CallingConv::ID getCallingConv() const {
@@ -1450,7 +1516,7 @@ class SelectInst : public Instruction {
setName(NameStr);
}
protected:
- virtual SelectInst *clone_impl() const;
+ SelectInst *clone_impl() const override;
public:
static SelectInst *Create(Value *C, Value *S1, Value *S2,
const Twine &NameStr = "",
@@ -1505,7 +1571,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value)
///
class VAArgInst : public UnaryInstruction {
protected:
- virtual VAArgInst *clone_impl() const;
+ VAArgInst *clone_impl() const override;
public:
VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "",
@@ -1545,7 +1611,7 @@ class ExtractElementInst : public Instruction {
ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr,
BasicBlock *InsertAtEnd);
protected:
- virtual ExtractElementInst *clone_impl() const;
+ ExtractElementInst *clone_impl() const override;
public:
static ExtractElementInst *Create(Value *Vec, Value *Idx,
@@ -1606,7 +1672,7 @@ class InsertElementInst : public Instruction {
InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
- virtual InsertElementInst *clone_impl() const;
+ InsertElementInst *clone_impl() const override;
public:
static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
@@ -1659,7 +1725,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
///
class ShuffleVectorInst : public Instruction {
protected:
- virtual ShuffleVectorInst *clone_impl() const;
+ ShuffleVectorInst *clone_impl() const override;
public:
// allocate space for exactly three operands
@@ -1760,7 +1826,7 @@ class ExtractValueInst : public UnaryInstruction {
return User::operator new(s, 1);
}
protected:
- virtual ExtractValueInst *clone_impl() const;
+ ExtractValueInst *clone_impl() const override;
public:
static ExtractValueInst *Create(Value *Agg,
@@ -1871,7 +1937,7 @@ class InsertValueInst : public Instruction {
InsertValueInst(Value *Agg, Value *Val, unsigned Idx,
const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
- virtual InsertValueInst *clone_impl() const;
+ InsertValueInst *clone_impl() const override;
public:
// allocate space for exactly two operands
void *operator new(size_t s) {
@@ -2006,7 +2072,7 @@ protected:
// values and pointers to the incoming blocks, all in one allocation.
Use *allocHungoffUses(unsigned) const;
- virtual PHINode *clone_impl() const;
+ PHINode *clone_impl() const override;
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).
@@ -2086,8 +2152,7 @@ public:
/// getIncomingBlock - Return incoming basic block corresponding
/// to value use iterator.
///
- template <typename U>
- BasicBlock *getIncomingBlock(value_use_iterator<U> I) const {
+ BasicBlock *getIncomingBlock(Value::const_user_iterator I) const {
return getIncomingBlock(I.getUse());
}
@@ -2198,7 +2263,7 @@ private:
unsigned NumReservedValues, const Twine &NameStr,
BasicBlock *InsertAtEnd);
protected:
- virtual LandingPadInst *clone_impl() const;
+ LandingPadInst *clone_impl() const override;
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).
@@ -2296,7 +2361,7 @@ private:
ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd);
explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd);
protected:
- virtual ReturnInst *clone_impl() const;
+ ReturnInst *clone_impl() const override;
public:
static ReturnInst* Create(LLVMContext &C, Value *retVal = 0,
Instruction *InsertBefore = 0) {
@@ -2329,9 +2394,9 @@ public:
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);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -2368,7 +2433,7 @@ class BranchInst : public TerminatorInst {
BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
BasicBlock *InsertAtEnd);
protected:
- virtual BranchInst *clone_impl() const;
+ BranchInst *clone_impl() const override;
public:
static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) {
return new(1) BranchInst(IfTrue, InsertBefore);
@@ -2428,9 +2493,9 @@ public:
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);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -2474,7 +2539,7 @@ class SwitchInst : public TerminatorInst {
SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
BasicBlock *InsertAtEnd);
protected:
- virtual SwitchInst *clone_impl() const;
+ SwitchInst *clone_impl() const override;
public:
// -2
@@ -2721,9 +2786,9 @@ public:
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);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -2766,7 +2831,7 @@ class IndirectBrInst : public TerminatorInst {
/// autoinserts at the end of the specified BasicBlock.
IndirectBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd);
protected:
- virtual IndirectBrInst *clone_impl() const;
+ IndirectBrInst *clone_impl() const override;
public:
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
Instruction *InsertBefore = 0) {
@@ -2819,9 +2884,9 @@ public:
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);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -2858,7 +2923,7 @@ class InvokeInst : public TerminatorInst {
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
- virtual InvokeInst *clone_impl() const;
+ InvokeInst *clone_impl() const override;
public:
static InvokeInst *Create(Value *Func,
BasicBlock *IfNormal, BasicBlock *IfException,
@@ -2889,6 +2954,20 @@ public:
Value *getArgOperand(unsigned i) const { return getOperand(i); }
void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<op_iterator> arg_operands() {
+ return iterator_range<op_iterator>(op_begin(), op_end() - 3);
+ }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ iterator_range<const_op_iterator> arg_operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), op_end() - 3);
+ }
+
+ /// \brief Wrappers for getting the \c Use of a invoke argument.
+ const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
+ Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+
/// getCallingConv/setCallingConv - Get or set the calling convention of this
/// function call.
CallingConv::ID getCallingConv() const {
@@ -2970,6 +3049,12 @@ public:
addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
}
+ /// \brief Determine if the invoke cannot be duplicated.
+ bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); }
+ void setCannotDuplicate() {
+ addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
+ }
+
/// \brief Determine if the call returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
@@ -3038,9 +3123,9 @@ public:
}
private:
- virtual BasicBlock *getSuccessorV(unsigned idx) const;
- virtual unsigned getNumSuccessorsV() const;
- virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
bool hasFnAttrImpl(Attribute::AttrKind A) const;
@@ -3093,7 +3178,7 @@ class ResumeInst : public TerminatorInst {
explicit ResumeInst(Value *Exn, Instruction *InsertBefore=0);
ResumeInst(Value *Exn, BasicBlock *InsertAtEnd);
protected:
- virtual ResumeInst *clone_impl() const;
+ ResumeInst *clone_impl() const override;
public:
static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = 0) {
return new(1) ResumeInst(Exn, InsertBefore);
@@ -3118,9 +3203,9 @@ public:
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);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
@@ -3142,7 +3227,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
class UnreachableInst : public TerminatorInst {
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
protected:
- virtual UnreachableInst *clone_impl() const;
+ UnreachableInst *clone_impl() const override;
public:
// allocate space for exactly zero operands
@@ -3162,9 +3247,9 @@ public:
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);
+ BasicBlock *getSuccessorV(unsigned idx) const override;
+ unsigned getNumSuccessorsV() const override;
+ void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
//===----------------------------------------------------------------------===//
@@ -3175,7 +3260,7 @@ private:
class TruncInst : public CastInst {
protected:
/// \brief Clone an identical TruncInst
- virtual TruncInst *clone_impl() const;
+ TruncInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3211,7 +3296,7 @@ public:
class ZExtInst : public CastInst {
protected:
/// \brief Clone an identical ZExtInst
- virtual ZExtInst *clone_impl() const;
+ ZExtInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3247,7 +3332,7 @@ public:
class SExtInst : public CastInst {
protected:
/// \brief Clone an identical SExtInst
- virtual SExtInst *clone_impl() const;
+ SExtInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3283,7 +3368,7 @@ public:
class FPTruncInst : public CastInst {
protected:
/// \brief Clone an identical FPTruncInst
- virtual FPTruncInst *clone_impl() const;
+ FPTruncInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3319,7 +3404,7 @@ public:
class FPExtInst : public CastInst {
protected:
/// \brief Clone an identical FPExtInst
- virtual FPExtInst *clone_impl() const;
+ FPExtInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3355,7 +3440,7 @@ public:
class UIToFPInst : public CastInst {
protected:
/// \brief Clone an identical UIToFPInst
- virtual UIToFPInst *clone_impl() const;
+ UIToFPInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3391,7 +3476,7 @@ public:
class SIToFPInst : public CastInst {
protected:
/// \brief Clone an identical SIToFPInst
- virtual SIToFPInst *clone_impl() const;
+ SIToFPInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3427,7 +3512,7 @@ public:
class FPToUIInst : public CastInst {
protected:
/// \brief Clone an identical FPToUIInst
- virtual FPToUIInst *clone_impl() const;
+ FPToUIInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3463,7 +3548,7 @@ public:
class FPToSIInst : public CastInst {
protected:
/// \brief Clone an identical FPToSIInst
- virtual FPToSIInst *clone_impl() const;
+ FPToSIInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3515,7 +3600,7 @@ public:
);
/// \brief Clone an identical IntToPtrInst
- virtual IntToPtrInst *clone_impl() const;
+ IntToPtrInst *clone_impl() const override;
/// \brief Returns the address space of this instruction's pointer type.
unsigned getAddressSpace() const {
@@ -3539,7 +3624,7 @@ public:
class PtrToIntInst : public CastInst {
protected:
/// \brief Clone an identical PtrToIntInst
- virtual PtrToIntInst *clone_impl() const;
+ PtrToIntInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3587,7 +3672,7 @@ public:
class BitCastInst : public CastInst {
protected:
/// \brief Clone an identical BitCastInst
- virtual BitCastInst *clone_impl() const;
+ BitCastInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
@@ -3624,7 +3709,7 @@ public:
class AddrSpaceCastInst : public CastInst {
protected:
/// \brief Clone an identical AddrSpaceCastInst
- virtual AddrSpaceCastInst *clone_impl() const;
+ AddrSpaceCastInst *clone_impl() const override;
public:
/// \brief Constructor with insert-before-instruction semantics
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index 8344c56..e053f78 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -118,8 +118,13 @@ namespace llvm {
class MemIntrinsic : public IntrinsicInst {
public:
Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); }
+ const Use &getRawDestUse() const { return getArgOperandUse(0); }
+ Use &getRawDestUse() { return getArgOperandUse(0); }
Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); }
+ const Use &getLengthUse() const { return getArgOperandUse(2); }
+ Use &getLengthUse() { return getArgOperandUse(2); }
+
ConstantInt *getAlignmentCst() const {
return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3)));
}
@@ -192,6 +197,8 @@ namespace llvm {
/// get* - Return the arguments to the instruction.
///
Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); }
+ const Use &getValueUse() const { return getArgOperandUse(1); }
+ Use &getValueUse() { return getArgOperandUse(1); }
void setValue(Value *Val) {
assert(getValue()->getType() == Val->getType() &&
@@ -215,6 +222,8 @@ namespace llvm {
/// get* - Return the arguments to the instruction.
///
Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); }
+ const Use &getRawSourceUse() const { return getArgOperandUse(1); }
+ Use &getRawSourceUse() { return getArgOperandUse(1); }
/// getSource - This is just like getRawSource, but it strips off any cast
/// instructions that feed it, giving the original input. The returned
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index 473e525..839bbbd 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -79,7 +79,7 @@ namespace Intrinsic {
enum IITDescriptorKind {
Void, VarArg, MMX, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
- Argument, ExtendVecArgument, TruncVecArgument
+ Argument, ExtendArgument, TruncArgument, HalfVecArgument
} Kind;
union {
@@ -98,13 +98,13 @@ namespace Intrinsic {
AK_AnyPointer
};
unsigned getArgumentNumber() const {
- assert(Kind == Argument || Kind == ExtendVecArgument ||
- Kind == TruncVecArgument);
+ assert(Kind == Argument || Kind == ExtendArgument ||
+ Kind == TruncArgument || Kind == HalfVecArgument);
return Argument_Info >> 2;
}
ArgKind getArgumentKind() const {
- assert(Kind == Argument || Kind == ExtendVecArgument ||
- Kind == TruncVecArgument);
+ assert(Kind == Argument || Kind == ExtendArgument ||
+ Kind == TruncArgument || Kind == HalfVecArgument);
return (ArgKind)(Argument_Info&3);
}
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index ded6cc1..6a48f17 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -69,6 +69,10 @@ class ReadNone<int argNo> : IntrinsicProperty {
def IntrNoReturn : IntrinsicProperty;
+// IntrNoduplicate - Calls to this intrinsic cannot be duplicated.
+// Parallels the noduplicate attribute on LLVM IR functions.
+def IntrNoDuplicate : IntrinsicProperty;
+
//===----------------------------------------------------------------------===//
// Types used by intrinsics.
//===----------------------------------------------------------------------===//
@@ -102,12 +106,16 @@ class LLVMMatchType<int num>
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>;
+// Match the type of another intrinsic parameter that is expected to be based on
+// an integral type (i.e. either iN or <N x iM>), but change the scalar 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 LLVMExtendedType<int num> : LLVMMatchType<num>;
+class LLVMTruncatedType<int num> : LLVMMatchType<num>;
+
+// Match the type of another intrinsic parameter that is expected to be a
+// vector type, but change the element count to be half as many
+class LLVMHalfElementsVectorType<int num> : LLVMMatchType<num>;
def llvm_void_ty : LLVMType<isVoid>;
def llvm_anyint_ty : LLVMType<iAny>;
@@ -285,10 +293,17 @@ def int_memset : Intrinsic<[],
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 {
+let Properties = [IntrNoMem] in {
+ def int_fma : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>]>;
+ def int_fmuladd : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>]>;
+
+ // These functions do not read memory, but are sensitive to the
+ // rounding mode. LLVM purposely does not model changes to the FP
+ // environment so they can be treated as readnone.
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>]>;
@@ -311,16 +326,6 @@ let Properties = [IntrReadMem] in {
def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
}
-let Properties = [IntrNoMem] in {
- def int_fma : Intrinsic<[llvm_anyfloat_ty],
- [LLVMMatchType<0>, LLVMMatchType<0>,
- LLVMMatchType<0>]>;
-
- def int_fmuladd : 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], [IntrNoReturn]>;
@@ -458,13 +463,14 @@ def int_invariant_end : Intrinsic<[],
//===------------------------ Stackmap Intrinsics -------------------------===//
//
def int_experimental_stackmap : Intrinsic<[],
- [llvm_i32_ty, llvm_i32_ty, llvm_vararg_ty]>;
+ [llvm_i64_ty, llvm_i32_ty, llvm_vararg_ty],
+ [Throws]>;
def int_experimental_patchpoint_void : Intrinsic<[],
- [llvm_i32_ty, llvm_i32_ty,
+ [llvm_i64_ty, llvm_i32_ty,
llvm_ptr_ty, llvm_i32_ty,
llvm_vararg_ty]>;
def int_experimental_patchpoint_i64 : Intrinsic<[llvm_i64_ty],
- [llvm_i32_ty, llvm_i32_ty,
+ [llvm_i64_ty, llvm_i32_ty,
llvm_ptr_ty, llvm_i32_ty,
llvm_vararg_ty]>;
@@ -511,6 +517,11 @@ def int_convertus : Intrinsic<[llvm_anyint_ty],
def int_convertuu : Intrinsic<[llvm_anyint_ty],
[llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>;
+// Clear cache intrinsic, default to ignore (ie. emit nothing)
+// maps to void __clear_cache() on supporting platforms
+def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
+ [], "llvm.clear_cache">;
+
//===----------------------------------------------------------------------===//
// Target-specific intrinsics
//===----------------------------------------------------------------------===//
@@ -518,6 +529,7 @@ def int_convertuu : Intrinsic<[llvm_anyint_ty],
include "llvm/IR/IntrinsicsPowerPC.td"
include "llvm/IR/IntrinsicsX86.td"
include "llvm/IR/IntrinsicsARM.td"
+include "llvm/IR/IntrinsicsARM64.td"
include "llvm/IR/IntrinsicsAArch64.td"
include "llvm/IR/IntrinsicsXCore.td"
include "llvm/IR/IntrinsicsHexagon.td"
diff --git a/include/llvm/IR/IntrinsicsAArch64.td b/include/llvm/IR/IntrinsicsAArch64.td
index 68af8c1..61c0e5d 100644
--- a/include/llvm/IR/IntrinsicsAArch64.td
+++ b/include/llvm/IR/IntrinsicsAArch64.td
@@ -36,27 +36,11 @@ def int_aarch64_neon_xtn :
// Vector floating-point convert
def int_aarch64_neon_frintn : Neon_1Arg_Intrinsic;
def int_aarch64_neon_fsqrt : Neon_1Arg_Intrinsic;
-def int_aarch64_neon_fcvtxn :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtns :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtnu :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtps :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtpu :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtms :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtmu :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtas :
+def int_aarch64_neon_vcvtxn :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtau :
- Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtzs :
+def int_aarch64_neon_vcvtzs :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_aarch64_neon_fcvtzu :
+def int_aarch64_neon_vcvtzu :
Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Vector maxNum (Floating Point)
@@ -84,7 +68,7 @@ class Neon_N3V_Intrinsic
[IntrNoMem]>;
class Neon_N2V_Narrow_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
- [LLVMExtendedElementVectorType<0>, llvm_i32_ty],
+ [LLVMExtendedType<0>, llvm_i32_ty],
[IntrNoMem]>;
// Vector rounding shift right by immediate (Signed)
@@ -107,9 +91,6 @@ def int_aarch64_neon_vuqrshrn : Neon_N2V_Narrow_Intrinsic;
class Neon_Across_Intrinsic
: Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-class Neon_2Arg_Across_Float_Intrinsic
- : Intrinsic<[llvm_anyvector_ty], [llvm_v4f32_ty], [IntrNoMem]>;
-
def int_aarch64_neon_saddlv : Neon_Across_Intrinsic;
def int_aarch64_neon_uaddlv : Neon_Across_Intrinsic;
def int_aarch64_neon_smaxv : Neon_Across_Intrinsic;
@@ -117,30 +98,34 @@ def int_aarch64_neon_umaxv : Neon_Across_Intrinsic;
def int_aarch64_neon_sminv : Neon_Across_Intrinsic;
def int_aarch64_neon_uminv : Neon_Across_Intrinsic;
def int_aarch64_neon_vaddv : Neon_Across_Intrinsic;
-def int_aarch64_neon_vmaxv : Neon_Across_Intrinsic;
-def int_aarch64_neon_vminv : Neon_Across_Intrinsic;
-def int_aarch64_neon_vmaxnmv : Neon_Across_Intrinsic;
-def int_aarch64_neon_vminnmv : Neon_Across_Intrinsic;
+def int_aarch64_neon_vmaxv :
+ Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_aarch64_neon_vminv :
+ Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_aarch64_neon_vmaxnmv :
+ Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_aarch64_neon_vminnmv :
+ Intrinsic<[llvm_float_ty], [llvm_v4f32_ty], [IntrNoMem]>;
// Vector Table Lookup.
def int_aarch64_neon_vtbl1 :
Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, LLVMMatchType<0>], [IntrNoMem]>;
+ [llvm_v16i8_ty, LLVMMatchType<0>], [IntrNoMem]>;
def int_aarch64_neon_vtbl2 :
Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<0>],
+ [llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
def int_aarch64_neon_vtbl3 :
Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
LLVMMatchType<0>], [IntrNoMem]>;
def int_aarch64_neon_vtbl4 :
Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
- LLVMMatchType<1>, LLVMMatchType<0>], [IntrNoMem]>;
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, LLVMMatchType<0>], [IntrNoMem]>;
// Vector Table Extension.
// Some elements of the destination vector may not be updated, so the original
@@ -148,23 +133,23 @@ def int_aarch64_neon_vtbl4 :
// arguments after that are the table.
def int_aarch64_neon_vtbx1 :
Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>],
+ [LLVMMatchType<0>, llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
def int_aarch64_neon_vtbx2 :
Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>,
- LLVMMatchType<0>], [IntrNoMem]>;
+ [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+ LLVMMatchType<0>], [IntrNoMem]>;
def int_aarch64_neon_vtbx3 :
Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>,
- LLVMMatchType<1>, LLVMMatchType<0>], [IntrNoMem]>;
+ [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, LLVMMatchType<0>], [IntrNoMem]>;
def int_aarch64_neon_vtbx4 :
Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>,
- LLVMMatchType<1>, LLVMMatchType<1>, LLVMMatchType<0>],
+ [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>],
[IntrNoMem]>;
// Vector Load/store
@@ -233,74 +218,118 @@ def int_aarch64_neon_vqrshlu : Neon_2Arg_Intrinsic;
def int_aarch64_neon_vpadd :
Intrinsic<[llvm_v1i64_ty], [llvm_v2i64_ty],[IntrNoMem]>;
def int_aarch64_neon_vpfadd :
- Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vpfaddq :
- Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Reduce Pairwise Floating Point Max/Min.
def int_aarch64_neon_vpmax :
- Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vpmaxq :
- Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_vpmin :
- Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vpminq :
- Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Reduce Pairwise Floating Point Maxnm/Minnm.
def int_aarch64_neon_vpfmaxnm :
- Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vpfmaxnmq :
- Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_aarch64_neon_vpfminnm :
- Intrinsic<[llvm_v1f32_ty], [llvm_v2f32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vpfminnmq :
- Intrinsic<[llvm_v1f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Signed Integer Convert To Floating-point
-def int_aarch64_neon_vcvtf32_s32 :
- Intrinsic<[llvm_float_ty], [llvm_v1i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vcvtf64_s64 :
- Intrinsic<[llvm_double_ty], [llvm_v1i64_ty], [IntrNoMem]>;
+def int_aarch64_neon_vcvtint2fps :
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
// Scalar Unsigned Integer Convert To Floating-point
-def int_aarch64_neon_vcvtf32_u32 :
- Intrinsic<[llvm_float_ty], [llvm_v1i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vcvtf64_u64 :
- Intrinsic<[llvm_double_ty], [llvm_v1i64_ty], [IntrNoMem]>;
+def int_aarch64_neon_vcvtint2fpu :
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+
+// Scalar Floating-point Convert
+def int_aarch64_neon_fcvtxn :
+ Intrinsic<[llvm_float_ty], [llvm_double_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtns :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtnu :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtps :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtpu :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtms :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtmu :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtas :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtau :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtzs :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+def int_aarch64_neon_fcvtzu :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+
+// Scalar Floating-point Reciprocal Estimate.
+def int_aarch64_neon_vrecpe :
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
// Scalar Floating-point Reciprocal Exponent
-def int_aarch64_neon_vrecpx : Neon_1Arg_Intrinsic;
+def int_aarch64_neon_vrecpx :
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-class Neon_Cmp_Intrinsic
- : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_anyvector_ty],
- [IntrNoMem]>;
+// Scalar Floating-point Reciprocal Square Root Estimate
+def int_aarch64_neon_vrsqrte :
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+// Scalar Floating-point Reciprocal Step
+def int_aarch64_neon_vrecps :
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+// Scalar Floating-point Reciprocal Square Root Step
+def int_aarch64_neon_vrsqrts :
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+// Compare with vector operands.
+class Neon_Cmp_Intrinsic :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_anyvector_ty],
+ [IntrNoMem]>;
+
+// Floating-point compare with scalar operands.
+class Neon_Float_Cmp_Intrinsic :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty, llvm_anyfloat_ty],
+ [IntrNoMem]>;
// Scalar Compare Equal
def int_aarch64_neon_vceq : Neon_Cmp_Intrinsic;
+def int_aarch64_neon_fceq : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Greater-Than or Equal
def int_aarch64_neon_vcge : Neon_Cmp_Intrinsic;
def int_aarch64_neon_vchs : Neon_Cmp_Intrinsic;
+def int_aarch64_neon_fcge : Neon_Float_Cmp_Intrinsic;
+def int_aarch64_neon_fchs : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Less-Than or Equal
def int_aarch64_neon_vclez : Neon_Cmp_Intrinsic;
+def int_aarch64_neon_fclez : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Less-Than
def int_aarch64_neon_vcltz : Neon_Cmp_Intrinsic;
+def int_aarch64_neon_fcltz : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Greater-Than
def int_aarch64_neon_vcgt : Neon_Cmp_Intrinsic;
def int_aarch64_neon_vchi : Neon_Cmp_Intrinsic;
+def int_aarch64_neon_fcgt : Neon_Float_Cmp_Intrinsic;
+def int_aarch64_neon_fchi : Neon_Float_Cmp_Intrinsic;
// Scalar Compare Bitwise Test Bits
def int_aarch64_neon_vtstd : Neon_Cmp_Intrinsic;
// Scalar Floating-point Absolute Compare Greater Than Or Equal
def int_aarch64_neon_vcage : Neon_Cmp_Intrinsic;
-
+def int_aarch64_neon_fcage : Neon_Float_Cmp_Intrinsic;
+
// Scalar Floating-point Absolute Compare Greater Than
def int_aarch64_neon_vcagt : Neon_Cmp_Intrinsic;
+def int_aarch64_neon_fcagt : Neon_Float_Cmp_Intrinsic;
// Scalar Signed Saturating Accumulated of Unsigned Value
def int_aarch64_neon_vuqadd : Neon_2Arg_Intrinsic;
@@ -313,7 +342,9 @@ def int_aarch64_neon_vabs :
Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty], [IntrNoMem]>;
// Scalar Absolute Difference
-def int_aarch64_neon_vabd : Neon_2Arg_Intrinsic;
+def int_aarch64_neon_vabd :
+ Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
// Scalar Negate Value
def int_aarch64_neon_vneg :
@@ -325,6 +356,9 @@ def int_aarch64_neon_vqdmlal : Neon_3Arg_Long_Intrinsic;
// Signed Saturating Doubling Multiply-Subtract Long
def int_aarch64_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic;
+def int_aarch64_neon_vmull_p64 :
+ Intrinsic<[llvm_v16i8_ty], [llvm_v1i64_ty, llvm_v1i64_ty], [IntrNoMem]>;
+
class Neon_2Arg_ShiftImm_Intrinsic
: Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -355,34 +389,19 @@ def int_aarch64_neon_vqshlu_n : Neon_N2V_Intrinsic;
def int_aarch64_neon_vqshlus_n : Neon_N2V_Intrinsic;
// Scalar Signed Fixed-point Convert To Floating-Point (Immediate)
-def int_aarch64_neon_vcvtf32_n_s32 :
- Intrinsic<[llvm_float_ty], [llvm_v1i32_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vcvtf64_n_s64 :
- Intrinsic<[llvm_double_ty], [llvm_v1i64_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_aarch64_neon_vcvtfxs2fp_n :
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty, llvm_i32_ty], [IntrNoMem]>;
// Scalar Unsigned Fixed-point Convert To Floating-Point (Immediate)
-def int_aarch64_neon_vcvtf32_n_u32 :
- Intrinsic<[llvm_float_ty], [llvm_v1i32_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vcvtf64_n_u64 :
- Intrinsic<[llvm_double_ty], [llvm_v1i64_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_aarch64_neon_vcvtfxu2fp_n :
+ Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty, llvm_i32_ty], [IntrNoMem]>;
// Scalar Floating-point Convert To Signed Fixed-point (Immediate)
-def int_aarch64_neon_vcvts_n_s32_f32 :
- Intrinsic<[llvm_v1i32_ty], [llvm_v1f32_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vcvtd_n_s64_f64 :
- Intrinsic<[llvm_v1i64_ty], [llvm_v1f64_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_aarch64_neon_vcvtfp2fxs_n :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
// Scalar Floating-point Convert To Unsigned Fixed-point (Immediate)
-def int_aarch64_neon_vcvts_n_u32_f32 :
- Intrinsic<[llvm_v1i32_ty], [llvm_v1f32_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_vcvtd_n_u64_f64 :
- Intrinsic<[llvm_v1i64_ty], [llvm_v1f64_ty, llvm_i32_ty], [IntrNoMem]>;
-
-class Neon_SHA_Intrinsic
- : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v1i32_ty, llvm_v4i32_ty],
- [IntrNoMem]>;
+def int_aarch64_neon_vcvtfp2fxu_n :
+ Intrinsic<[llvm_anyvector_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_aarch64_neon_sha1c : Neon_SHA_Intrinsic;
-def int_aarch64_neon_sha1m : Neon_SHA_Intrinsic;
-def int_aarch64_neon_sha1p : Neon_SHA_Intrinsic;
}
diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td
index 0b50d64..482f98e 100644
--- a/include/llvm/IR/IntrinsicsARM.td
+++ b/include/llvm/IR/IntrinsicsARM.td
@@ -38,12 +38,20 @@ def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
def int_arm_ldrex : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty]>;
def int_arm_strex : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyptr_ty]>;
+
+def int_arm_ldaex : Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty]>;
+def int_arm_stlex : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_anyptr_ty]>;
+
def int_arm_clrex : Intrinsic<[]>;
def int_arm_strexd : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty,
llvm_ptr_ty]>;
def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
+def int_arm_stlexd : Intrinsic<[llvm_i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty]>;
+def int_arm_ldaexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>;
+
//===----------------------------------------------------------------------===//
// Data barrier instructions
def int_arm_dmb : GCCBuiltin<"__builtin_arm_dmb">, Intrinsic<[], [llvm_i32_ty]>;
@@ -123,20 +131,15 @@ def int_arm_sevl : Intrinsic<[], []>;
class Neon_1Arg_Intrinsic
: Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
class Neon_1Arg_Narrow_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMExtendedElementVectorType<0>], [IntrNoMem]>;
+ : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<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>],
+ : Intrinsic<[llvm_anyvector_ty], [LLVMExtendedType<0>, LLVMExtendedType<0>],
[IntrNoMem]>;
class Neon_2Arg_Long_Intrinsic
- : Intrinsic<[llvm_anyvector_ty],
- [LLVMTruncatedElementVectorType<0>,
- LLVMTruncatedElementVectorType<0>],
+ : Intrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>, LLVMTruncatedType<0>],
[IntrNoMem]>;
class Neon_3Arg_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -144,9 +147,7 @@ class Neon_3Arg_Intrinsic
[IntrNoMem]>;
class Neon_3Arg_Long_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>,
- LLVMTruncatedElementVectorType<0>,
- LLVMTruncatedElementVectorType<0>],
+ [LLVMMatchType<0>, LLVMTruncatedType<0>, LLVMTruncatedType<0>],
[IntrNoMem]>;
class Neon_CvtFxToFP_Intrinsic
: Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -155,6 +156,10 @@ class Neon_CvtFPToFx_Intrinsic
class Neon_CvtFPtoInt_1Arg_Intrinsic
: Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+class Neon_Compare_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMMatchType<1>],
+ [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.
@@ -224,18 +229,8 @@ def int_arm_neon_vqsubu : Neon_2Arg_Intrinsic;
def int_arm_neon_vrsubhn : Neon_2Arg_Narrow_Intrinsic;
// Vector Absolute Compare.
-def int_arm_neon_vacged : Intrinsic<[llvm_v2i32_ty],
- [llvm_v2f32_ty, llvm_v2f32_ty],
- [IntrNoMem]>;
-def int_arm_neon_vacgeq : Intrinsic<[llvm_v4i32_ty],
- [llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
-def int_arm_neon_vacgtd : Intrinsic<[llvm_v2i32_ty],
- [llvm_v2f32_ty, llvm_v2f32_ty],
- [IntrNoMem]>;
-def int_arm_neon_vacgtq : Intrinsic<[llvm_v4i32_ty],
- [llvm_v4f32_ty, llvm_v4f32_ty],
- [IntrNoMem]>;
+def int_arm_neon_vacge : Neon_Compare_Intrinsic;
+def int_arm_neon_vacgt : Neon_Compare_Intrinsic;
// Vector Absolute Differences.
def int_arm_neon_vabds : Neon_2Arg_Intrinsic;
@@ -293,9 +288,6 @@ def int_arm_neon_vpminu : Neon_2Arg_Intrinsic;
// 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;
@@ -472,19 +464,37 @@ def int_arm_neon_vbsl : Intrinsic<[llvm_anyvector_ty],
// Crypto instructions
-def int_arm_neon_aesd : Neon_2Arg_Intrinsic;
-def int_arm_neon_aese : Neon_2Arg_Intrinsic;
-def int_arm_neon_aesimc : Neon_1Arg_Intrinsic;
-def int_arm_neon_aesmc : Neon_1Arg_Intrinsic;
-def int_arm_neon_sha1h : Neon_1Arg_Intrinsic;
-def int_arm_neon_sha1su1 : Neon_2Arg_Intrinsic;
-def int_arm_neon_sha256su0 : Neon_2Arg_Intrinsic;
-def int_arm_neon_sha1c : Neon_3Arg_Intrinsic;
-def int_arm_neon_sha1m : Neon_3Arg_Intrinsic;
-def int_arm_neon_sha1p : Neon_3Arg_Intrinsic;
-def int_arm_neon_sha1su0: Neon_3Arg_Intrinsic;
-def int_arm_neon_sha256h: Neon_3Arg_Intrinsic;
-def int_arm_neon_sha256h2: Neon_3Arg_Intrinsic;
-def int_arm_neon_sha256su1: Neon_3Arg_Intrinsic;
+class AES_1Arg_Intrinsic : Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty], [IntrNoMem]>;
+class AES_2Arg_Intrinsic : Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+class SHA_1Arg_Intrinsic : Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
+ [IntrNoMem]>;
+class SHA_2Arg_Intrinsic : Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+class SHA_3Arg_i32_Intrinsic : Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+class SHA_3Arg_v4i32_Intrinsic : Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+def int_arm_neon_aesd : AES_2Arg_Intrinsic;
+def int_arm_neon_aese : AES_2Arg_Intrinsic;
+def int_arm_neon_aesimc : AES_1Arg_Intrinsic;
+def int_arm_neon_aesmc : AES_1Arg_Intrinsic;
+def int_arm_neon_sha1h : SHA_1Arg_Intrinsic;
+def int_arm_neon_sha1su1 : SHA_2Arg_Intrinsic;
+def int_arm_neon_sha256su0 : SHA_2Arg_Intrinsic;
+def int_arm_neon_sha1c : SHA_3Arg_i32_Intrinsic;
+def int_arm_neon_sha1m : SHA_3Arg_i32_Intrinsic;
+def int_arm_neon_sha1p : SHA_3Arg_i32_Intrinsic;
+def int_arm_neon_sha1su0: SHA_3Arg_v4i32_Intrinsic;
+def int_arm_neon_sha256h: SHA_3Arg_v4i32_Intrinsic;
+def int_arm_neon_sha256h2: SHA_3Arg_v4i32_Intrinsic;
+def int_arm_neon_sha256su1: SHA_3Arg_v4i32_Intrinsic;
} // end TargetPrefix
diff --git a/include/llvm/IR/IntrinsicsARM64.td b/include/llvm/IR/IntrinsicsARM64.td
new file mode 100644
index 0000000..d7f307e
--- /dev/null
+++ b/include/llvm/IR/IntrinsicsARM64.td
@@ -0,0 +1,628 @@
+//===- IntrinsicsARM64.td - Defines ARM64 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 ARM64-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+let TargetPrefix = "arm64" in {
+
+def int_arm64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty]>;
+def int_arm64_stxr : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_anyptr_ty]>;
+def int_arm64_clrex : Intrinsic<[]>;
+
+def int_arm64_ldxp : Intrinsic<[llvm_i64_ty, llvm_i64_ty], [llvm_ptr_ty]>;
+def int_arm64_stxp : Intrinsic<[llvm_i32_ty], [llvm_i64_ty, llvm_i64_ty,
+ llvm_ptr_ty]>;
+
+def int_arm64_sdiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+ LLVMMatchType<0>], [IntrNoMem]>;
+def int_arm64_udiv : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
+ LLVMMatchType<0>], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Advanced SIMD (NEON)
+
+let TargetPrefix = "arm64" in { // All intrinsics start with "llvm.arm64.".
+ class AdvSIMD_2Scalar_Float_Intrinsic
+ : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+ class AdvSIMD_FPToIntRounding_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]>;
+
+ class AdvSIMD_1IntArg_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ class AdvSIMD_1FloatArg_Intrinsic
+ : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ class AdvSIMD_1VectorArg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+ class AdvSIMD_1VectorArg_Expand_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+ class AdvSIMD_1VectorArg_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMTruncatedType<0>], [IntrNoMem]>;
+ class AdvSIMD_1IntArg_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [llvm_anyint_ty], [IntrNoMem]>;
+ class AdvSIMD_1VectorArg_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [LLVMExtendedType<0>], [IntrNoMem]>;
+ class AdvSIMD_1VectorArg_Int_Across_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+ class AdvSIMD_1VectorArg_Float_Across_Intrinsic
+ : Intrinsic<[llvm_anyfloat_ty], [llvm_anyvector_ty], [IntrNoMem]>;
+
+ class AdvSIMD_2IntArg_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2FloatArg_Intrinsic
+ : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Compare_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMMatchType<1>],
+ [IntrNoMem]>;
+ class AdvSIMD_2Arg_FloatCompare_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMTruncatedType<0>, LLVMTruncatedType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Wide_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMTruncatedType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMExtendedType<0>, LLVMExtendedType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2Arg_Scalar_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyint_ty],
+ [LLVMExtendedType<0>, llvm_i32_ty],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Scalar_Expand_BySize_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Scalar_Wide_BySize_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMTruncatedType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMTruncatedType<0>, llvm_i32_ty],
+ [IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Tied_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMHalfElementsVectorType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
+
+ class AdvSIMD_3VectorArg_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_3VectorArg_Scalar_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
+ [IntrNoMem]>;
+ class AdvSIMD_3VectorArg_Tied_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMHalfElementsVectorType<0>, llvm_anyvector_ty,
+ LLVMMatchType<1>], [IntrNoMem]>;
+ class AdvSIMD_3VectorArg_Scalar_Tied_Narrow_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMHalfElementsVectorType<0>, llvm_anyvector_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ class AdvSIMD_CvtFxToFP_Intrinsic
+ : Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ class AdvSIMD_CvtFPToFx_Intrinsic
+ : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+}
+
+// Arithmetic ops
+
+let Properties = [IntrNoMem] in {
+ // Vector Add Across Lanes
+ def int_arm64_neon_saddv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_uaddv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_faddv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+
+ // Vector Long Add Across Lanes
+ def int_arm64_neon_saddlv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_uaddlv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+
+ // Vector Halving Add
+ def int_arm64_neon_shadd : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_uhadd : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Vector Rounding Halving Add
+ def int_arm64_neon_srhadd : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_urhadd : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Vector Saturating Add
+ def int_arm64_neon_sqadd : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_suqadd : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_usqadd : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_uqadd : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Add High-Half
+ // FIXME: this is a legacy intrinsic for aarch64_simd.h. Remove it when that
+ // header is no longer supported.
+ def int_arm64_neon_addhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+ // Vector Rounding Add High-Half
+ def int_arm64_neon_raddhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+ // Vector Saturating Doubling Multiply High
+ def int_arm64_neon_sqdmulh : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Saturating Rounding Doubling Multiply High
+ def int_arm64_neon_sqrdmulh : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Polynominal Multiply
+ def int_arm64_neon_pmul : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Vector Long Multiply
+ def int_arm64_neon_smull : AdvSIMD_2VectorArg_Long_Intrinsic;
+ def int_arm64_neon_umull : AdvSIMD_2VectorArg_Long_Intrinsic;
+ def int_arm64_neon_pmull : AdvSIMD_2VectorArg_Long_Intrinsic;
+
+ // 64-bit polynomial multiply really returns an i128, which is not legal. Fake
+ // it with a v16i8.
+ def int_arm64_neon_pmull64 :
+ Intrinsic<[llvm_v16i8_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
+ // Vector Extending Multiply
+ def int_arm64_neon_fmulx : AdvSIMD_2FloatArg_Intrinsic;
+
+ // Vector Saturating Doubling Long Multiply
+ def int_arm64_neon_sqdmull : AdvSIMD_2VectorArg_Long_Intrinsic;
+ def int_arm64_neon_sqdmulls_scalar
+ : Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+
+ // Vector Halving Subtract
+ def int_arm64_neon_shsub : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_uhsub : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Vector Saturating Subtract
+ def int_arm64_neon_sqsub : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_uqsub : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Subtract High-Half
+ // FIXME: this is a legacy intrinsic for aarch64_simd.h. Remove it when that
+ // header is no longer supported.
+ def int_arm64_neon_subhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+ // Vector Rounding Subtract High-Half
+ def int_arm64_neon_rsubhn : AdvSIMD_2VectorArg_Narrow_Intrinsic;
+
+ // Vector Compare Absolute Greater-than-or-equal
+ def int_arm64_neon_facge : AdvSIMD_2Arg_FloatCompare_Intrinsic;
+
+ // Vector Compare Absolute Greater-than
+ def int_arm64_neon_facgt : AdvSIMD_2Arg_FloatCompare_Intrinsic;
+
+ // Vector Absolute Difference
+ def int_arm64_neon_sabd : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_uabd : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fabd : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Scalar Absolute Difference
+ def int_arm64_sisd_fabd : AdvSIMD_2Scalar_Float_Intrinsic;
+
+ // Vector Max
+ def int_arm64_neon_smax : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_umax : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fmax : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fmaxnmp : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Vector Max Across Lanes
+ def int_arm64_neon_smaxv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_umaxv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_fmaxv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+ def int_arm64_neon_fmaxnmv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+
+ // Vector Min
+ def int_arm64_neon_smin : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_umin : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fmin : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fminnmp : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Vector Min/Max Number
+ def int_arm64_neon_fminnm : AdvSIMD_2FloatArg_Intrinsic;
+ def int_arm64_neon_fmaxnm : AdvSIMD_2FloatArg_Intrinsic;
+
+ // Vector Min Across Lanes
+ def int_arm64_neon_sminv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_uminv : AdvSIMD_1VectorArg_Int_Across_Intrinsic;
+ def int_arm64_neon_fminv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+ def int_arm64_neon_fminnmv : AdvSIMD_1VectorArg_Float_Across_Intrinsic;
+
+ // Pairwise Add
+ def int_arm64_neon_addp : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Long Pairwise Add
+ // FIXME: In theory, we shouldn't need intrinsics for saddlp or
+ // uaddlp, but tblgen's type inference currently can't handle the
+ // pattern fragments this ends up generating.
+ def int_arm64_neon_saddlp : AdvSIMD_1VectorArg_Expand_Intrinsic;
+ def int_arm64_neon_uaddlp : AdvSIMD_1VectorArg_Expand_Intrinsic;
+
+ // Folding Maximum
+ def int_arm64_neon_smaxp : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_umaxp : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fmaxp : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Folding Minimum
+ def int_arm64_neon_sminp : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_uminp : AdvSIMD_2VectorArg_Intrinsic;
+ def int_arm64_neon_fminp : AdvSIMD_2VectorArg_Intrinsic;
+
+ // Reciprocal Estimate/Step
+ def int_arm64_neon_frecps : AdvSIMD_2FloatArg_Intrinsic;
+ def int_arm64_neon_frsqrts : AdvSIMD_2FloatArg_Intrinsic;
+
+ // Reciprocal Exponent
+ def int_arm64_neon_frecpx : AdvSIMD_1FloatArg_Intrinsic;
+
+ // Vector Saturating Shift Left
+ def int_arm64_neon_sqshl : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_uqshl : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Rounding Shift Left
+ def int_arm64_neon_srshl : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_urshl : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Saturating Rounding Shift Left
+ def int_arm64_neon_sqrshl : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_uqrshl : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Signed->Unsigned Shift Left by Constant
+ def int_arm64_neon_sqshlu : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Signed->Unsigned Narrowing Saturating Shift Right by Constant
+ def int_arm64_neon_sqshrun : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+ // Vector Signed->Unsigned Rounding Narrowing Saturating Shift Right by Const
+ def int_arm64_neon_sqrshrun : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+ // Vector Narrowing Shift Right by Constant
+ def int_arm64_neon_sqshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+ def int_arm64_neon_uqshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+ // Vector Rounding Narrowing Shift Right by Constant
+ def int_arm64_neon_rshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+ // Vector Rounding Narrowing Saturating Shift Right by Constant
+ def int_arm64_neon_sqrshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+ def int_arm64_neon_uqrshrn : AdvSIMD_2Arg_Scalar_Narrow_Intrinsic;
+
+ // Vector Shift Left
+ def int_arm64_neon_sshl : AdvSIMD_2IntArg_Intrinsic;
+ def int_arm64_neon_ushl : AdvSIMD_2IntArg_Intrinsic;
+
+ // Vector Widening Shift Left by Constant
+ def int_arm64_neon_shll : AdvSIMD_2VectorArg_Scalar_Wide_BySize_Intrinsic;
+ def int_arm64_neon_sshll : AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic;
+ def int_arm64_neon_ushll : AdvSIMD_2VectorArg_Scalar_Wide_Intrinsic;
+
+ // Vector Shift Right by Constant and Insert
+ def int_arm64_neon_vsri : AdvSIMD_3VectorArg_Scalar_Intrinsic;
+
+ // Vector Shift Left by Constant and Insert
+ def int_arm64_neon_vsli : AdvSIMD_3VectorArg_Scalar_Intrinsic;
+
+ // Vector Saturating Narrow
+ def int_arm64_neon_scalar_sqxtn: AdvSIMD_1IntArg_Narrow_Intrinsic;
+ def int_arm64_neon_scalar_uqxtn : AdvSIMD_1IntArg_Narrow_Intrinsic;
+ def int_arm64_neon_sqxtn : AdvSIMD_1VectorArg_Narrow_Intrinsic;
+ def int_arm64_neon_uqxtn : AdvSIMD_1VectorArg_Narrow_Intrinsic;
+
+ // Vector Saturating Extract and Unsigned Narrow
+ def int_arm64_neon_scalar_sqxtun : AdvSIMD_1IntArg_Narrow_Intrinsic;
+ def int_arm64_neon_sqxtun : AdvSIMD_1VectorArg_Narrow_Intrinsic;
+
+ // Vector Absolute Value
+ def int_arm64_neon_abs : AdvSIMD_1IntArg_Intrinsic;
+
+ // Vector Saturating Absolute Value
+ def int_arm64_neon_sqabs : AdvSIMD_1IntArg_Intrinsic;
+
+ // Vector Saturating Negation
+ def int_arm64_neon_sqneg : AdvSIMD_1IntArg_Intrinsic;
+
+ // Vector Count Leading Sign Bits
+ def int_arm64_neon_cls : AdvSIMD_1VectorArg_Intrinsic;
+
+ // Vector Reciprocal Estimate
+ def int_arm64_neon_urecpe : AdvSIMD_1VectorArg_Intrinsic;
+ def int_arm64_neon_frecpe : AdvSIMD_1FloatArg_Intrinsic;
+
+ // Vector Square Root Estimate
+ def int_arm64_neon_ursqrte : AdvSIMD_1VectorArg_Intrinsic;
+ def int_arm64_neon_frsqrte : AdvSIMD_1FloatArg_Intrinsic;
+
+ // Vector Bitwise Reverse
+ def int_arm64_neon_rbit : AdvSIMD_1VectorArg_Intrinsic;
+
+ // Vector Conversions Between Half-Precision and Single-Precision.
+ def int_arm64_neon_vcvtfp2hf
+ : Intrinsic<[llvm_v4i16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_arm64_neon_vcvthf2fp
+ : Intrinsic<[llvm_v4f32_ty], [llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Vector Conversions Between Floating-point and Fixed-point.
+ def int_arm64_neon_vcvtfp2fxs : AdvSIMD_CvtFPToFx_Intrinsic;
+ def int_arm64_neon_vcvtfp2fxu : AdvSIMD_CvtFPToFx_Intrinsic;
+ def int_arm64_neon_vcvtfxs2fp : AdvSIMD_CvtFxToFP_Intrinsic;
+ def int_arm64_neon_vcvtfxu2fp : AdvSIMD_CvtFxToFP_Intrinsic;
+
+ // Vector FP->Int Conversions
+ def int_arm64_neon_fcvtas : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtau : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtms : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtmu : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtns : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtnu : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtps : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtpu : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtzs : AdvSIMD_FPToIntRounding_Intrinsic;
+ def int_arm64_neon_fcvtzu : AdvSIMD_FPToIntRounding_Intrinsic;
+
+ // Vector FP Rounding: only ties to even is unrepresented by a normal
+ // intrinsic.
+ def int_arm64_neon_frintn : AdvSIMD_1FloatArg_Intrinsic;
+
+ // Scalar FP->Int conversions
+
+ // Vector FP Inexact Narrowing
+ def int_arm64_neon_fcvtxn : AdvSIMD_1VectorArg_Expand_Intrinsic;
+
+ // Scalar FP Inexact Narrowing
+ def int_arm64_sisd_fcvtxn : Intrinsic<[llvm_float_ty], [llvm_double_ty],
+ [IntrNoMem]>;
+}
+
+let TargetPrefix = "arm64" in { // All intrinsics start with "llvm.arm64.".
+ class AdvSIMD_2Vector2Index_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_i64_ty, LLVMMatchType<0>, llvm_i64_ty],
+ [IntrNoMem]>;
+}
+
+// Vector element to element moves
+def int_arm64_neon_vcopy_lane: AdvSIMD_2Vector2Index_Intrinsic;
+
+let TargetPrefix = "arm64" in { // All intrinsics start with "llvm.arm64.".
+ class AdvSIMD_1Vec_Load_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadArgMem]>;
+ class AdvSIMD_1Vec_Store_Lane_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadWriteArgMem, NoCapture<2>]>;
+
+ class AdvSIMD_2Vec_Load_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadArgMem]>;
+ class AdvSIMD_2Vec_Load_Lane_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadArgMem]>;
+ class AdvSIMD_2Vec_Store_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadWriteArgMem, NoCapture<2>]>;
+ class AdvSIMD_2Vec_Store_Lane_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadWriteArgMem, NoCapture<3>]>;
+
+ class AdvSIMD_3Vec_Load_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadArgMem]>;
+ class AdvSIMD_3Vec_Load_Lane_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadArgMem]>;
+ class AdvSIMD_3Vec_Store_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadWriteArgMem, NoCapture<3>]>;
+ class AdvSIMD_3Vec_Store_Lane_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadWriteArgMem, NoCapture<4>]>;
+
+ class AdvSIMD_4Vec_Load_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>],
+ [LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadArgMem]>;
+ class AdvSIMD_4Vec_Load_Lane_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>],
+ [LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadArgMem]>;
+ class AdvSIMD_4Vec_Store_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMAnyPointerType<LLVMMatchType<0>>],
+ [IntrReadWriteArgMem, NoCapture<4>]>;
+ class AdvSIMD_4Vec_Store_Lane_Intrinsic
+ : Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i64_ty, llvm_anyptr_ty],
+ [IntrReadWriteArgMem, NoCapture<5>]>;
+}
+
+// Memory ops
+
+def int_arm64_neon_ld1x2 : AdvSIMD_2Vec_Load_Intrinsic;
+def int_arm64_neon_ld1x3 : AdvSIMD_3Vec_Load_Intrinsic;
+def int_arm64_neon_ld1x4 : AdvSIMD_4Vec_Load_Intrinsic;
+
+def int_arm64_neon_st1x2 : AdvSIMD_2Vec_Store_Intrinsic;
+def int_arm64_neon_st1x3 : AdvSIMD_3Vec_Store_Intrinsic;
+def int_arm64_neon_st1x4 : AdvSIMD_4Vec_Store_Intrinsic;
+
+def int_arm64_neon_ld2 : AdvSIMD_2Vec_Load_Intrinsic;
+def int_arm64_neon_ld3 : AdvSIMD_3Vec_Load_Intrinsic;
+def int_arm64_neon_ld4 : AdvSIMD_4Vec_Load_Intrinsic;
+
+def int_arm64_neon_ld2lane : AdvSIMD_2Vec_Load_Lane_Intrinsic;
+def int_arm64_neon_ld3lane : AdvSIMD_3Vec_Load_Lane_Intrinsic;
+def int_arm64_neon_ld4lane : AdvSIMD_4Vec_Load_Lane_Intrinsic;
+
+def int_arm64_neon_ld2r : AdvSIMD_2Vec_Load_Intrinsic;
+def int_arm64_neon_ld3r : AdvSIMD_3Vec_Load_Intrinsic;
+def int_arm64_neon_ld4r : AdvSIMD_4Vec_Load_Intrinsic;
+
+def int_arm64_neon_st2 : AdvSIMD_2Vec_Store_Intrinsic;
+def int_arm64_neon_st3 : AdvSIMD_3Vec_Store_Intrinsic;
+def int_arm64_neon_st4 : AdvSIMD_4Vec_Store_Intrinsic;
+
+def int_arm64_neon_st2lane : AdvSIMD_2Vec_Store_Lane_Intrinsic;
+def int_arm64_neon_st3lane : AdvSIMD_3Vec_Store_Lane_Intrinsic;
+def int_arm64_neon_st4lane : AdvSIMD_4Vec_Store_Lane_Intrinsic;
+
+let TargetPrefix = "arm64" in { // All intrinsics start with "llvm.arm64.".
+ class AdvSIMD_Tbl1_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [llvm_v16i8_ty, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_Tbl2_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>], [IntrNoMem]>;
+ class AdvSIMD_Tbl3_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+ LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_Tbl4_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+ LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+ class AdvSIMD_Tbx1_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_v16i8_ty, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_Tbx2_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+ LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_Tbx3_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, LLVMMatchType<0>],
+ [IntrNoMem]>;
+ class AdvSIMD_Tbx4_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_v16i8_ty, LLVMMatchType<0>],
+ [IntrNoMem]>;
+}
+def int_arm64_neon_tbl1 : AdvSIMD_Tbl1_Intrinsic;
+def int_arm64_neon_tbl2 : AdvSIMD_Tbl2_Intrinsic;
+def int_arm64_neon_tbl3 : AdvSIMD_Tbl3_Intrinsic;
+def int_arm64_neon_tbl4 : AdvSIMD_Tbl4_Intrinsic;
+
+def int_arm64_neon_tbx1 : AdvSIMD_Tbx1_Intrinsic;
+def int_arm64_neon_tbx2 : AdvSIMD_Tbx2_Intrinsic;
+def int_arm64_neon_tbx3 : AdvSIMD_Tbx3_Intrinsic;
+def int_arm64_neon_tbx4 : AdvSIMD_Tbx4_Intrinsic;
+
+let TargetPrefix = "arm64" in {
+ class Crypto_AES_DataKey_Intrinsic
+ : Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+ class Crypto_AES_Data_Intrinsic
+ : Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
+
+ // SHA intrinsic taking 5 words of the hash (v4i32, i32) and 4 of the schedule
+ // (v4i32).
+ class Crypto_SHA_5Hash4Schedule_Intrinsic
+ : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ // SHA intrinsic taking 5 words of the hash (v4i32, i32) and 4 of the schedule
+ // (v4i32).
+ class Crypto_SHA_1Hash_Intrinsic
+ : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
+
+ // SHA intrinsic taking 8 words of the schedule
+ class Crypto_SHA_8Schedule_Intrinsic
+ : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+
+ // SHA intrinsic taking 12 words of the schedule
+ class Crypto_SHA_12Schedule_Intrinsic
+ : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ // SHA intrinsic taking 8 words of the hash and 4 of the schedule.
+ class Crypto_SHA_8Hash4Schedule_Intrinsic
+ : Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+}
+
+// AES
+def int_arm64_crypto_aese : Crypto_AES_DataKey_Intrinsic;
+def int_arm64_crypto_aesd : Crypto_AES_DataKey_Intrinsic;
+def int_arm64_crypto_aesmc : Crypto_AES_Data_Intrinsic;
+def int_arm64_crypto_aesimc : Crypto_AES_Data_Intrinsic;
+
+// SHA1
+def int_arm64_crypto_sha1c : Crypto_SHA_5Hash4Schedule_Intrinsic;
+def int_arm64_crypto_sha1p : Crypto_SHA_5Hash4Schedule_Intrinsic;
+def int_arm64_crypto_sha1m : Crypto_SHA_5Hash4Schedule_Intrinsic;
+def int_arm64_crypto_sha1h : Crypto_SHA_1Hash_Intrinsic;
+
+def int_arm64_crypto_sha1su0 : Crypto_SHA_12Schedule_Intrinsic;
+def int_arm64_crypto_sha1su1 : Crypto_SHA_8Schedule_Intrinsic;
+
+// SHA256
+def int_arm64_crypto_sha256h : Crypto_SHA_8Hash4Schedule_Intrinsic;
+def int_arm64_crypto_sha256h2 : Crypto_SHA_8Hash4Schedule_Intrinsic;
+def int_arm64_crypto_sha256su0 : Crypto_SHA_8Schedule_Intrinsic;
+def int_arm64_crypto_sha256su1 : Crypto_SHA_12Schedule_Intrinsic;
+
+//===----------------------------------------------------------------------===//
+// CRC32
+
+let TargetPrefix = "arm64" in {
+
+def int_arm64_crc32b : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32cb : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32h : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32ch : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32w : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32cw : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32x : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+def int_arm64_crc32cx : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+}
diff --git a/include/llvm/IR/IntrinsicsMips.td b/include/llvm/IR/IntrinsicsMips.td
index 42c5821..3455761 100644
--- a/include/llvm/IR/IntrinsicsMips.td
+++ b/include/llvm/IR/IntrinsicsMips.td
@@ -26,22 +26,26 @@ let TargetPrefix = "mips" in { // All intrinsics start with "llvm.mips.".
// Addition/subtraction
def int_mips_addu_qb : GCCBuiltin<"__builtin_mips_addu_qb">,
- Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty],
+ [Commutative, IntrNoMem]>;
def int_mips_addu_s_qb : GCCBuiltin<"__builtin_mips_addu_s_qb">,
- Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty],
+ [Commutative, IntrNoMem]>;
def int_mips_subu_qb : GCCBuiltin<"__builtin_mips_subu_qb">,
- Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>;
def int_mips_subu_s_qb : GCCBuiltin<"__builtin_mips_subu_s_qb">,
- Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], []>;
+ Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [IntrNoMem]>;
def int_mips_addq_ph : GCCBuiltin<"__builtin_mips_addq_ph">,
- Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty],
+ [Commutative, IntrNoMem]>;
def int_mips_addq_s_ph : GCCBuiltin<"__builtin_mips_addq_s_ph">,
- Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [Commutative]>;
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty],
+ [Commutative, IntrNoMem]>;
def int_mips_subq_ph : GCCBuiltin<"__builtin_mips_subq_ph">,
- Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], []>;
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
def int_mips_subq_s_ph : GCCBuiltin<"__builtin_mips_subq_s_ph">,
- Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], []>;
+ Intrinsic<[mips_v2q15_ty], [mips_v2q15_ty, mips_v2q15_ty], [IntrNoMem]>;
def int_mips_madd: GCCBuiltin<"__builtin_mips_madd">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
@@ -833,6 +837,12 @@ def int_mips_div_u_w : GCCBuiltin<"__builtin_msa_div_u_w">,
def int_mips_div_u_d : GCCBuiltin<"__builtin_msa_div_u_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
+// This instruction is part of the MSA spec but it does not share the
+// __builtin_msa prefix because it operates on GP registers.
+def int_mips_dlsa : GCCBuiltin<"__builtin_mips_dlsa">,
+ Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
def int_mips_dotp_s_h : GCCBuiltin<"__builtin_msa_dotp_s_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_dotp_s_w : GCCBuiltin<"__builtin_msa_dotp_s_w">,
@@ -1544,22 +1554,26 @@ def int_mips_shf_w : GCCBuiltin<"__builtin_msa_shf_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_b : GCCBuiltin<"__builtin_msa_sld_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_h : GCCBuiltin<"__builtin_msa_sld_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_w : GCCBuiltin<"__builtin_msa_sld_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sld_d : GCCBuiltin<"__builtin_msa_sld_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_sldi_b : GCCBuiltin<"__builtin_msa_sldi_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_mips_sldi_h : GCCBuiltin<"__builtin_msa_sldi_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_mips_sldi_w : GCCBuiltin<"__builtin_msa_sldi_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_mips_sldi_d : GCCBuiltin<"__builtin_msa_sldi_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_mips_sll_b : GCCBuiltin<"__builtin_msa_sll_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td
index a372c22..7f72ce8 100644
--- a/include/llvm/IR/IntrinsicsNVVM.td
+++ b/include/llvm/IR/IntrinsicsNVVM.td
@@ -730,15 +730,15 @@ def llvm_anyi64ptr_ty : LLVMAnyPointerType<llvm_i64_ty>; // (space)i64*
// Bar.Sync
def int_cuda_syncthreads : GCCBuiltin<"__syncthreads">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoDuplicate]>;
def int_nvvm_barrier0 : GCCBuiltin<"__nvvm_bar0">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoDuplicate]>;
def int_nvvm_barrier0_popc : GCCBuiltin<"__nvvm_bar0_popc">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoDuplicate]>;
def int_nvvm_barrier0_and : GCCBuiltin<"__nvvm_bar0_and">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoDuplicate]>;
def int_nvvm_barrier0_or : GCCBuiltin<"__nvvm_bar0_or">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoDuplicate]>;
// Membar
def int_nvvm_membar_cta : GCCBuiltin<"__nvvm_membar_cta">,
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 4c5718f..8f64b5d 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -536,6 +536,8 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[], [], []>;
def int_x86_sse2_mfence : GCCBuiltin<"__builtin_ia32_mfence">,
Intrinsic<[], [], []>;
+ def int_x86_sse2_pause : GCCBuiltin<"__builtin_ia32_pause">,
+ Intrinsic<[], [], []>;
}
//===----------------------------------------------------------------------===//
@@ -1246,6 +1248,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_ptestnzc_256 : GCCBuiltin<"__builtin_ia32_ptestnzc256">,
Intrinsic<[llvm_i32_ty], [llvm_v4i64_ty,
llvm_v4i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_ptestm_d_512 : GCCBuiltin<"__builtin_ia32_ptestmd512">,
+ Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_ptestm_q_512 : GCCBuiltin<"__builtin_ia32_ptestmq512">,
+ Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
}
// Vector extract sign mask
@@ -1313,6 +1321,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_maskload_ps_256 : GCCBuiltin<"__builtin_ia32_maskloadps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_ptr_ty, llvm_v8f32_ty],
[IntrReadArgMem]>;
+ def int_x86_avx512_mask_loadu_ps_512 : GCCBuiltin<"__builtin_ia32_loadups512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty],
+ [IntrReadArgMem]>;
+ def int_x86_avx512_mask_loadu_pd_512 : GCCBuiltin<"__builtin_ia32_loadupd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
+ [IntrReadArgMem]>;
}
// Conditional store ops
@@ -1331,6 +1345,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_maskstoreps256">,
Intrinsic<[], [llvm_ptr_ty,
llvm_v8f32_ty, llvm_v8f32_ty], [IntrReadWriteArgMem]>;
+ def int_x86_avx512_mask_storeu_ps_512 :
+ GCCBuiltin<"__builtin_ia32_storeups512_mask">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v16f32_ty, llvm_i16_ty],
+ [IntrReadWriteArgMem]>;
+ def int_x86_avx512_mask_storeu_pd_512 :
+ GCCBuiltin<"__builtin_ia32_storeupd512_mask">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v8f64_ty, llvm_i8_ty],
+ [IntrReadWriteArgMem]>;
}
//===----------------------------------------------------------------------===//
@@ -1386,6 +1408,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw256">,
Intrinsic<[llvm_v4i64_ty], [llvm_v32i8_ty,
llvm_v32i8_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx512_mask_pmulu_dq_512 : GCCBuiltin<"__builtin_ia32_pmuludq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmul_dq_512 : GCCBuiltin<"__builtin_ia32_pmuldq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
}
// Vector min, max
@@ -1426,6 +1454,30 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_pmins_d : GCCBuiltin<"__builtin_ia32_pminsd256">,
Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
llvm_v8i32_ty], [IntrNoMem, Commutative]>;
+ def int_x86_avx512_mask_pmaxu_d_512 : GCCBuiltin<"__builtin_ia32_pmaxud512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmaxs_d_512 : GCCBuiltin<"__builtin_ia32_pmaxsd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmaxu_q_512 : GCCBuiltin<"__builtin_ia32_pmaxuq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmaxs_q_512 : GCCBuiltin<"__builtin_ia32_pmaxsq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pminu_d_512 : GCCBuiltin<"__builtin_ia32_pminud512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmins_d_512 : GCCBuiltin<"__builtin_ia32_pminsd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pminu_q_512 : GCCBuiltin<"__builtin_ia32_pminuq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pmins_q_512 : GCCBuiltin<"__builtin_ia32_pminsq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
}
// Integer shift ops.
@@ -1518,6 +1570,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
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]>;
+ def int_x86_avx512_mask_pabs_d_512 : GCCBuiltin<"__builtin_ia32_pabsd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pabs_q_512 : GCCBuiltin<"__builtin_ia32_pabsq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
}
// Horizontal arithmetic ops
@@ -1658,6 +1716,18 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_pbroadcastq_256 :
GCCBuiltin<"__builtin_ia32_pbroadcastq256">,
Intrinsic<[llvm_v4i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pbroadcast_d_gpr_512 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastd512_gpr_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_i32_ty, llvm_v16i32_ty,
+ llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pbroadcast_q_gpr_512 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastq512_gpr_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_i64_ty, llvm_v8i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_pbroadcast_q_mem_512 :
+ GCCBuiltin<"__builtin_ia32_pbroadcastq512_mem_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_i64_ty, llvm_v8i64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
}
// Vector permutation
@@ -1697,6 +1767,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_maskload_q_256 : GCCBuiltin<"__builtin_ia32_maskloadq256">,
Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty, llvm_v4i64_ty],
[IntrReadArgMem]>;
+ def int_x86_avx512_mask_loadu_d_512 : GCCBuiltin<"__builtin_ia32_loaddqusi512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty],
+ [IntrReadArgMem]>;
+ def int_x86_avx512_mask_loadu_q_512 : GCCBuiltin<"__builtin_ia32_loaddqudi512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty],
+ [IntrReadArgMem]>;
}
// Conditional store ops
@@ -1715,6 +1791,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_maskstoreq256">,
Intrinsic<[], [llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty],
[IntrReadWriteArgMem]>;
+ def int_x86_avx512_mask_storeu_d_512 :
+ GCCBuiltin<"__builtin_ia32_storedqusi512_mask">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v16i32_ty, llvm_i16_ty],
+ [IntrReadWriteArgMem]>;
+ def int_x86_avx512_mask_storeu_q_512 :
+ GCCBuiltin<"__builtin_ia32_storedqudi512_mask">,
+ Intrinsic<[], [llvm_ptr_ty, llvm_v8i64_ty, llvm_i8_ty],
+ [IntrReadWriteArgMem]>;
}
// Variable bit shift ops
@@ -1758,68 +1842,68 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">,
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">,
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
}
// Misc.
@@ -2592,6 +2676,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty],
[IntrNoMem]>;
+ def int_x86_avx512_mask_vcvtph2ps_512 : GCCBuiltin<"__builtin_ia32_vcvtph2ps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16i16_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_vcvtps2ph_512 : GCCBuiltin<"__builtin_ia32_vcvtps2ph512_mask">,
+ Intrinsic<[llvm_v16i16_ty], [llvm_v16f32_ty, llvm_i32_ty,
+ llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
@@ -2641,37 +2731,30 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Mask instructions
// 16-bit mask
- def int_x86_kadd_v16i1 : GCCBuiltin<"__builtin_ia32_kaddw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
- [IntrNoMem]>;
- def int_x86_kand_v16i1 : GCCBuiltin<"__builtin_ia32_kandw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ def int_x86_avx512_kand_w : GCCBuiltin<"__builtin_ia32_kandhi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_kandn_v16i1 : GCCBuiltin<"__builtin_ia32_kandnw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ def int_x86_avx512_kandn_w : GCCBuiltin<"__builtin_ia32_kandnhi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_knot_v16i1 : GCCBuiltin<"__builtin_ia32_knotw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty], [IntrNoMem]>;
- def int_x86_kor_v16i1 : GCCBuiltin<"__builtin_ia32_korw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ def int_x86_avx512_knot_w : GCCBuiltin<"__builtin_ia32_knothi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_kor_w : GCCBuiltin<"__builtin_ia32_korhi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_kxor_v16i1 : GCCBuiltin<"__builtin_ia32_kxorw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ def int_x86_avx512_kxor_w : GCCBuiltin<"__builtin_ia32_kxorhi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_kxnor_v16i1 : GCCBuiltin<"__builtin_ia32_kxnorw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v16i1_ty, llvm_v16i1_ty],
+ def int_x86_avx512_kxnor_w : GCCBuiltin<"__builtin_ia32_kxnorhi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_mask2int_v16i1 : GCCBuiltin<"__builtin_ia32_mask2intw">,
- Intrinsic<[llvm_i32_ty], [llvm_v16i1_ty], [IntrNoMem]>;
- def int_x86_int2mask_v16i1 : GCCBuiltin<"__builtin_ia32_int2maskw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_i32_ty], [IntrNoMem]>;
- def int_x86_kunpck_v16i1 : GCCBuiltin<"__builtin_ia32_kunpckbw">,
- Intrinsic<[llvm_v16i1_ty], [llvm_v8i1_ty, llvm_v8i1_ty],
+ def int_x86_avx512_kunpck_bw : GCCBuiltin<"__builtin_ia32_kunpckhi">,
+ Intrinsic<[llvm_i16_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_avx512_kortestz : GCCBuiltin<"__builtin_ia32_kortestz">,
+ def int_x86_avx512_kortestz_w : GCCBuiltin<"__builtin_ia32_kortestzhi">,
Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_avx512_kortestc : GCCBuiltin<"__builtin_ia32_kortestc">,
+ def int_x86_avx512_kortestc_w : GCCBuiltin<"__builtin_ia32_kortestchi">,
Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
[IntrNoMem]>;
}
@@ -2707,20 +2790,55 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_cvtusi642sd : GCCBuiltin<"__builtin_ia32_cvtusi642sd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
llvm_i64_ty], [IntrNoMem]>;
-
- def int_x86_avx512_vcvtph2ps_512 : GCCBuiltin<"__builtin_ia32_vcvtph2ps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16i16_ty], [IntrNoMem]>;
- def int_x86_avx512_vcvtps2ph_512 : GCCBuiltin<"__builtin_ia32_vcvtps2ph512">,
- Intrinsic<[llvm_v16i16_ty], [llvm_v16f32_ty, llvm_i32_ty],
- [IntrNoMem]>;
}
// Vector convert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx512_cvt_ps2dq_512 : GCCBuiltin<"__builtin_ia32_cvtps2dq512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty], [IntrNoMem]>;
- def int_x86_avx512_cvtdq2_ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvttps2dq_512: GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvttps2udq_512: GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvttpd2dq_512: GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvttpd2udq_512: GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_rndscale_ps_512: GCCBuiltin<"__builtin_ia32_rndscaleps_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_rndscale_pd_512: GCCBuiltin<"__builtin_ia32_rndscalepd_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtps2dq_512: GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtpd2dq_512: GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtps2udq_512: GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16f32_ty, llvm_v16i32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtpd2udq_512: GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">,
+ Intrinsic<[llvm_v8i32_ty], [llvm_v8f64_ty, llvm_v8i32_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtdq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtdq2ps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtdq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtdq2pd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtudq2ps_512 : GCCBuiltin<"__builtin_ia32_cvtudq2ps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtudq2pd_512 : GCCBuiltin<"__builtin_ia32_cvtudq2pd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_v8f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cvtpd2ps_512 : GCCBuiltin<"__builtin_ia32_cvtpd2ps512_mask">,
+ Intrinsic<[llvm_v8f32_ty], [llvm_v8f64_ty, llvm_v8f32_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
}
// Vector load with broadcast
@@ -2773,44 +2891,18 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Arithmetic ops
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx512_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty,
- llvm_v16f32_ty], [IntrNoMem]>;
- def int_x86_avx512_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty,
- llvm_v8f64_ty], [IntrNoMem]>;
- def int_x86_avx512_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty,
- llvm_v16f32_ty], [IntrNoMem]>;
- def int_x86_avx512_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty,
- llvm_v8f64_ty], [IntrNoMem]>;
-
- def int_x86_avx512_pmaxu_d : GCCBuiltin<"__builtin_ia32_pmaxud512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
- llvm_v16i32_ty], [IntrNoMem]>;
- def int_x86_avx512_pmaxu_q : GCCBuiltin<"__builtin_ia32_pmaxuq512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_v8i64_ty], [IntrNoMem]>;
- def int_x86_avx512_pmaxs_d : GCCBuiltin<"__builtin_ia32_pmaxsd512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
- llvm_v16i32_ty], [IntrNoMem]>;
- def int_x86_avx512_pmaxs_q : GCCBuiltin<"__builtin_ia32_pmaxsq512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_v8i64_ty], [IntrNoMem]>;
-
- def int_x86_avx512_pminu_d : GCCBuiltin<"__builtin_ia32_pminud512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
- llvm_v16i32_ty], [IntrNoMem]>;
- def int_x86_avx512_pminu_q : GCCBuiltin<"__builtin_ia32_pminuq512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_v8i64_ty], [IntrNoMem]>;
- def int_x86_avx512_pmins_d : GCCBuiltin<"__builtin_ia32_pminsd512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
- llvm_v16i32_ty], [IntrNoMem]>;
- def int_x86_avx512_pmins_q : GCCBuiltin<"__builtin_ia32_pminsq512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_v8i64_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
def int_x86_avx512_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
@@ -2825,66 +2917,67 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
- def int_x86_avx512_rndscale_ps_512 : GCCBuiltin<"__builtin_ia32_rndscaleps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem]>;
- def int_x86_avx512_rndscale_pd_512 : GCCBuiltin<"__builtin_ia32_rndscalepd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem]>;
-
def int_x86_avx512_sqrt_pd_512 : GCCBuiltin<"__builtin_ia32_sqrtpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty], [IntrNoMem]>;
def int_x86_avx512_sqrt_ps_512 : GCCBuiltin<"__builtin_ia32_sqrtps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty], [IntrNoMem]>;
- def int_x86_avx512_rcp14_ps_512 : GCCBuiltin<"__builtin_ia32_rcp14ps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rcp14_pd_512 : GCCBuiltin<"__builtin_ia32_rcp14pd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rcp14_ss : GCCBuiltin<"__builtin_ia32_rcp14ss">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rcp14_sd : GCCBuiltin<"__builtin_ia32_rcp14sd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rsqrt14_ps_512 : GCCBuiltin<"__builtin_ia32_rsqrt14ps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rsqrt14_pd_512 : GCCBuiltin<"__builtin_ia32_rsqrt14pd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rsqrt14_sd : GCCBuiltin<"__builtin_ia32_rsqrt14sd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
- [IntrNoMem]>;
-
- def int_x86_avx512_rcp28_ps_512 : GCCBuiltin<"__builtin_ia32_rcp28ps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rcp28_pd_512 : GCCBuiltin<"__builtin_ia32_rcp28pd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty],
- [IntrNoMem]>;
- def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_rsqrt14_sd : GCCBuiltin<"__builtin_ia32_rsqrt14sd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_rsqrt14_pd_512 : GCCBuiltin<"__builtin_ia32_rsqrt14pd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_rsqrt14_ps_512 : GCCBuiltin<"__builtin_ia32_rsqrt14ps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_i16_ty], [IntrNoMem]>;
+ def int_x86_avx512_rcp14_ss : GCCBuiltin<"__builtin_ia32_rcp14ss_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_rcp14_sd : GCCBuiltin<"__builtin_ia32_rcp14sd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_rcp14_pd_512 : GCCBuiltin<"__builtin_ia32_rcp14pd512_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_avx512_rcp14_ps_512 : GCCBuiltin<"__builtin_ia32_rcp14ps512_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_i16_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_rcp28_ps : GCCBuiltin<"__builtin_ia32_rcp28ps_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_rcp28_pd : GCCBuiltin<"__builtin_ia32_rcp28pd_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
[IntrNoMem]>;
- def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
+ def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
[IntrNoMem]>;
- def int_x86_avx512_rsqrt28_ps_512 : GCCBuiltin<"__builtin_ia32_rsqrt28ps512">,
- Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty],
+ def int_x86_avx512_rsqrt28_ps : GCCBuiltin<"__builtin_ia32_rsqrt28ps_mask">,
+ Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
+ llvm_i16_ty, llvm_i32_ty],
[IntrNoMem]>;
- def int_x86_avx512_rsqrt28_pd_512 : GCCBuiltin<"__builtin_ia32_rsqrt28pd512">,
- Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty],
+ def int_x86_avx512_rsqrt28_pd : GCCBuiltin<"__builtin_ia32_rsqrt28pd_mask">,
+ Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
+ llvm_i8_ty, llvm_i32_ty],
[IntrNoMem]>;
- def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty],
+ def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss_mask">,
+ Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
[IntrNoMem]>;
- def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty],
+ def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd_mask">,
+ Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
[IntrNoMem]>;
}
@@ -2909,28 +3002,28 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_gather_dpd_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i8_ty,
llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_dps_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i16_ty,
llvm_v16i32_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_qpd_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherqpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i8_ty,
llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_qps_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherqps512">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i8_ty,
llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_dpd_512 : GCCBuiltin<"__builtin_ia32_gatherdpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_ptr_ty,
llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_dps_512 : GCCBuiltin<"__builtin_ia32_gatherdps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_ptr_ty,
llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherqpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
llvm_i32_ty],
@@ -2938,12 +3031,12 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_gather_qps_512 : GCCBuiltin<"__builtin_ia32_gatherqps512">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8i64_ty, llvm_ptr_ty,
llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_dpq_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdpq512">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_i8_ty,
llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_dpi_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdpi512">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_i16_ty,
llvm_v16i32_ty, llvm_ptr_ty, llvm_i32_ty],
@@ -2955,7 +3048,7 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_gather_qpi_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherqpi512">,
Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i8_ty,
llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem]>;
+ [IntrReadArgMem]>;
def int_x86_avx512_gather_dpq_512 : GCCBuiltin<"__builtin_ia32_gatherdpq512">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i32_ty, llvm_ptr_ty,
@@ -3045,62 +3138,62 @@ let TargetPrefix = "x86" in {
// AVX-512 conflict detection
let TargetPrefix = "x86" in {
- def int_x86_avx512_conflict_d_512 : GCCBuiltin<"__builtin_ia32_conflictd512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty],
- []>;
- def int_x86_avx512_conflict_d_mask_512 :
- GCCBuiltin<"__builtin_ia32_mask_conflictd512">,
+ def int_x86_avx512_mask_conflict_d_512 :
+ GCCBuiltin<"__builtin_ia32_vpconflictsi_512_mask">,
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty,
- llvm_v16i1_ty, llvm_v16i32_ty],
- []>;
- def int_x86_avx512_conflict_d_maskz_512:
- GCCBuiltin<"__builtin_ia32_maskz_conflictd512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i1_ty, llvm_v16i32_ty],
+ llvm_v16i32_ty, llvm_i16_ty],
[]>;
-
- def int_x86_avx512_conflict_q_512 : GCCBuiltin<"__builtin_ia32_conflictq512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty],
- []>;
- def int_x86_avx512_conflict_q_mask_512 :
- GCCBuiltin<"__builtin_ia32_mask_conflictq512">,
+ def int_x86_avx512_mask_conflict_q_512 :
+ GCCBuiltin<"__builtin_ia32_vpconflictdi_512_mask">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty,
- llvm_v8i1_ty, llvm_v8i64_ty],
- []>;
- def int_x86_avx512_conflict_q_maskz_512:
- GCCBuiltin<"__builtin_ia32_maskz_conflictq512">,
- Intrinsic<[llvm_v8i64_ty], [llvm_v8i1_ty, llvm_v8i64_ty],
+ llvm_v8i64_ty, llvm_i8_ty],
[]>;
}
// Vector blend
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx512_mskblend_ps_512 : GCCBuiltin<"__builtin_ia32_mskblendps512">,
+ def int_x86_avx512_mask_blend_ps_512 : GCCBuiltin<"__builtin_ia32_blendmps_512_mask">,
Intrinsic<[llvm_v16f32_ty],
- [llvm_v16i1_ty, llvm_v16f32_ty, llvm_v16f32_ty],
+ [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_avx512_mskblend_pd_512 : GCCBuiltin<"__builtin_ia32_mskblendpd512">,
+ def int_x86_avx512_mask_blend_pd_512 : GCCBuiltin<"__builtin_ia32_blendmpd_512_mask">,
Intrinsic<[llvm_v8f64_ty],
- [llvm_v8i1_ty, llvm_v8f64_ty, llvm_v8f64_ty],
+ [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i8_ty],
[IntrNoMem]>;
- def int_x86_avx512_mskblend_d_512 : GCCBuiltin<"__builtin_ia32_mskblendd512">,
+ def int_x86_avx512_mask_blend_d_512 : GCCBuiltin<"__builtin_ia32_blendmd_512_mask">,
Intrinsic<[llvm_v16i32_ty],
- [llvm_v16i1_ty, llvm_v16i32_ty, llvm_v16i32_ty],
+ [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty],
[IntrNoMem]>;
- def int_x86_avx512_mskblend_q_512 : GCCBuiltin<"__builtin_ia32_mskblendq512">,
+ def int_x86_avx512_mask_blend_q_512 : GCCBuiltin<"__builtin_ia32_blendmq_512_mask">,
Intrinsic<[llvm_v8i64_ty],
- [llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8i64_ty],
+ [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
[IntrNoMem]>;
}
// Misc.
let TargetPrefix = "x86" in {
- def int_x86_avx512_cmpeq_pi_512 : GCCBuiltin<"__builtin_ia32_cmpeqpi512">,
- Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty],
+ def int_x86_avx512_mask_cmp_ps_512 : GCCBuiltin<"__builtin_ia32_cmpps512_mask">,
+ Intrinsic<[llvm_i16_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty,
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_avx512_mask_cmp_pd_512 : GCCBuiltin<"__builtin_ia32_cmppd512_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty,
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem]>;
+
+ def int_x86_avx512_mask_pcmpeq_d_512 : GCCBuiltin<"__builtin_ia32_pcmpeqd512_mask">,
+ Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_mask_pcmpeq_q_512 : GCCBuiltin<"__builtin_ia32_pcmpeqq512_mask">,
+ Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_d_512 : GCCBuiltin<"__builtin_ia32_pandd512_mask">,
+ Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty,
+ llvm_v16i32_ty, llvm_i16_ty],
+ [IntrNoMem]>;
+ def int_x86_avx512_mask_pand_q_512 : GCCBuiltin<"__builtin_ia32_pandq512_mask">,
+ Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
+ llvm_v8i64_ty, llvm_i8_ty],
[IntrNoMem]>;
- def int_x86_avx512_and_pi : GCCBuiltin<"__builtin_ia32_andpi512">,
- Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_v16i32_ty],
- [IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/IR/IntrinsicsXCore.td b/include/llvm/IR/IntrinsicsXCore.td
index bf345d4..b614e1e 100644
--- a/include/llvm/IR/IntrinsicsXCore.td
+++ b/include/llvm/IR/IntrinsicsXCore.td
@@ -67,6 +67,8 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
[NoCapture<0>]>;
def int_xcore_setpt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
[NoCapture<0>]>;
+ def int_xcore_clrpt : Intrinsic<[],[llvm_anyptr_ty],
+ [NoCapture<0>]>;
def int_xcore_getts : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
[NoCapture<0>]>;
def int_xcore_syncr : Intrinsic<[],[llvm_anyptr_ty],
@@ -78,6 +80,7 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
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_edu : 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],
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index dd379ae..ae4859a 100644
--- a/include/llvm/IR/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -15,9 +15,9 @@
#ifndef LLVM_IR_LLVMCONTEXT_H
#define LLVM_IR_LLVMCONTEXT_H
+#include "llvm-c/Core.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
-#include "llvm-c/Core.h"
namespace llvm {
@@ -27,6 +27,7 @@ class Twine;
class Instruction;
class Module;
class SMDiagnostic;
+class DiagnosticInfo;
template <typename T> class SmallVectorImpl;
/// This is an important class for using LLVM in a threaded context. It
@@ -64,6 +65,11 @@ public:
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
unsigned LocCookie);
+ /// Defines the type of a diagnostic handler.
+ /// \see LLVMContext::setDiagnosticHandler.
+ /// \see LLVMContext::diagnose.
+ typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);
+
/// 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
@@ -82,6 +88,33 @@ public:
/// setInlineAsmDiagnosticHandler.
void *getInlineAsmDiagnosticContext() const;
+ /// setDiagnosticHandler - This method sets a handler that is invoked
+ /// when the backend needs to report anything to the user. 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 setDiagnosticHandler(DiagnosticHandlerTy DiagHandler,
+ void *DiagContext = 0);
+
+ /// getDiagnosticHandler - Return the diagnostic handler set by
+ /// setDiagnosticHandler.
+ DiagnosticHandlerTy getDiagnosticHandler() const;
+
+ /// getDiagnosticContext - Return the diagnostic context set by
+ /// setDiagnosticContext.
+ void *getDiagnosticContext() const;
+
+ /// diagnose - Report a message to the currently installed diagnostic handler.
+ /// This function returns, in particular in the case of error reporting
+ /// (DI.Severity == RS_Error), so the caller should leave the compilation
+ /// process in a self-consistent state, even though the generated code
+ /// need not be correct.
+ /// The diagnostic message will be implicitly prefixed with a severity
+ /// keyword according to \p DI.getSeverity(), i.e., "error: "
+ /// for RS_Error, "warning: " for RS_Warning, and "note: " for RS_Note.
+ void diagnose(const DiagnosticInfo &DI);
/// emitError - Emit an error message to the currently installed error handler
/// with optional location information. This function returns, so code should
diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/IR/LeakDetector.h
index 501a9db..cb18df8 100644
--- a/include/llvm/Support/LeakDetector.h
+++ b/include/llvm/IR/LeakDetector.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===//
+//===- LeakDetector.h - Provide leak detection ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,8 +19,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
-#define LLVM_SUPPORT_LEAKDETECTOR_H
+#ifndef LLVM_IR_LEAKDETECTOR_H
+#define LLVM_IR_LEAKDETECTOR_H
#include <string>
diff --git a/include/llvm/IR/LegacyPassManager.h b/include/llvm/IR/LegacyPassManager.h
index fa1436e..c967a6b 100644
--- a/include/llvm/IR/LegacyPassManager.h
+++ b/include/llvm/IR/LegacyPassManager.h
@@ -55,7 +55,7 @@ public:
/// 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);
+ void add(Pass *P) override;
/// 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.
@@ -80,7 +80,7 @@ public:
/// 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);
+ void add(Pass *P) override;
/// run - Execute all of the passes scheduled for execution. Keep
/// track of whether any of the passes modifies the function, and if
diff --git a/include/llvm/IR/LegacyPassManagers.h b/include/llvm/IR/LegacyPassManagers.h
index d256a3e..5c9dccd 100644
--- a/include/llvm/IR/LegacyPassManagers.h
+++ b/include/llvm/IR/LegacyPassManagers.h
@@ -101,15 +101,15 @@ namespace llvm {
// 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"
+ EXECUTION_MSG, // "Executing Pass '" + PassName
+ MODIFICATION_MSG, // "Made Modification '" + PassName
+ FREEING_MSG, // " Freeing Pass '" + PassName
+ ON_BASICBLOCK_MSG, // "' on BasicBlock '" + InstructionName + "'...\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'"
+ ON_REGION_MSG, // "' on Region '" + Msg + "'...\n'"
+ ON_LOOP_MSG, // "' on Loop '" + Msg + "'...\n'"
+ ON_CG_MSG // "' on Call Graph Nodes '" + Msg + "'...\n'"
};
/// PassManagerPrettyStackEntry - This is used to print informative information
@@ -127,7 +127,7 @@ public:
: 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;
+ void print(raw_ostream &OS) const override;
};
@@ -414,7 +414,7 @@ public:
/// 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);
+ bool runOnModule(Module &M) override;
/// cleanup - After running all passes, clean up pass manager cache.
void cleanup();
@@ -426,7 +426,7 @@ public:
/// doInitialization - Run all of the initializers for the function passes.
///
- bool doInitialization(Module &M);
+ bool doInitialization(Module &M) override;
/// doFinalization - Overrides ModulePass doFinalization for global
/// finalization tasks
@@ -435,20 +435,20 @@ public:
/// doFinalization - Run all of the finalizers for the function passes.
///
- bool doFinalization(Module &M);
+ bool doFinalization(Module &M) override;
- virtual PMDataManager *getAsPMDataManager() { return this; }
- virtual Pass *getAsPass() { return this; }
+ PMDataManager *getAsPMDataManager() override { return this; }
+ Pass *getAsPass() override { return this; }
/// Pass Manager itself does not invalidate any analysis info.
- void getAnalysisUsage(AnalysisUsage &Info) const {
+ void getAnalysisUsage(AnalysisUsage &Info) const override{
Info.setPreservesAll();
}
// Print passes managed by this manager
- void dumpPassStructure(unsigned Offset);
+ void dumpPassStructure(unsigned Offset) override;
- virtual const char *getPassName() const {
+ const char *getPassName() const override {
return "Function Pass Manager";
}
@@ -458,7 +458,7 @@ public:
return FP;
}
- virtual PassManagerType getPassManagerType() const {
+ PassManagerType getPassManagerType() const override {
return PMT_FunctionPassManager;
}
};
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/IR/LegacyPassNameParser.h
index c0914b1..1f6bbbc 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/IR/LegacyPassNameParser.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
+//===- LegacyPassNameParser.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -18,10 +18,13 @@
// includes passes that have a PassType that are compatible with the filter
// (which is the template argument).
//
+// Note that this is part of the legacy pass manager infrastructure and will be
+// (eventually) going away.
+//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H
-#define LLVM_SUPPORT_PASSNAMEPARSER_H
+#ifndef LLVM_IR_LEGACYPASSNAMEPARSER_H
+#define LLVM_IR_LEGACYPASSNAMEPARSER_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/Pass.h"
@@ -65,7 +68,7 @@ public:
// Implement the PassRegistrationListener callbacks used to populate our map
//
- virtual void passRegistered(const PassInfo *P) {
+ void passRegistered(const PassInfo *P) override {
if (ignorablePass(P) || !Opt) return;
if (findOption(P->getPassArgument()) != getNumOptions()) {
errs() << "Two passes with the same argument (-"
@@ -74,11 +77,11 @@ public:
}
addLiteralOption(P->getPassArgument(), P, P->getPassName());
}
- virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
+ void passEnumerate(const PassInfo *P) override { 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 {
+ void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const override {
PassNameParser *PNP = const_cast<PassNameParser*>(this);
array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
@@ -104,7 +107,9 @@ private:
Filter filter;
public:
- bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); }
+ bool ignorablePassImpl(const PassInfo *P) const override {
+ return !filter(*P);
+ }
};
///===----------------------------------------------------------------------===//
diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h
index ce81b54..c07b2bd 100644
--- a/include/llvm/IR/MDBuilder.h
+++ b/include/llvm/IR/MDBuilder.h
@@ -174,11 +174,8 @@ public:
/// given name, an offset and a parent in the TBAA type DAG.
MDNode *createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
uint64_t Offset = 0) {
- SmallVector<Value *, 4> Ops(3);
- Type *Int64 = IntegerType::get(Context, 64);
- Ops[0] = createString(Name);
- Ops[1] = Parent;
- Ops[2] = ConstantInt::get(Int64, Offset);
+ ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset);
+ Value *Ops[3] = { createString(Name), Parent, Off };
return MDNode::get(Context, Ops);
}
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/IR/Mangler.h
index eee7bf6..c1ba585 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/IR/Mangler.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/Mangler.h - Self-contained name mangler -----*- C++ -*-===//
+//===-- llvm/IR/Mangler.h - Self-contained name mangler ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,13 +15,13 @@
#define LLVM_TARGET_MANGLER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
+class DataLayout;
class GlobalValue;
-class MCContext;
template <typename T> class SmallVectorImpl;
-class TargetMachine;
class Twine;
class Mangler {
@@ -33,33 +33,35 @@ public:
};
private:
- const TargetMachine *TM;
+ const DataLayout *DL;
/// 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;
+ mutable DenseMap<const GlobalValue*, unsigned> AnonGlobalIDs;
/// NextAnonGlobalID - This simple counter is used to unique value names.
///
- unsigned NextAnonGlobalID;
+ mutable unsigned NextAnonGlobalID;
public:
- Mangler(const TargetMachine *TM) : TM(TM), NextAnonGlobalID(1) {}
+ Mangler(const DataLayout *DL) : DL(DL), NextAnonGlobalID(1) {}
- /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
- /// and the specified global variable's name. If the global variable doesn't
- /// have a name, this fills in a unique name for the global.
+ /// Print 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(raw_ostream &OS, const GlobalValue *GV,
+ bool CannotUsePrivateLabel) const;
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
- bool isImplicitlyPrivate, bool UseGlobalPrefix = true);
+ bool CannotUsePrivateLabel) const;
- /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
- /// and the specified name as the global variable name. GVName must not be
- /// empty.
+ /// Print the appropriate prefix and the specified name as the global variable
+ /// name. GVName must not be empty.
+ void getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
+ ManglerPrefixTy PrefixTy = Mangler::Default) const;
void getNameWithPrefix(SmallVectorImpl<char> &OutName, const Twine &GVName,
- ManglerPrefixTy PrefixTy = Mangler::Default,
- bool UseGlobalPrefix = true);
+ ManglerPrefixTy PrefixTy = Mangler::Default) const;
};
} // End llvm namespace
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index 9659c2e..d054fbb 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Value.h"
namespace llvm {
@@ -28,7 +29,7 @@ template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
+enum LLVMConstants : uint32_t {
DEBUG_METADATA_VERSION = 1 // Current debug info version number.
};
@@ -207,6 +208,42 @@ class NamedMDNode : public ilist_node<NamedMDNode> {
explicit NamedMDNode(const Twine &N);
+ template<class T1, class T2>
+ class op_iterator_impl :
+ public std::iterator<std::bidirectional_iterator_tag, T2> {
+ const NamedMDNode *Node;
+ unsigned Idx;
+ op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) { }
+
+ friend class NamedMDNode;
+
+ public:
+ op_iterator_impl() : Node(0), Idx(0) { }
+
+ bool operator==(const op_iterator_impl &o) const { return Idx == o.Idx; }
+ bool operator!=(const op_iterator_impl &o) const { return Idx != o.Idx; }
+ op_iterator_impl &operator++() {
+ ++Idx;
+ return *this;
+ }
+ op_iterator_impl operator++(int) {
+ op_iterator_impl tmp(*this);
+ operator++();
+ return tmp;
+ }
+ op_iterator_impl &operator--() {
+ --Idx;
+ return *this;
+ }
+ op_iterator_impl operator--(int) {
+ op_iterator_impl tmp(*this);
+ operator--();
+ return tmp;
+ }
+
+ T1 operator*() const { return Node->getOperand(Idx); }
+ };
+
public:
/// eraseFromParent - Drop all references and remove the node from parent
/// module.
@@ -239,6 +276,24 @@ public:
/// dump() - Allow printing of NamedMDNodes from the debugger.
void dump() const;
+
+ // ---------------------------------------------------------------------------
+ // Operand Iterator interface...
+ //
+ typedef op_iterator_impl<MDNode*, MDNode> op_iterator;
+ op_iterator op_begin() { return op_iterator(this, 0); }
+ op_iterator op_end() { return op_iterator(this, getNumOperands()); }
+
+ typedef op_iterator_impl<const MDNode*, MDNode> const_op_iterator;
+ const_op_iterator op_begin() const { return const_op_iterator(this, 0); }
+ const_op_iterator op_end() const { return const_op_iterator(this, getNumOperands()); }
+
+ inline iterator_range<op_iterator> operands() {
+ return iterator_range<op_iterator>(op_begin(), op_end());
+ }
+ inline iterator_range<const_op_iterator> operands() const {
+ return iterator_range<const_op_iterator>(op_begin(), op_end());
+ }
};
} // end llvm namespace
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index b30a9a3..f0d4002 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -15,13 +15,15 @@
#ifndef LLVM_IR_MODULE_H
#define LLVM_IR_MODULE_H
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/system_error.h"
namespace llvm {
@@ -142,12 +144,6 @@ public:
/// The named metadata constant interators.
typedef NamedMDListType::const_iterator const_named_metadata_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 };
-
/// This enumeration defines the supported behaviors of module flags.
enum ModFlagBehavior {
/// Emits an error if two values disagree, otherwise the resulting value is
@@ -156,7 +152,7 @@ public:
/// Emits a warning if two values disagree. The result value will be the
/// operand for the flag from the first module being linked.
- Warning = 2,
+ Warning = 2,
/// Adds a requirement that another module flag be present and have a
/// specified value after linking is performed. The value must be a metadata
@@ -201,12 +197,20 @@ private:
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::unique_ptr<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.
+ // We need to keep the string because the C API expects us to own the string
+ // representation.
+ // Since we have it, we also use an empty string to represent a module without
+ // a DataLayout. If it has a DataLayout, these variables are in sync and the
+ // string is just a cache of getDataLayout()->getStringRepresentation().
+ std::string DataLayoutStr;
+ DataLayout DL;
+
friend class Constant;
/// @}
@@ -227,23 +231,17 @@ public:
/// @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 data layout string for the module's target platform. This is
+ /// equivalent to getDataLayout()->getStringRepresentation().
+ const std::string &getDataLayoutStr() const { return DataLayoutStr; }
+
+ /// Get the data layout for the module's target platform.
+ const DataLayout *getDataLayout() const;
/// 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; }
@@ -260,7 +258,8 @@ public:
void setModuleIdentifier(StringRef ID) { ModuleID = ID; }
/// Set the data layout
- void setDataLayout(StringRef DL) { DataLayout = DL; }
+ void setDataLayout(StringRef Desc);
+ void setDataLayout(const DataLayout *Other);
/// Set the target triple.
void setTargetTriple(StringRef T) { TargetTriple = T; }
@@ -464,18 +463,13 @@ public:
/// 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);
+ /// Make sure all GlobalValues in this Module are fully read.
+ error_code materializeAll();
- /// 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);
+ /// Make sure all GlobalValues in this Module are fully read and clear the
+ /// Materializer. If the module is corrupt, this DOES NOT clear the old
+ /// Materializer.
+ error_code materializeAllPermanently();
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
@@ -524,6 +518,13 @@ public:
const_global_iterator global_end () const { return GlobalList.end(); }
bool global_empty() const { return GlobalList.empty(); }
+ iterator_range<global_iterator> globals() {
+ return iterator_range<global_iterator>(global_begin(), global_end());
+ }
+ iterator_range<const_global_iterator> globals() const {
+ return iterator_range<const_global_iterator>(global_begin(), global_end());
+ }
+
/// @}
/// @name Function Iteration
/// @{
@@ -546,6 +547,12 @@ public:
size_t alias_size () const { return AliasList.size(); }
bool alias_empty() const { return AliasList.empty(); }
+ iterator_range<alias_iterator> aliases() {
+ return iterator_range<alias_iterator>(alias_begin(), alias_end());
+ }
+ iterator_range<const_alias_iterator> aliases() const {
+ return iterator_range<const_alias_iterator>(alias_begin(), alias_end());
+ }
/// @}
/// @name Named Metadata Iteration
@@ -564,6 +571,14 @@ public:
size_t named_metadata_size() const { return NamedMDList.size(); }
bool named_metadata_empty() const { return NamedMDList.empty(); }
+ iterator_range<named_metadata_iterator> named_metadata() {
+ return iterator_range<named_metadata_iterator>(named_metadata_begin(),
+ named_metadata_end());
+ }
+ iterator_range<const_named_metadata_iterator> named_metadata() const {
+ return iterator_range<const_named_metadata_iterator>(named_metadata_begin(),
+ named_metadata_end());
+ }
/// @}
/// @name Utility functions for printing and dumping Module objects
diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/IR/NoFolder.h
index ecfbbaa..a9cdfc3 100644
--- a/include/llvm/Support/NoFolder.h
+++ b/include/llvm/IR/NoFolder.h
@@ -1,4 +1,4 @@
-//======-- llvm/Support/NoFolder.h - Constant folding helper -*- C++ -*-======//
+//===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,8 +19,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_NOFOLDER_H
-#define LLVM_SUPPORT_NOFOLDER_H
+#ifndef LLVM_IR_NOFOLDER_H
+#define LLVM_IR_NOFOLDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/Constants.h"
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 5b9bee7..888cabf 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -18,9 +18,9 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Type.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
namespace llvm {
@@ -210,6 +210,10 @@ public:
setNoSignedZeros();
setAllowReciprocal();
}
+
+ void operator&=(const FastMathFlags &OtherFlags) {
+ Flags &= OtherFlags.Flags;
+ }
};
@@ -473,6 +477,36 @@ public:
};
+class PtrToIntOperator
+ : public ConcreteOperator<Operator, Instruction::PtrToInt> {
+ friend class PtrToInt;
+ friend class ConstantExpr;
+
+public:
+ 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();
+ }
+
+ /// getPointerAddressSpace - Method to return the address space of the
+ /// pointer operand.
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperandType())->getAddressSpace();
+ }
+};
+
+
} // End llvm namespace
#endif
diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h
index 833547a..c6c530c 100644
--- a/include/llvm/IR/PassManager.h
+++ b/include/llvm/IR/PassManager.h
@@ -35,12 +35,17 @@
///
//===----------------------------------------------------------------------===//
+#ifndef LLVM_IR_PASS_MANAGER_H
+#define LLVM_IR_PASS_MANAGER_H
+
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/polymorphic_ptr.h"
-#include "llvm/Support/type_traits.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/type_traits.h"
#include <list>
+#include <memory>
#include <vector>
namespace llvm {
@@ -48,317 +53,747 @@ namespace llvm {
class Module;
class Function;
+/// \brief An abstract set of preserved analyses following a transformation pass
+/// run.
+///
+/// When a transformation pass is run, it can return a set of analyses whose
+/// results were preserved by that transformation. The default set is "none",
+/// and preserving analyses must be done explicitly.
+///
+/// There is also an explicit all state which can be used (for example) when
+/// the IR is not mutated at all.
+class PreservedAnalyses {
+public:
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ PreservedAnalyses() {}
+ PreservedAnalyses(const PreservedAnalyses &Arg)
+ : PreservedPassIDs(Arg.PreservedPassIDs) {}
+ PreservedAnalyses(PreservedAnalyses &&Arg)
+ : PreservedPassIDs(std::move(Arg.PreservedPassIDs)) {}
+ friend void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS) {
+ using std::swap;
+ swap(LHS.PreservedPassIDs, RHS.PreservedPassIDs);
+ }
+ PreservedAnalyses &operator=(PreservedAnalyses RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ /// \brief Convenience factory function for the empty preserved set.
+ static PreservedAnalyses none() { return PreservedAnalyses(); }
+
+ /// \brief Construct a special preserved set that preserves all passes.
+ static PreservedAnalyses all() {
+ PreservedAnalyses PA;
+ PA.PreservedPassIDs.insert((void *)AllPassesID);
+ return PA;
+ }
+
+ /// \brief Mark a particular pass as preserved, adding it to the set.
+ template <typename PassT> void preserve() {
+ if (!areAllPreserved())
+ PreservedPassIDs.insert(PassT::ID());
+ }
+
+ /// \brief Intersect this set with another in place.
+ ///
+ /// This is a mutating operation on this preserved set, removing all
+ /// preserved passes which are not also preserved in the argument.
+ void intersect(const PreservedAnalyses &Arg) {
+ if (Arg.areAllPreserved())
+ return;
+ if (areAllPreserved()) {
+ PreservedPassIDs = Arg.PreservedPassIDs;
+ return;
+ }
+ for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
+ E = PreservedPassIDs.end();
+ I != E; ++I)
+ if (!Arg.PreservedPassIDs.count(*I))
+ PreservedPassIDs.erase(*I);
+ }
+
+ /// \brief Intersect this set with a temporary other set in place.
+ ///
+ /// This is a mutating operation on this preserved set, removing all
+ /// preserved passes which are not also preserved in the argument.
+ void intersect(PreservedAnalyses &&Arg) {
+ if (Arg.areAllPreserved())
+ return;
+ if (areAllPreserved()) {
+ PreservedPassIDs = std::move(Arg.PreservedPassIDs);
+ return;
+ }
+ for (SmallPtrSet<void *, 2>::const_iterator I = PreservedPassIDs.begin(),
+ E = PreservedPassIDs.end();
+ I != E; ++I)
+ if (!Arg.PreservedPassIDs.count(*I))
+ PreservedPassIDs.erase(*I);
+ }
+
+ /// \brief Query whether a pass is marked as preserved by this set.
+ template <typename PassT> bool preserved() const {
+ return preserved(PassT::ID());
+ }
+
+ /// \brief Query whether an abstract pass ID is marked as preserved by this
+ /// set.
+ bool preserved(void *PassID) const {
+ return PreservedPassIDs.count((void *)AllPassesID) ||
+ PreservedPassIDs.count(PassID);
+ }
+
+private:
+ // Note that this must not be -1 or -2 as those are already used by the
+ // SmallPtrSet.
+ static const uintptr_t AllPassesID = (intptr_t)(-3);
+
+ bool areAllPreserved() const {
+ return PreservedPassIDs.count((void *)AllPassesID);
+ }
+
+ SmallPtrSet<void *, 2> PreservedPassIDs;
+};
+
/// \brief Implementation details of the pass manager interfaces.
namespace detail {
/// \brief Template for the abstract base class used to dispatch
/// polymorphically over pass objects.
-template <typename T> struct PassConcept {
+template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept {
// Boiler plate necessary for the container of derived classes.
virtual ~PassConcept() {}
- virtual PassConcept *clone() = 0;
/// \brief The polymorphic API which runs the pass over a given IR entity.
- virtual bool run(T Arg) = 0;
+ ///
+ /// Note that actual pass object can omit the analysis manager argument if
+ /// desired. Also that the analysis manager may be null if there is no
+ /// analysis manager in the pass pipeline.
+ virtual PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) = 0;
+
+ /// \brief Polymorphic method to access the name of a pass.
+ virtual StringRef name() = 0;
+};
+
+/// \brief SFINAE metafunction for computing whether \c PassT has a run method
+/// accepting an \c AnalysisManagerT.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
+ typename ResultT>
+class PassRunAcceptsAnalysisManager {
+ typedef char SmallType;
+ struct BigType {
+ char a, b;
+ };
+
+ template <typename T, ResultT (T::*)(IRUnitT, AnalysisManagerT *)>
+ struct Checker;
+
+ template <typename T> static SmallType f(Checker<T, &T::run> *);
+ template <typename T> static BigType f(...);
+
+public:
+ enum { Value = sizeof(f<PassT>(0)) == sizeof(SmallType) };
};
/// \brief A template wrapper used to implement the polymorphic API.
///
-/// Can be instantiated for any object which provides a \c run method
-/// accepting a \c T. It requires the pass to be a copyable
-/// object.
-template <typename T, typename PassT> struct PassModel : PassConcept<T> {
- PassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
- virtual PassModel *clone() { return new PassModel(Pass); }
- virtual bool run(T Arg) { return Pass.run(Arg); }
+/// Can be instantiated for any object which provides a \c run method accepting
+/// an \c IRUnitT. It requires the pass to be a copyable object. When the
+/// \c run method also accepts an \c AnalysisManagerT*, we pass it along.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
+ bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
+ IRUnitT, AnalysisManagerT, PassT, PreservedAnalyses>::Value>
+struct PassModel;
+
+/// \brief Specialization of \c PassModel for passes that accept an analyis
+/// manager.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct PassModel<IRUnitT, AnalysisManagerT, PassT, true>
+ : PassConcept<IRUnitT, AnalysisManagerT> {
+ explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
+ PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+ friend void swap(PassModel &LHS, PassModel &RHS) {
+ using std::swap;
+ swap(LHS.Pass, RHS.Pass);
+ }
+ PassModel &operator=(PassModel RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
+ return Pass.run(IR, AM);
+ }
+ StringRef name() override { return PassT::name(); }
PassT Pass;
};
-}
+/// \brief Specialization of \c PassModel for passes that accept an analyis
+/// manager.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct PassModel<IRUnitT, AnalysisManagerT, PassT, false>
+ : PassConcept<IRUnitT, AnalysisManagerT> {
+ explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
+ PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+ friend void swap(PassModel &LHS, PassModel &RHS) {
+ using std::swap;
+ swap(LHS.Pass, RHS.Pass);
+ }
+ PassModel &operator=(PassModel RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ PreservedAnalyses run(IRUnitT IR, AnalysisManagerT *AM) override {
+ return Pass.run(IR);
+ }
+ StringRef name() override { return PassT::name(); }
+ PassT Pass;
+};
-class AnalysisManager;
+/// \brief Abstract concept of an analysis result.
+///
+/// This concept is parameterized over the IR unit that this result pertains
+/// to.
+template <typename IRUnitT> struct AnalysisResultConcept {
+ virtual ~AnalysisResultConcept() {}
+
+ /// \brief Method to try and mark a result as invalid.
+ ///
+ /// When the outer analysis manager detects a change in some underlying
+ /// unit of the IR, it will call this method on all of the results cached.
+ ///
+ /// This method also receives a set of preserved analyses which can be used
+ /// to avoid invalidation because the pass which changed the underlying IR
+ /// took care to update or preserve the analysis result in some way.
+ ///
+ /// \returns true if the result is indeed invalid (the default).
+ virtual bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) = 0;
+};
+
+/// \brief SFINAE metafunction for computing whether \c ResultT provides an
+/// \c invalidate member function.
+template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
+ typedef char SmallType;
+ struct BigType {
+ char a, b;
+ };
+
+ template <typename T, bool (T::*)(IRUnitT, const PreservedAnalyses &)>
+ struct Checker;
+
+ template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
+ template <typename T> static BigType f(...);
+
+public:
+ enum { Value = sizeof(f<ResultT>(0)) == sizeof(SmallType) };
+};
+
+/// \brief Wrapper to model the analysis result concept.
+///
+/// By default, this will implement the invalidate method with a trivial
+/// implementation so that the actual analysis result doesn't need to provide
+/// an invalidation handler. It is only selected when the invalidation handler
+/// is not part of the ResultT's interface.
+template <typename IRUnitT, typename PassT, typename ResultT,
+ bool HasInvalidateHandler =
+ ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
+struct AnalysisResultModel;
+
+/// \brief Specialization of \c AnalysisResultModel which provides the default
+/// invalidate functionality.
+template <typename IRUnitT, typename PassT, typename ResultT>
+struct AnalysisResultModel<IRUnitT, PassT, ResultT, false>
+ : AnalysisResultConcept<IRUnitT> {
+ explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
+ AnalysisResultModel(AnalysisResultModel &&Arg)
+ : Result(std::move(Arg.Result)) {}
+ friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
+ using std::swap;
+ swap(LHS.Result, RHS.Result);
+ }
+ AnalysisResultModel &operator=(AnalysisResultModel RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ /// \brief The model bases invalidation solely on being in the preserved set.
+ //
+ // FIXME: We should actually use two different concepts for analysis results
+ // rather than two different models, and avoid the indirect function call for
+ // ones that use the trivial behavior.
+ bool invalidate(IRUnitT, const PreservedAnalyses &PA) override {
+ return !PA.preserved(PassT::ID());
+ }
+
+ ResultT Result;
+};
+
+/// \brief Specialization of \c AnalysisResultModel which delegates invalidate
+/// handling to \c ResultT.
+template <typename IRUnitT, typename PassT, typename ResultT>
+struct AnalysisResultModel<IRUnitT, PassT, ResultT, true>
+ : AnalysisResultConcept<IRUnitT> {
+ explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
+ AnalysisResultModel(AnalysisResultModel &&Arg)
+ : Result(std::move(Arg.Result)) {}
+ friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
+ using std::swap;
+ swap(LHS.Result, RHS.Result);
+ }
+ AnalysisResultModel &operator=(AnalysisResultModel RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ /// \brief The model delegates to the \c ResultT method.
+ bool invalidate(IRUnitT IR, const PreservedAnalyses &PA) override {
+ return Result.invalidate(IR, PA);
+ }
+
+ ResultT Result;
+};
+
+/// \brief Abstract concept of an analysis pass.
+///
+/// This concept is parameterized over the IR unit that it can run over and
+/// produce an analysis result.
+template <typename IRUnitT, typename AnalysisManagerT>
+struct AnalysisPassConcept {
+ virtual ~AnalysisPassConcept() {}
+
+ /// \brief Method to run this analysis over a unit of IR.
+ /// \returns A unique_ptr to the analysis result object to be queried by
+ /// users.
+ virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+ run(IRUnitT IR, AnalysisManagerT *AM) = 0;
+};
+
+/// \brief Wrapper to model the analysis pass concept.
+///
+/// Can wrap any type which implements a suitable \c run method. The method
+/// must accept the IRUnitT as an argument and produce an object which can be
+/// wrapped in a \c AnalysisResultModel.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT,
+ bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
+ IRUnitT, AnalysisManagerT, PassT, typename PassT::Result>::Value>
+struct AnalysisPassModel;
+
+/// \brief Specialization of \c AnalysisPassModel which passes an
+/// \c AnalysisManager to PassT's run method.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, true>
+ : AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
+ explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
+ AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+ friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
+ using std::swap;
+ swap(LHS.Pass, RHS.Pass);
+ }
+ AnalysisPassModel &operator=(AnalysisPassModel RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ // FIXME: Replace PassT::Result with type traits when we use C++11.
+ typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+ ResultModelT;
+
+ /// \brief The model delegates to the \c PassT::run method.
+ ///
+ /// The return is wrapped in an \c AnalysisResultModel.
+ std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+ run(IRUnitT IR, AnalysisManagerT *AM) override {
+ return make_unique<ResultModelT>(Pass.run(IR, AM));
+ }
+
+ PassT Pass;
+};
+
+/// \brief Specialization of \c AnalysisPassModel which does not pass an
+/// \c AnalysisManager to PassT's run method.
+template <typename IRUnitT, typename AnalysisManagerT, typename PassT>
+struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, false>
+ : AnalysisPassConcept<IRUnitT, AnalysisManagerT> {
+ explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
+ AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
+ friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
+ using std::swap;
+ swap(LHS.Pass, RHS.Pass);
+ }
+ AnalysisPassModel &operator=(AnalysisPassModel RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ // FIXME: Replace PassT::Result with type traits when we use C++11.
+ typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+ ResultModelT;
+
+ /// \brief The model delegates to the \c PassT::run method.
+ ///
+ /// The return is wrapped in an \c AnalysisResultModel.
+ std::unique_ptr<AnalysisResultConcept<IRUnitT>>
+ run(IRUnitT IR, AnalysisManagerT *) override {
+ return make_unique<ResultModelT>(Pass.run(IR));
+ }
+
+ PassT Pass;
+};
+
+} // End namespace detail
+
+class ModuleAnalysisManager;
class ModulePassManager {
public:
- ModulePassManager(Module *M, AnalysisManager *AM = 0) : M(M), AM(AM) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ ModulePassManager() {}
+ ModulePassManager(ModulePassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
+ ModulePassManager &operator=(ModulePassManager &&RHS) {
+ Passes = std::move(RHS.Passes);
+ return *this;
+ }
+
+ /// \brief Run all of the module passes in this module pass manager over
+ /// a module.
+ ///
+ /// This method should only be called for a single module as there is the
+ /// expectation that the lifetime of a pass is bounded to that of a module.
+ PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM = 0);
template <typename ModulePassT> void addPass(ModulePassT Pass) {
- Passes.push_back(new ModulePassModel<ModulePassT>(llvm_move(Pass)));
+ Passes.emplace_back(new ModulePassModel<ModulePassT>(std::move(Pass)));
}
- void run();
+ static StringRef name() { return "ModulePassManager"; }
private:
// Pull in the concept type and model template specialized for modules.
- typedef detail::PassConcept<Module *> ModulePassConcept;
+ typedef detail::PassConcept<Module *, ModuleAnalysisManager>
+ ModulePassConcept;
template <typename PassT>
- struct ModulePassModel : detail::PassModel<Module *, PassT> {
- ModulePassModel(PassT Pass) : detail::PassModel<Module *, PassT>(Pass) {}
+ struct ModulePassModel
+ : detail::PassModel<Module *, ModuleAnalysisManager, PassT> {
+ ModulePassModel(PassT Pass)
+ : detail::PassModel<Module *, ModuleAnalysisManager, PassT>(
+ std::move(Pass)) {}
};
- Module *M;
- AnalysisManager *AM;
- std::vector<polymorphic_ptr<ModulePassConcept> > Passes;
+ ModulePassManager(const ModulePassManager &) LLVM_DELETED_FUNCTION;
+ ModulePassManager &operator=(const ModulePassManager &) LLVM_DELETED_FUNCTION;
+
+ std::vector<std::unique_ptr<ModulePassConcept>> Passes;
};
+class FunctionAnalysisManager;
+
class FunctionPassManager {
public:
- FunctionPassManager(AnalysisManager *AM = 0) : AM(AM) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ FunctionPassManager() {}
+ FunctionPassManager(FunctionPassManager &&Arg)
+ : Passes(std::move(Arg.Passes)) {}
+ FunctionPassManager &operator=(FunctionPassManager &&RHS) {
+ Passes = std::move(RHS.Passes);
+ return *this;
+ }
template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
- Passes.push_back(new FunctionPassModel<FunctionPassT>(llvm_move(Pass)));
+ Passes.emplace_back(new FunctionPassModel<FunctionPassT>(std::move(Pass)));
}
- bool run(Module *M);
+ PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM = 0);
+
+ static StringRef name() { return "FunctionPassManager"; }
private:
// Pull in the concept type and model template specialized for functions.
- typedef detail::PassConcept<Function *> FunctionPassConcept;
+ typedef detail::PassConcept<Function *, FunctionAnalysisManager>
+ FunctionPassConcept;
template <typename PassT>
- struct FunctionPassModel : detail::PassModel<Function *, PassT> {
+ struct FunctionPassModel
+ : detail::PassModel<Function *, FunctionAnalysisManager, PassT> {
FunctionPassModel(PassT Pass)
- : detail::PassModel<Function *, PassT>(Pass) {}
+ : detail::PassModel<Function *, FunctionAnalysisManager, PassT>(
+ std::move(Pass)) {}
};
- AnalysisManager *AM;
- std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
+ FunctionPassManager(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
+ FunctionPassManager &
+ operator=(const FunctionPassManager &) LLVM_DELETED_FUNCTION;
+
+ std::vector<std::unique_ptr<FunctionPassConcept>> Passes;
};
+namespace detail {
-/// \brief An analysis manager to coordinate and cache analyses run over
-/// a module.
+/// \brief A CRTP base used to implement analysis managers.
///
-/// The analysis manager is typically used by passes in a pass pipeline
-/// (consisting potentially of several individual pass managers) over a module
-/// of IR. It provides registration of available analyses, declaring
-/// requirements on support for specific analyses, running of an specific
-/// analysis over a specific unit of IR to compute an analysis result, and
-/// caching of the analysis results to reuse them across multiple passes.
+/// This class template serves as the boiler plate of an analysis manager. Any
+/// analysis manager can be implemented on top of this base class. Any
+/// implementation will be required to provide specific hooks:
///
-/// It is the responsibility of callers to use the invalidation API to
-/// invalidate analysis results when the IR they correspond to changes. The
-/// \c ModulePassManager and \c FunctionPassManager do this automatically.
-class AnalysisManager {
-public:
- AnalysisManager(Module *M) : M(M) {}
+/// - getResultImpl
+/// - getCachedResultImpl
+/// - invalidateImpl
+///
+/// The details of the call pattern are within.
+template <typename DerivedT, typename IRUnitT> class AnalysisManagerBase {
+ DerivedT *derived_this() { return static_cast<DerivedT *>(this); }
+ const DerivedT *derived_this() const {
+ return static_cast<const DerivedT *>(this);
+ }
+
+ AnalysisManagerBase(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+ AnalysisManagerBase &
+ operator=(const AnalysisManagerBase &) LLVM_DELETED_FUNCTION;
+
+protected:
+ typedef detail::AnalysisResultConcept<IRUnitT> ResultConceptT;
+ typedef detail::AnalysisPassConcept<IRUnitT, DerivedT> PassConceptT;
+
+ // FIXME: Provide template aliases for the models when we're using C++11 in
+ // a mode supporting them.
+
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ AnalysisManagerBase() {}
+ AnalysisManagerBase(AnalysisManagerBase &&Arg)
+ : AnalysisPasses(std::move(Arg.AnalysisPasses)) {}
+ AnalysisManagerBase &operator=(AnalysisManagerBase &&RHS) {
+ AnalysisPasses = std::move(RHS.AnalysisPasses);
+ return *this;
+ }
+public:
/// \brief Get the result of an analysis pass for this module.
///
/// If there is not a valid cached result in the manager already, this will
/// re-run the analysis to produce a valid result.
- ///
- /// The module passed in must be the same module as the analysis manager was
- /// constructed around.
- template <typename PassT>
- const typename PassT::Result &getResult(Module *M) {
- assert(ModuleAnalysisPasses.count(PassT::ID()) &&
+ template <typename PassT> typename PassT::Result &getResult(IRUnitT IR) {
+ assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
- const AnalysisResultConcept<Module> &ResultConcept =
- getResultImpl(PassT::ID(), M);
- typedef AnalysisResultModel<Module, typename PassT::Result> ResultModelT;
- return static_cast<const ResultModelT &>(ResultConcept).Result;
+ ResultConceptT &ResultConcept =
+ derived_this()->getResultImpl(PassT::ID(), IR);
+ typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+ ResultModelT;
+ return static_cast<ResultModelT &>(ResultConcept).Result;
}
- /// \brief Get the result of an analysis pass for a function.
+ /// \brief Get the cached result of an analysis pass for this module.
///
- /// If there is not a valid cached result in the manager already, this will
- /// re-run the analysis to produce a valid result.
+ /// This method never runs the analysis.
+ ///
+ /// \returns null if there is no cached result.
template <typename PassT>
- const typename PassT::Result &getResult(Function *F) {
- assert(FunctionAnalysisPasses.count(PassT::ID()) &&
+ typename PassT::Result *getCachedResult(IRUnitT IR) const {
+ assert(AnalysisPasses.count(PassT::ID()) &&
"This analysis pass was not registered prior to being queried");
- const AnalysisResultConcept<Function> &ResultConcept =
- getResultImpl(PassT::ID(), F);
- typedef AnalysisResultModel<Function, typename PassT::Result> ResultModelT;
- return static_cast<const ResultModelT &>(ResultConcept).Result;
+ ResultConceptT *ResultConcept =
+ derived_this()->getCachedResultImpl(PassT::ID(), IR);
+ if (!ResultConcept)
+ return 0;
+
+ typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
+ ResultModelT;
+ return &static_cast<ResultModelT *>(ResultConcept)->Result;
}
/// \brief Register an analysis pass with the manager.
///
- /// This provides an initialized and set-up analysis pass to the
- /// analysis
- /// manager. Whomever is setting up analysis passes must use this to
- /// populate
+ /// This provides an initialized and set-up analysis pass to the analysis
+ /// manager. Whomever is setting up analysis passes must use this to populate
/// the manager with all of the analysis passes available.
- template <typename PassT> void registerAnalysisPass(PassT Pass) {
- registerAnalysisPassImpl<PassT>(llvm_move(Pass));
+ template <typename PassT> void registerPass(PassT Pass) {
+ assert(!AnalysisPasses.count(PassT::ID()) &&
+ "Registered the same analysis pass twice!");
+ typedef detail::AnalysisPassModel<IRUnitT, DerivedT, PassT> PassModelT;
+ AnalysisPasses[PassT::ID()].reset(new PassModelT(std::move(Pass)));
}
/// \brief Invalidate a specific analysis pass for an IR module.
///
/// Note that the analysis result can disregard invalidation.
template <typename PassT> void invalidate(Module *M) {
- invalidateImpl(PassT::ID(), M);
+ assert(AnalysisPasses.count(PassT::ID()) &&
+ "This analysis pass was not registered prior to being invalidated");
+ derived_this()->invalidateImpl(PassT::ID(), M);
}
- /// \brief Invalidate a specific analysis pass for an IR function.
+ /// \brief Invalidate analyses cached for an IR unit.
///
- /// Note that the analysis result can disregard invalidation.
- template <typename PassT> void invalidate(Function *F) {
- invalidateImpl(PassT::ID(), F);
+ /// Walk through all of the analyses pertaining to this unit of IR and
+ /// invalidate them unless they are preserved by the PreservedAnalyses set.
+ void invalidate(IRUnitT IR, const PreservedAnalyses &PA) {
+ derived_this()->invalidateImpl(IR, PA);
}
- /// \brief Invalidate analyses cached for an IR Module.
- ///
- /// Note that specific analysis results can disregard invalidation by
- /// overriding their invalidate method.
- ///
- /// The module must be the module this analysis manager was constructed
- /// around.
- void invalidateAll(Module *M);
+protected:
+ /// \brief Lookup a registered analysis pass.
+ PassConceptT &lookupPass(void *PassID) {
+ typename AnalysisPassMapT::iterator PI = AnalysisPasses.find(PassID);
+ assert(PI != AnalysisPasses.end() &&
+ "Analysis passes must be registered prior to being queried!");
+ return *PI->second;
+ }
- /// \brief Invalidate analyses cached for an IR Function.
- ///
- /// Note that specific analysis results can disregard invalidation by
- /// overriding the invalidate method.
- void invalidateAll(Function *F);
+ /// \brief Lookup a registered analysis pass.
+ const PassConceptT &lookupPass(void *PassID) const {
+ typename AnalysisPassMapT::const_iterator PI = AnalysisPasses.find(PassID);
+ assert(PI != AnalysisPasses.end() &&
+ "Analysis passes must be registered prior to being queried!");
+ return *PI->second;
+ }
private:
- /// \brief Abstract concept of an analysis result.
- ///
- /// This concept is parameterized over the IR unit that this result pertains
- /// to.
- template <typename IRUnitT> struct AnalysisResultConcept {
- virtual ~AnalysisResultConcept() {}
- virtual AnalysisResultConcept *clone() = 0;
-
- /// \brief Method to try and mark a result as invalid.
- ///
- /// When the outer \c AnalysisManager detects a change in some underlying
- /// unit of the IR, it will call this method on all of the results cached.
- ///
- /// \returns true if the result should indeed be invalidated (the default).
- virtual bool invalidate(IRUnitT *IR) = 0;
- };
-
- /// \brief Wrapper to model the analysis result concept.
- ///
- /// Can wrap any type which implements a suitable invalidate member and model
- /// the AnalysisResultConcept for the AnalysisManager.
- template <typename IRUnitT, typename ResultT>
- struct AnalysisResultModel : AnalysisResultConcept<IRUnitT> {
- AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {}
- virtual AnalysisResultModel *clone() {
- return new AnalysisResultModel(Result);
- }
-
- /// \brief The model delegates to the \c ResultT method.
- virtual bool invalidate(IRUnitT *IR) { return Result.invalidate(IR); }
-
- ResultT Result;
- };
-
- /// \brief Abstract concept of an analysis pass.
- ///
- /// This concept is parameterized over the IR unit that it can run over and
- /// produce an analysis result.
- template <typename IRUnitT> struct AnalysisPassConcept {
- virtual ~AnalysisPassConcept() {}
- virtual AnalysisPassConcept *clone() = 0;
-
- /// \brief Method to run this analysis over a unit of IR.
- /// \returns The analysis result object to be queried by users, the caller
- /// takes ownership.
- virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT *IR) = 0;
- };
-
- /// \brief Wrapper to model the analysis pass concept.
- ///
- /// Can wrap any type which implements a suitable \c run method. The method
- /// must accept the IRUnitT as an argument and produce an object which can be
- /// wrapped in a \c AnalysisResultModel.
- template <typename PassT>
- struct AnalysisPassModel : AnalysisPassConcept<typename PassT::IRUnitT> {
- AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
- virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); }
+ /// \brief Map type from module analysis pass ID to pass concept pointer.
+ typedef DenseMap<void *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
- // FIXME: Replace PassT::IRUnitT with type traits when we use C++11.
- typedef typename PassT::IRUnitT IRUnitT;
+ /// \brief Collection of module analysis passes, indexed by ID.
+ AnalysisPassMapT AnalysisPasses;
+};
- // FIXME: Replace PassT::Result with type traits when we use C++11.
- typedef AnalysisResultModel<IRUnitT, typename PassT::Result> ResultModelT;
+} // End namespace detail
- /// \brief The model delegates to the \c PassT::run method.
- ///
- /// The return is wrapped in an \c AnalysisResultModel.
- virtual ResultModelT *run(IRUnitT *IR) {
- return new ResultModelT(Pass.run(IR));
- }
+/// \brief A module analysis pass manager with lazy running and caching of
+/// results.
+class ModuleAnalysisManager
+ : public detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> {
+ friend class detail::AnalysisManagerBase<ModuleAnalysisManager, Module *>;
+ typedef detail::AnalysisManagerBase<ModuleAnalysisManager, Module *> BaseT;
+ typedef BaseT::ResultConceptT ResultConceptT;
+ typedef BaseT::PassConceptT PassConceptT;
- PassT Pass;
- };
+public:
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ ModuleAnalysisManager() {}
+ ModuleAnalysisManager(ModuleAnalysisManager &&Arg)
+ : BaseT(std::move(static_cast<BaseT &>(Arg))),
+ ModuleAnalysisResults(std::move(Arg.ModuleAnalysisResults)) {}
+ ModuleAnalysisManager &operator=(ModuleAnalysisManager &&RHS) {
+ BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ ModuleAnalysisResults = std::move(RHS.ModuleAnalysisResults);
+ return *this;
+ }
+private:
+ ModuleAnalysisManager(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
+ ModuleAnalysisManager &
+ operator=(const ModuleAnalysisManager &) LLVM_DELETED_FUNCTION;
/// \brief Get a module pass result, running the pass if necessary.
- const AnalysisResultConcept<Module> &getResultImpl(void *PassID, Module *M);
+ ResultConceptT &getResultImpl(void *PassID, Module *M);
- /// \brief Get a function pass result, running the pass if necessary.
- const AnalysisResultConcept<Function> &getResultImpl(void *PassID,
- Function *F);
+ /// \brief Get a cached module pass result or return null.
+ ResultConceptT *getCachedResultImpl(void *PassID, Module *M) const;
/// \brief Invalidate a module pass result.
void invalidateImpl(void *PassID, Module *M);
- /// \brief Invalidate a function pass result.
- void invalidateImpl(void *PassID, Function *F);
+ /// \brief Invalidate results across a module.
+ void invalidateImpl(Module *M, const PreservedAnalyses &PA);
+ /// \brief Map type from module analysis pass ID to pass result concept
+ /// pointer.
+ typedef DenseMap<void *,
+ std::unique_ptr<detail::AnalysisResultConcept<Module *>>>
+ ModuleAnalysisResultMapT;
- /// \brief Module pass specific implementation of registration.
- template <typename PassT>
- typename enable_if<is_same<typename PassT::IRUnitT, Module> >::type
- registerAnalysisPassImpl(PassT Pass) {
- assert(!ModuleAnalysisPasses.count(PassT::ID()) &&
- "Registered the same analysis pass twice!");
- ModuleAnalysisPasses[PassT::ID()] =
- new AnalysisPassModel<PassT>(llvm_move(Pass));
- }
+ /// \brief Cache of computed module analysis results for this module.
+ ModuleAnalysisResultMapT ModuleAnalysisResults;
+};
- /// \brief Function pass specific implementation of registration.
- template <typename PassT>
- typename enable_if<is_same<typename PassT::IRUnitT, Function> >::type
- registerAnalysisPassImpl(PassT Pass) {
- assert(!FunctionAnalysisPasses.count(PassT::ID()) &&
- "Registered the same analysis pass twice!");
- FunctionAnalysisPasses[PassT::ID()] =
- new AnalysisPassModel<PassT>(llvm_move(Pass));
- }
+/// \brief A function analysis manager to coordinate and cache analyses run over
+/// a module.
+class FunctionAnalysisManager
+ : public detail::AnalysisManagerBase<FunctionAnalysisManager, Function *> {
+ friend class detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>;
+ typedef detail::AnalysisManagerBase<FunctionAnalysisManager, Function *>
+ BaseT;
+ typedef BaseT::ResultConceptT ResultConceptT;
+ typedef BaseT::PassConceptT PassConceptT;
+public:
+ // Most public APIs are inherited from the CRTP base class.
+
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ FunctionAnalysisManager() {}
+ FunctionAnalysisManager(FunctionAnalysisManager &&Arg)
+ : BaseT(std::move(static_cast<BaseT &>(Arg))),
+ FunctionAnalysisResults(std::move(Arg.FunctionAnalysisResults)) {}
+ FunctionAnalysisManager &operator=(FunctionAnalysisManager &&RHS) {
+ BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ FunctionAnalysisResults = std::move(RHS.FunctionAnalysisResults);
+ return *this;
+ }
- /// \brief Map type from module analysis pass ID to pass concept pointer.
- typedef DenseMap<void *, polymorphic_ptr<AnalysisPassConcept<Module> > >
- ModuleAnalysisPassMapT;
+ /// \brief Returns true if the analysis manager has an empty results cache.
+ bool empty() const;
- /// \brief Collection of module analysis passes, indexed by ID.
- ModuleAnalysisPassMapT ModuleAnalysisPasses;
+ /// \brief Clear the function analysis result cache.
+ ///
+ /// This routine allows cleaning up when the set of functions itself has
+ /// potentially changed, and thus we can't even look up a a result and
+ /// invalidate it directly. Notably, this does *not* call invalidate
+ /// functions as there is nothing to be done for them.
+ void clear();
- /// \brief Map type from module analysis pass ID to pass result concept pointer.
- typedef DenseMap<void *, polymorphic_ptr<AnalysisResultConcept<Module> > >
- ModuleAnalysisResultMapT;
+private:
+ FunctionAnalysisManager(const FunctionAnalysisManager &)
+ LLVM_DELETED_FUNCTION;
+ FunctionAnalysisManager &
+ operator=(const FunctionAnalysisManager &) LLVM_DELETED_FUNCTION;
- /// \brief Cache of computed module analysis results for this module.
- ModuleAnalysisResultMapT ModuleAnalysisResults;
+ /// \brief Get a function pass result, running the pass if necessary.
+ ResultConceptT &getResultImpl(void *PassID, Function *F);
+ /// \brief Get a cached function pass result or return null.
+ ResultConceptT *getCachedResultImpl(void *PassID, Function *F) const;
- /// \brief Map type from function analysis pass ID to pass concept pointer.
- typedef DenseMap<void *, polymorphic_ptr<AnalysisPassConcept<Function> > >
- FunctionAnalysisPassMapT;
+ /// \brief Invalidate a function pass result.
+ void invalidateImpl(void *PassID, Function *F);
- /// \brief Collection of function analysis passes, indexed by ID.
- FunctionAnalysisPassMapT FunctionAnalysisPasses;
+ /// \brief Invalidate the results for a function..
+ void invalidateImpl(Function *F, const PreservedAnalyses &PA);
/// \brief List of function analysis pass IDs and associated concept pointers.
///
/// Requires iterators to be valid across appending new entries and arbitrary
/// erases. Provides both the pass ID and concept pointer such that it is
/// half of a bijection and provides storage for the actual result concept.
- typedef std::list<
- std::pair<void *, polymorphic_ptr<AnalysisResultConcept<Function> > > >
- FunctionAnalysisResultListT;
+ typedef std::list<std::pair<
+ void *, std::unique_ptr<detail::AnalysisResultConcept<Function *>>>>
+ FunctionAnalysisResultListT;
/// \brief Map type from function pointer to our custom list type.
- typedef DenseMap<Function *, FunctionAnalysisResultListT> FunctionAnalysisResultListMapT;
+ typedef DenseMap<Function *, FunctionAnalysisResultListT>
+ FunctionAnalysisResultListMapT;
/// \brief Map from function to a list of function analysis results.
///
@@ -370,14 +805,230 @@ private:
/// iterator into a particular result list.
typedef DenseMap<std::pair<void *, Function *>,
FunctionAnalysisResultListT::iterator>
- FunctionAnalysisResultMapT;
+ FunctionAnalysisResultMapT;
/// \brief Map from an analysis ID and function to a particular cached
/// analysis result.
FunctionAnalysisResultMapT FunctionAnalysisResults;
+};
+
+/// \brief A module analysis which acts as a proxy for a function analysis
+/// manager.
+///
+/// This primarily proxies invalidation information from the module analysis
+/// manager and module pass manager to a function analysis manager. You should
+/// never use a function analysis manager from within (transitively) a module
+/// pass manager unless your parent module pass has received a proxy result
+/// object for it.
+class FunctionAnalysisManagerModuleProxy {
+public:
+ class Result;
+
+ static void *ID() { return (void *)&PassID; }
+
+ explicit FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
+ : FAM(&FAM) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ FunctionAnalysisManagerModuleProxy(
+ const FunctionAnalysisManagerModuleProxy &Arg)
+ : FAM(Arg.FAM) {}
+ FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
+ : FAM(std::move(Arg.FAM)) {}
+ FunctionAnalysisManagerModuleProxy &
+ operator=(FunctionAnalysisManagerModuleProxy RHS) {
+ std::swap(FAM, RHS.FAM);
+ return *this;
+ }
+
+ /// \brief Run the analysis pass and create our proxy result object.
+ ///
+ /// This doesn't do any interesting work, it is primarily used to insert our
+ /// proxy result object into the module analysis cache so that we can proxy
+ /// invalidation to the function analysis manager.
+ ///
+ /// In debug builds, it will also assert that the analysis manager is empty
+ /// as no queries should arrive at the function analysis manager prior to
+ /// this analysis being requested.
+ Result run(Module *M);
+
+private:
+ static char PassID;
+
+ FunctionAnalysisManager *FAM;
+};
+
+/// \brief The result proxy object for the
+/// \c FunctionAnalysisManagerModuleProxy.
+///
+/// See its documentation for more information.
+class FunctionAnalysisManagerModuleProxy::Result {
+public:
+ explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ Result(const Result &Arg) : FAM(Arg.FAM) {}
+ Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
+ Result &operator=(Result RHS) {
+ std::swap(FAM, RHS.FAM);
+ return *this;
+ }
+ ~Result();
+
+ /// \brief Accessor for the \c FunctionAnalysisManager.
+ FunctionAnalysisManager &getManager() { return *FAM; }
+
+ /// \brief Handler for invalidation of the module.
+ ///
+ /// If this analysis itself is preserved, then we assume that the set of \c
+ /// Function objects in the \c Module hasn't changed and thus we don't need
+ /// to invalidate *all* cached data associated with a \c Function* in the \c
+ /// FunctionAnalysisManager.
+ ///
+ /// Regardless of whether this analysis is marked as preserved, all of the
+ /// analyses in the \c FunctionAnalysisManager are potentially invalidated
+ /// based on the set of preserved analyses.
+ bool invalidate(Module *M, const PreservedAnalyses &PA);
+
+private:
+ FunctionAnalysisManager *FAM;
+};
+
+/// \brief A function analysis which acts as a proxy for a module analysis
+/// manager.
+///
+/// This primarily provides an accessor to a parent module analysis manager to
+/// function passes. Only the const interface of the module analysis manager is
+/// provided to indicate that once inside of a function analysis pass you
+/// cannot request a module analysis to actually run. Instead, the user must
+/// rely on the \c getCachedResult API.
+///
+/// This proxy *doesn't* manage the invalidation in any way. That is handled by
+/// the recursive return path of each layer of the pass manager and the
+/// returned PreservedAnalysis set.
+class ModuleAnalysisManagerFunctionProxy {
+public:
+ /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy.
+ class Result {
+ public:
+ explicit Result(const ModuleAnalysisManager &MAM) : MAM(&MAM) {}
+ // We have to explicitly define all the special member functions because
+ // MSVC refuses to generate them.
+ Result(const Result &Arg) : MAM(Arg.MAM) {}
+ Result(Result &&Arg) : MAM(std::move(Arg.MAM)) {}
+ Result &operator=(Result RHS) {
+ std::swap(MAM, RHS.MAM);
+ return *this;
+ }
+
+ const ModuleAnalysisManager &getManager() const { return *MAM; }
+
+ /// \brief Handle invalidation by ignoring it, this pass is immutable.
+ bool invalidate(Function *) { return false; }
+
+ private:
+ const ModuleAnalysisManager *MAM;
+ };
- /// \brief Module handle for the \c AnalysisManager.
- Module *M;
+ static void *ID() { return (void *)&PassID; }
+
+ ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
+ : MAM(&MAM) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ ModuleAnalysisManagerFunctionProxy(
+ const ModuleAnalysisManagerFunctionProxy &Arg)
+ : MAM(Arg.MAM) {}
+ ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
+ : MAM(std::move(Arg.MAM)) {}
+ ModuleAnalysisManagerFunctionProxy &
+ operator=(ModuleAnalysisManagerFunctionProxy RHS) {
+ std::swap(MAM, RHS.MAM);
+ return *this;
+ }
+
+ /// \brief Run the analysis pass and create our proxy result object.
+ /// Nothing to see here, it just forwards the \c MAM reference into the
+ /// result.
+ Result run(Function *) { return Result(*MAM); }
+
+private:
+ static char PassID;
+
+ const ModuleAnalysisManager *MAM;
};
+/// \brief Trivial adaptor that maps from a module to its functions.
+///
+/// Designed to allow composition of a FunctionPass(Manager) and
+/// a ModulePassManager. Note that if this pass is constructed with a pointer
+/// to a \c ModuleAnalysisManager it will run the
+/// \c FunctionAnalysisManagerModuleProxy analysis prior to running the function
+/// pass over the module to enable a \c FunctionAnalysisManager to be used
+/// within this run safely.
+template <typename FunctionPassT> class ModuleToFunctionPassAdaptor {
+public:
+ explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass)
+ : Pass(std::move(Pass)) {}
+ // We have to explicitly define all the special member functions because MSVC
+ // refuses to generate them.
+ ModuleToFunctionPassAdaptor(const ModuleToFunctionPassAdaptor &Arg)
+ : Pass(Arg.Pass) {}
+ ModuleToFunctionPassAdaptor(ModuleToFunctionPassAdaptor &&Arg)
+ : Pass(std::move(Arg.Pass)) {}
+ friend void swap(ModuleToFunctionPassAdaptor &LHS, ModuleToFunctionPassAdaptor &RHS) {
+ using std::swap;
+ swap(LHS.Pass, RHS.Pass);
+ }
+ ModuleToFunctionPassAdaptor &operator=(ModuleToFunctionPassAdaptor RHS) {
+ swap(*this, RHS);
+ return *this;
+ }
+
+ /// \brief Runs the function pass across every function in the module.
+ PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
+ FunctionAnalysisManager *FAM = 0;
+ if (AM)
+ // Setup the function analysis manager from its proxy.
+ FAM = &AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
+ PreservedAnalyses PassPA = Pass.run(I, FAM);
+
+ // We know that the function pass couldn't have invalidated any other
+ // function's analyses (that's the contract of a function pass), so
+ // directly handle the function analysis manager's invalidation here.
+ if (FAM)
+ FAM->invalidate(I, PassPA);
+
+ // Then intersect the preserved set so that invalidation of module
+ // analyses will eventually occur when the module pass completes.
+ PA.intersect(std::move(PassPA));
+ }
+
+ // By definition we preserve the proxy. This precludes *any* invalidation
+ // of function analyses by the proxy, but that's OK because we've taken
+ // care to invalidate analyses in the function analysis manager
+ // incrementally above.
+ PA.preserve<FunctionAnalysisManagerModuleProxy>();
+ return PA;
+ }
+
+ static StringRef name() { return "ModuleToFunctionPassAdaptor"; }
+
+private:
+ FunctionPassT Pass;
+};
+
+/// \brief A function to deduce a function pass type and wrap it in the
+/// templated adaptor.
+template <typename FunctionPassT>
+ModuleToFunctionPassAdaptor<FunctionPassT>
+createModuleToFunctionPassAdaptor(FunctionPassT Pass) {
+ return std::move(ModuleToFunctionPassAdaptor<FunctionPassT>(std::move(Pass)));
}
+
+}
+
+#endif
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/IR/PatternMatch.h
index 240bb81..2efb294 100644
--- a/include/llvm/Support/PatternMatch.h
+++ b/include/llvm/IR/PatternMatch.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
+//===- PatternMatch.h - Match on the LLVM IR --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -26,14 +26,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_PATTERNMATCH_H
-#define LLVM_SUPPORT_PATTERNMATCH_H
+#ifndef LLVM_IR_PATTERNMATCH_H
+#define LLVM_IR_PATTERNMATCH_H
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
-#include "llvm/Support/CallSite.h"
namespace llvm {
namespace PatternMatch {
@@ -498,6 +498,96 @@ m_AShr(const LHS &L, const RHS &R) {
return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
}
+template<typename LHS_t, typename RHS_t, unsigned Opcode, unsigned WrapFlags = 0>
+struct OverflowingBinaryOp_match {
+ LHS_t L;
+ RHS_t R;
+
+ OverflowingBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (OverflowingBinaryOperator *Op = dyn_cast<OverflowingBinaryOperator>(V)) {
+ if (Op->getOpcode() != Opcode)
+ return false;
+ if (WrapFlags & OverflowingBinaryOperator::NoUnsignedWrap &&
+ !Op->hasNoUnsignedWrap())
+ return false;
+ if (WrapFlags & OverflowingBinaryOperator::NoSignedWrap &&
+ !Op->hasNoSignedWrap())
+ return false;
+ return L.match(Op->getOperand(0)) && R.match(Op->getOperand(1));
+ }
+ return false;
+ }
+};
+
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWAdd(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWSub(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWMul(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoSignedWrap>
+m_NSWShl(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoSignedWrap>(
+ L, R);
+}
+
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWAdd(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Add,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWSub(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Sub,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWMul(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Mul,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+template <typename LHS, typename RHS>
+inline OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoUnsignedWrap>
+m_NUWShl(const LHS &L, const RHS &R) {
+ return OverflowingBinaryOp_match<LHS, RHS, Instruction::Shl,
+ OverflowingBinaryOperator::NoUnsignedWrap>(
+ L, R);
+}
+
//===----------------------------------------------------------------------===//
// Class that matches two different binary ops.
//
diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/IR/PredIteratorCache.h
index c5fb780..bf18dfe 100644
--- a/include/llvm/Support/PredIteratorCache.h
+++ b/include/llvm/IR/PredIteratorCache.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/PredIteratorCache.h - pred_iterator Cache ---*- C++ -*-===//
+//===- PredIteratorCache.h - pred_iterator Cache ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,11 +13,11 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/CFG.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/CFG.h"
-#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H
-#define LLVM_SUPPORT_PREDITERATORCACHE_H
+#ifndef LLVM_IR_PREDITERATORCACHE_H
+#define LLVM_IR_PREDITERATORCACHE_H
namespace llvm {
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
index 3cfb84e..742a0d3 100644
--- a/include/llvm/IR/Type.h
+++ b/include/llvm/IR/Type.h
@@ -15,12 +15,13 @@
#ifndef LLVM_IR_TYPE_H
#define LLVM_IR_TYPE_H
+#include "llvm-c/Core.h"
#include "llvm/ADT/APFloat.h"
-#include "llvm/Support/Casting.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm-c/Core.h"
namespace llvm {
@@ -70,11 +71,7 @@ public:
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
+ VectorTyID ///< 15: SIMD 'packed' format, or other vector type
};
private:
@@ -239,12 +236,6 @@ public:
/// 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.
///
@@ -257,9 +248,8 @@ public:
/// and array types.
///
bool isSingleValueType() const {
- return (getTypeID() != VoidTyID && isPrimitiveType()) ||
- getTypeID() == IntegerTyID || getTypeID() == PointerTyID ||
- getTypeID() == VectorTyID;
+ return isFloatingPointTy() || isX86_MMXTy() || isIntegerTy() ||
+ isPointerTy() || isVectorTy();
}
/// isAggregateType - Return true if the type is an aggregate type. This
@@ -275,7 +265,7 @@ public:
/// get the actual size for a particular target, it is reasonable to use the
/// DataLayout subsystem to do this.
///
- bool isSized() const {
+ bool isSized(SmallPtrSet<const Type*, 4> *Visited = 0) const {
// If it's a primitive, it is always sized.
if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
getTypeID() == PointerTyID ||
@@ -287,7 +277,7 @@ public:
getTypeID() != VectorTyID)
return false;
// Otherwise we have to try harder to decide.
- return isSizedDerivedType();
+ return isSizedDerivedType(Visited);
}
/// getPrimitiveSizeInBits - Return the basic size of this type if it is a
@@ -300,12 +290,12 @@ public:
/// instance of the type is stored to memory. The DataLayout class provides
/// additional query functions to provide this information.
///
- unsigned getPrimitiveSizeInBits() const;
+ unsigned getPrimitiveSizeInBits() const LLVM_READONLY;
/// 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();
+ unsigned getScalarSizeInBits() const LLVM_READONLY;
/// getFPMantissaWidth - Return the width of the mantissa of this type. This
/// is only valid on floating point types. If the FP type does not
@@ -314,8 +304,8 @@ public:
/// getScalarType - If this is a vector type, return the element type,
/// otherwise return 'this'.
- const Type *getScalarType() const;
- Type *getScalarType();
+ const Type *getScalarType() const LLVM_READONLY;
+ Type *getScalarType() LLVM_READONLY;
//===--------------------------------------------------------------------===//
// Type Iteration support.
@@ -429,7 +419,7 @@ 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;
+ bool isSizedDerivedType(SmallPtrSet<const Type*, 4> *Visited = 0) const;
};
// Printing of types.
diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h
index 12cd150..340572a 100644
--- a/include/llvm/IR/Use.h
+++ b/include/llvm/IR/Use.h
@@ -6,29 +6,29 @@
// 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
-//
+/// \file
+///
+/// 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_IR_USE_H
#define LLVM_IR_USE_H
+#include "llvm-c/Core.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
-#include "llvm-c/Core.h"
#include <cstddef>
#include <iterator>
@@ -37,64 +37,67 @@ namespace llvm {
class Value;
class User;
class Use;
-template<typename>
-struct simplify_type;
+template <typename> struct simplify_type;
// Use** is only 4-byte aligned.
-template<>
-class PointerLikeTypeTraits<Use**> {
+template <> class PointerLikeTypeTraits<Use **> {
public:
- static inline void *getAsVoidPointer(Use** P) { return P; }
+ static inline void *getAsVoidPointer(Use **P) { return P; }
static inline Use **getFromVoidPointer(void *P) {
- return static_cast<Use**>(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.
+/// \brief A Use represents the edge between a Value definition and its users.
+///
+/// This is notionally a two-dimensional linked list. It supports traversing
+/// all of the uses for a particular value definition. It also supports jumping
+/// directly to the used value when we arrive from the User's operands, and
+/// jumping directly to the User when we arrive from the Value's uses.
+///
+/// The pointer to the used Value is explicit, and the pointer to the User is
+/// implicit. The implicit pointer is found via a waymarking algorithm
+/// described in the programmer's manual:
+///
+/// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
+///
+/// This is essentially the single most memory intensive object in LLVM because
+/// of the number of uses in the system. At the same time, the constant time
+/// operations it allows are essential to many optimizations having reasonable
+/// time complexity.
class Use {
public:
- /// swap - provide a fast substitute to std::swap<Use>
+ /// \brief 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;
+ typedef PointerIntPair<User *, 1, unsigned> UserRef;
private:
Use(const Use &U) LLVM_DELETED_FUNCTION;
/// Destructor - Only for zap()
~Use() {
- if (Val) removeFromList();
+ if (Val)
+ removeFromList();
}
- enum PrevPtrTag { zeroDigitTag
- , oneDigitTag
- , stopTag
- , fullStopTag };
+ enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
/// Constructor
- Use(PrevPtrTag tag) : Val(0) {
- Prev.setInt(tag);
- }
+ 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*.
+ operator Value *() const { return Val; }
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.
+
+ /// \brief 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);
@@ -108,116 +111,63 @@ public:
return *this;
}
- Value *operator->() { return Val; }
+ 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.
+ /// \brief Return the operand # of this use in its User.
+ unsigned getOperandNo() const;
+
+ /// \brief Initializes the waymarking tags on an array of Uses.
+ ///
+ /// This sets up the array of Uses such 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
+ /// \brief Destroys 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;
-
+ const Use *getImpliedUser() const;
+
Value *Val;
Use *Next;
- PointerIntPair<Use**, 2, PrevPtrTag> Prev;
+ PointerIntPair<Use **, 2, PrevPtrTag> Prev;
- void setPrev(Use **NewPrev) {
- Prev.setPointer(NewPrev);
- }
+ void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
void addToList(Use **List) {
Next = *List;
- if (Next) Next->setPrev(&Next);
+ if (Next)
+ Next->setPrev(&Next);
setPrev(List);
*List = this;
}
void removeFromList() {
Use **StrippedPrev = Prev.getPointer();
*StrippedPrev = Next;
- if (Next) Next->setPrev(StrippedPrev);
+ 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(Use &Val) {
- return Val.get();
- }
+/// \brief Allow clients to treat uses just like values when using
+/// casting operators.
+template <> struct simplify_type<Use> {
+ typedef Value *SimpleType;
+ static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
};
-template<> struct simplify_type<const Use> {
- typedef /*const*/ Value* SimpleType;
- static SimpleType getSimplifiedValue(const Use &Val) {
- return 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() {}
-
- 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;
+template <> struct simplify_type<const Use> {
+ typedef /*const*/ Value *SimpleType;
+ static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
-} // End llvm namespace
+}
#endif
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
index 505bdeb..061bc91 100644
--- a/include/llvm/IR/User.h
+++ b/include/llvm/IR/User.h
@@ -19,6 +19,7 @@
#ifndef LLVM_IR_USER_H
#define LLVM_IR_USER_H
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/ErrorHandling.h"
@@ -112,11 +113,19 @@ public:
//
typedef Use* op_iterator;
typedef const Use* const_op_iterator;
+ typedef iterator_range<op_iterator> op_range;
+ typedef iterator_range<const_op_iterator> const_op_range;
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; }
+ inline op_range operands() {
+ return op_range(op_begin(), op_end());
+ }
+ inline const_op_range operands() const {
+ return const_op_range(op_begin(), op_end());
+ }
/// Convenience iterator for directly iterating over the Values in the
/// OperandList
@@ -156,6 +165,9 @@ public:
inline value_op_iterator value_op_end() {
return value_op_iterator(op_end());
}
+ inline iterator_range<value_op_iterator> operand_values() {
+ return iterator_range<value_op_iterator>(value_op_begin(), value_op_end());
+ }
// dropAllReferences() - This function is in charge of "letting go" of all
// objects that this User refers to. This allows one to
@@ -166,8 +178,8 @@ public:
// delete.
//
void dropAllReferences() {
- for (op_iterator i = op_begin(), e = op_end(); i != e; ++i)
- i->set(0);
+ for (Use &U : operands())
+ U.set(0);
}
/// replaceUsesOfWith - Replaces all references to the "From" definition with
@@ -194,12 +206,6 @@ template<> struct 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/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index e1361fe..d5b9f11 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -14,11 +14,12 @@
#ifndef LLVM_IR_VALUE_H
#define LLVM_IR_VALUE_H
+#include "llvm-c/Core.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/Use.h"
-#include "llvm/Support/Casting.h"
#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
-#include "llvm-c/Core.h"
namespace llvm {
@@ -36,6 +37,7 @@ class InlineAsm;
class Instruction;
class LLVMContext;
class MDNode;
+class Module;
class StringRef;
class Twine;
class Type;
@@ -60,7 +62,7 @@ typedef StringMapEntry<Value*> ValueName;
/// 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.
+/// llvm/IR/ValueHandle.h for details.
///
/// @brief LLVM Value Representation
class Value {
@@ -74,6 +76,96 @@ protected:
unsigned char SubclassOptionalData : 7;
private:
+ template <typename UseT> // UseT == 'Use' or 'const Use'
+ class use_iterator_impl
+ : public std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag, UseT *, ptrdiff_t> super;
+
+ UseT *U;
+ explicit use_iterator_impl(UseT *u) : U(u) {}
+ friend class Value;
+
+ public:
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ use_iterator_impl() : U() {}
+
+ bool operator==(const use_iterator_impl &x) const { return U == x.U; }
+ bool operator!=(const use_iterator_impl &x) const { return !operator==(x); }
+
+ use_iterator_impl &operator++() { // Preincrement
+ assert(U && "Cannot increment end iterator!");
+ U = U->getNext();
+ return *this;
+ }
+ use_iterator_impl operator++(int) { // Postincrement
+ auto tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ UseT &operator*() const {
+ assert(U && "Cannot dereference end iterator!");
+ return *U;
+ }
+
+ UseT *operator->() const { return &operator*(); }
+
+ operator use_iterator_impl<const UseT>() const {
+ return use_iterator_impl<const UseT>(U);
+ }
+ };
+
+ template <typename UserTy> // UserTy == 'User' or 'const User'
+ class user_iterator_impl
+ : public std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> super;
+
+ use_iterator_impl<Use> UI;
+ explicit user_iterator_impl(Use *U) : UI(U) {}
+ friend class Value;
+
+ public:
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ user_iterator_impl() {}
+
+ bool operator==(const user_iterator_impl &x) const { return UI == x.UI; }
+ bool operator!=(const user_iterator_impl &x) const { return !operator==(x); }
+
+ /// \brief Returns true if this iterator is equal to user_end() on the value.
+ bool atEnd() const { return *this == user_iterator_impl(); }
+
+ user_iterator_impl &operator++() { // Preincrement
+ ++UI;
+ return *this;
+ }
+ user_iterator_impl operator++(int) { // Postincrement
+ auto tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Retrieve a pointer to the current User.
+ UserTy *operator*() const {
+ return UI->getUser();
+ }
+
+ UserTy *operator->() const { return operator*(); }
+
+ operator user_iterator_impl<const UserTy>() const {
+ return user_iterator_impl<const UserTy>(*UI);
+ }
+
+ Use &getUse() const { return *UI; }
+
+ /// \brief Return the operand # of this use in its User.
+ /// FIXME: Replace all callers with a direct call to Use::getOperandNo.
+ unsigned getOperandNo() const { return UI->getOperandNo(); }
+ };
+
/// 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.
@@ -106,6 +198,13 @@ public:
///
void print(raw_ostream &O, AssemblyAnnotationWriter *AAW = 0) const;
+ /// \brief Print the name of this Value out to the specified raw_ostream.
+ /// This is useful when you just want to print 'int %reg126', not the
+ /// instruction that generated it. If you specify a Module for context, then
+ /// even constanst get pretty-printed; for example, the type of a null
+ /// pointer is printed symbolically.
+ void printAsOperand(raw_ostream &O, bool PrintType = true, const Module *M = 0) const;
+
/// All values are typed, get the type of this value.
///
Type *getType() const { return VTy; }
@@ -143,16 +242,35 @@ public:
//----------------------------------------------------------------------
// 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; }
+
+ typedef use_iterator_impl<Use> use_iterator;
+ typedef use_iterator_impl<const Use> const_use_iterator;
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(); }
+ use_iterator use_end() { return use_iterator(); }
+ const_use_iterator use_end() const { return const_use_iterator(); }
+ iterator_range<use_iterator> uses() {
+ return iterator_range<use_iterator>(use_begin(), use_end());
+ }
+ iterator_range<const_use_iterator> uses() const {
+ return iterator_range<const_use_iterator>(use_begin(), use_end());
+ }
+
+ typedef user_iterator_impl<User> user_iterator;
+ typedef user_iterator_impl<const User> const_user_iterator;
+ user_iterator user_begin() { return user_iterator(UseList); }
+ const_user_iterator user_begin() const { return const_user_iterator(UseList); }
+ user_iterator user_end() { return user_iterator(); }
+ const_user_iterator user_end() const { return const_user_iterator(); }
+ User *user_back() { return *user_begin(); }
+ const User *user_back() const { return *user_begin(); }
+ iterator_range<user_iterator> users() {
+ return iterator_range<user_iterator>(user_begin(), user_end());
+ }
+ iterator_range<const_user_iterator> users() const {
+ return iterator_range<const_user_iterator>(user_begin(), user_end());
+ }
/// 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
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/IR/ValueHandle.h
index bc02ba3..9b5e11a 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/IR/ValueHandle.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===//
+//===- ValueHandle.h - Value Smart Pointer classes --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_VALUEHANDLE_H
-#define LLVM_SUPPORT_VALUEHANDLE_H
+#ifndef LLVM_IR_VALUEHANDLE_H
+#define LLVM_IR_VALUEHANDLE_H
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/PointerIntPair.h"
diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/IR/ValueMap.h
index b4fed7a..42da529 100644
--- a/include/llvm/ADT/ValueMap.h
+++ b/include/llvm/IR/ValueMap.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/ValueMap.h - Safe map from Values to data -------*- C++ -*-===//
+//===- ValueMap.h - Safe map from Values to data ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -23,12 +23,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_VALUEMAP_H
-#define LLVM_ADT_VALUEMAP_H
+#ifndef LLVM_IR_VALUEMAP_H
+#define LLVM_IR_VALUEMAP_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/type_traits.h"
#include <iterator>
@@ -198,7 +198,7 @@ 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;
+ typedef typename std::remove_pointer<KeyT>::type KeySansPointerT;
ValueMapT *Map;
@@ -209,7 +209,7 @@ class ValueMapCallbackVH : public CallbackVH {
public:
KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
- virtual void deleted() {
+ void deleted() override {
// Make a copy that won't get changed even when *this is destroyed.
ValueMapCallbackVH Copy(*this);
sys::Mutex *M = Config::getMutex(Copy.Map->Data);
@@ -220,7 +220,7 @@ public:
if (M)
M->release();
}
- virtual void allUsesReplacedWith(Value *new_key) {
+ void allUsesReplacedWith(Value *new_key) override {
assert(isa<KeySansPointerT>(new_key) &&
"Invalid RAUW on key of ValueMap<>");
// Make a copy that won't get changed even when *this is destroyed.
diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h
new file mode 100644
index 0000000..9a2f402
--- /dev/null
+++ b/include/llvm/IR/Verifier.h
@@ -0,0 +1,75 @@
+//===- 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_IR_VERIFIER_H
+#define LLVM_IR_VERIFIER_H
+
+#include "llvm/ADT/StringRef.h"
+#include <string>
+
+namespace llvm {
+
+class Function;
+class FunctionPass;
+class Module;
+class PreservedAnalyses;
+class raw_ostream;
+
+/// \brief Check a function for errors, useful for use when debugging a
+/// pass.
+///
+/// If there are no errors, the function returns false. If an error is found,
+/// a message describing the error is written to OS (if non-null) and true is
+/// returned.
+bool verifyFunction(const Function &F, raw_ostream *OS = 0);
+
+/// \brief Check a module for errors.
+///
+/// If there are no errors, the function returns false. If an error is found,
+/// a message describing the error is written to OS (if non-null) and true is
+/// returned.
+bool verifyModule(const Module &M, raw_ostream *OS = 0);
+
+/// \brief Create a verifier pass.
+///
+/// Check a module or function for validity. This is essentially a pass wrapped
+/// around the above verifyFunction and verifyModule routines and
+/// functionality. When the pass detects a verification error it is always
+/// printed to stderr, and by default they are fatal. You can override that by
+/// passing \c false to \p FatalErrors.
+///
+/// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass.
+FunctionPass *createVerifierPass(bool FatalErrors = true);
+
+class VerifierPass {
+ bool FatalErrors;
+
+public:
+ explicit VerifierPass(bool FatalErrors = true) : FatalErrors(FatalErrors) {}
+
+ PreservedAnalyses run(Module *M);
+ PreservedAnalyses run(Function *F);
+
+ static StringRef name() { return "VerifierPass"; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index aefb3c0..9b9f234 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -63,6 +63,7 @@ void initializeCodeGen(PassRegistry&);
void initializeTarget(PassRegistry&);
void initializeAAEvalPass(PassRegistry&);
+void initializeAddDiscriminatorsPass(PassRegistry&);
void initializeADCEPass(PassRegistry&);
void initializeAliasAnalysisAnalysisGroup(PassRegistry&);
void initializeAliasAnalysisCounterPass(PassRegistry&);
@@ -73,7 +74,7 @@ void initializeArgPromotionPass(PassRegistry&);
void initializeSampleProfileLoaderPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
-void initializeCallGraphPass(PassRegistry&);
+void initializeCallGraphWrapperPassPass(PassRegistry &);
void initializeBasicTTIPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
void initializeBlockFrequencyInfoPass(PassRegistry&);
@@ -90,6 +91,7 @@ void initializeCFGSimplifyPassPass(PassRegistry&);
void initializeFlattenCFGPassPass(PassRegistry&);
void initializeStructurizeCFGPass(PassRegistry&);
void initializeCFGViewerPass(PassRegistry&);
+void initializeConstantHoistingPass(PassRegistry&);
void initializeCodeGenPreparePass(PassRegistry&);
void initializeConstantMergePass(PassRegistry&);
void initializeConstantPropagationPass(PassRegistry&);
@@ -110,7 +112,7 @@ void initializeDomOnlyViewerPass(PassRegistry&);
void initializeDomPrinterPass(PassRegistry&);
void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierPass(PassRegistry&);
-void initializeDominatorTreePass(PassRegistry&);
+void initializeDominatorTreeWrapperPassPass(PassRegistry&);
void initializeEarlyIfConverterPass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
void initializeExpandPostRAPass(PassRegistry&);
@@ -120,6 +122,7 @@ void initializeAddressSanitizerModulePass(PassRegistry&);
void initializeMemorySanitizerPass(PassRegistry&);
void initializeThreadSanitizerPass(PassRegistry&);
void initializeDataFlowSanitizerPass(PassRegistry&);
+void initializeScalarizerPass(PassRegistry&);
void initializeEarlyCSEPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&);
void initializeFindUsedTypesPass(PassRegistry&);
@@ -209,9 +212,9 @@ void initializePostDomPrinterPass(PassRegistry&);
void initializePostDomViewerPass(PassRegistry&);
void initializePostDominatorTreePass(PassRegistry&);
void initializePostRASchedulerPass(PassRegistry&);
-void initializePreVerifierPass(PassRegistry&);
-void initializePrintFunctionPassPass(PassRegistry&);
-void initializePrintModulePassPass(PassRegistry&);
+void initializePostMachineSchedulerPass(PassRegistry&);
+void initializePrintFunctionPassWrapperPass(PassRegistry&);
+void initializePrintModulePassWrapperPass(PassRegistry&);
void initializePrintBasicBlockPassPass(PassRegistry&);
void initializeProcessImplicitDefsPass(PassRegistry&);
void initializePromotePassPass(PassRegistry&);
@@ -246,7 +249,7 @@ void initializeStripSymbolsPass(PassRegistry&);
void initializeTailCallElimPass(PassRegistry&);
void initializeTailDuplicatePassPass(PassRegistry&);
void initializeTargetPassConfigPass(PassRegistry&);
-void initializeDataLayoutPass(PassRegistry&);
+void initializeDataLayoutPassPass(PassRegistry &);
void initializeTargetTransformInfoAnalysisGroup(PassRegistry&);
void initializeNoTTIPass(PassRegistry&);
void initializeTargetLibraryInfoPass(PassRegistry&);
@@ -255,7 +258,7 @@ void initializeTypeBasedAliasAnalysisPass(PassRegistry&);
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
void initializeUnreachableBlockElimPass(PassRegistry&);
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
-void initializeVerifierPass(PassRegistry&);
+void initializeVerifierLegacyPassPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);
void initializeVirtRegRewriterPass(PassRegistry&);
void initializeInstSimplifierPass(PassRegistry&);
@@ -265,6 +268,7 @@ void initializeLoopVectorizePass(PassRegistry&);
void initializeSLPVectorizerPass(PassRegistry&);
void initializeBBVectorizePass(PassRegistry&);
void initializeMachineFunctionPrinterPassPass(PassRegistry&);
+void initializeStackMapLivenessPass(PassRegistry&);
}
#endif
diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h
index c478bd9..5433991 100644
--- a/include/llvm/LTO/LTOCodeGenerator.h
+++ b/include/llvm/LTO/LTOCodeGenerator.h
@@ -9,7 +9,7 @@
//
// This file declares the LTOCodeGenerator class.
//
-// LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO.
+// LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO.
//
// The Pre-IPO phase compiles source code into bitcode file. The resulting
// bitcode files, along with object files and libraries, will be fed to the
@@ -21,12 +21,12 @@
// The IPO phase perform inter-procedural analyses and optimizations, and
// the Post-IPO consists two sub-phases: intra-procedural scalar optimizations
// (SOPT), and intra-procedural target-dependent code generator (CG).
-//
+//
// As of this writing, we don't separate IPO and the Post-IPO SOPT. They
// are intermingled together, and are driven by a single pass manager (see
// PassManagerBuilder::populateLTOPassManager()).
-//
-// The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages.
+//
+// The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages.
// The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator"
// with the machine specific code generator.
//
@@ -36,16 +36,17 @@
#define LTO_CODE_GENERATOR_H
#include "llvm-c/lto.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Linker.h"
+#include "llvm/Linker/Linker.h"
#include "llvm/Target/TargetOptions.h"
#include <string>
#include <vector>
namespace llvm {
class LLVMContext;
+ class DiagnosticInfo;
class GlobalValue;
class Mangler;
class MemoryBuffer;
@@ -79,9 +80,8 @@ struct LTOCodeGenerator {
// not necessarily for debugging purpose (The function name is misleading).
// This function should be called before LTOCodeGenerator::compilexxx(),
// and LTOCodeGenerator::writeMergedModules().
- //
void setCodeGenDebugOptions(const char *opts);
-
+
// Parse the options set in setCodeGenDebugOptions. Like
// setCodeGenDebugOptions, this must be called before
// LTOCodeGenerator::compilexxx() and LTOCodeGenerator::writeMergedModules()
@@ -98,7 +98,6 @@ struct LTOCodeGenerator {
// NOTE that it is up to the linker to remove the intermediate object file.
// Do not try to remove the object file in LTOCodeGenerator's destructor
// as we don't who (LTOCodeGenerator or the obj file) will last longer.
- //
bool compile_to_file(const char **name,
bool disableOpt,
bool disableInline,
@@ -109,14 +108,15 @@ struct LTOCodeGenerator {
// single object file. Instead of returning the object-file-path to the caller
// (linker), it brings the object to a buffer, and return the buffer to the
// caller. This function should delete intermediate object file once its content
- // is brought to memory. Return NULL if the compilation was not successful.
- //
+ // is brought to memory. Return NULL if the compilation was not successful.
const void *compile(size_t *length,
bool disableOpt,
bool disableInline,
bool disableGVNLoadPRE,
std::string &errMsg);
+ void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
+
private:
void initializeLTOPasses();
@@ -133,6 +133,10 @@ private:
llvm::Mangler &Mangler);
bool determineTarget(std::string &errMsg);
+ static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context);
+
+ void DiagnosticHandler2(const llvm::DiagnosticInfo &DI);
+
typedef llvm::StringMap<uint8_t> StringSet;
llvm::LLVMContext &Context;
@@ -148,6 +152,8 @@ private:
std::string MCpu;
std::string NativeObjectPath;
llvm::TargetOptions Options;
+ lto_diagnostic_handler_t DiagHandler;
+ void *DiagContext;
};
#endif // LTO_CODE_GENERATOR_H
diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h
index f4693c8..1e4fa1b 100644
--- a/include/llvm/LTO/LTOModule.h
+++ b/include/llvm/LTO/LTOModule.h
@@ -15,11 +15,11 @@
#define LTO_MODULE_H
#include "llvm-c/lto.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/Target/Mangler.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/Target/TargetMachine.h"
#include <string>
#include <vector>
@@ -47,8 +47,12 @@ private:
const llvm::GlobalValue *symbol;
};
- llvm::OwningPtr<llvm::Module> _module;
- llvm::OwningPtr<llvm::TargetMachine> _target;
+ std::unique_ptr<llvm::Module> _module;
+ std::unique_ptr<llvm::TargetMachine> _target;
+ llvm::MCObjectFileInfo ObjFileInfo;
+ StringSet _linkeropt_strings;
+ std::vector<const char *> _deplibs;
+ std::vector<const char *> _linkeropts;
std::vector<NameAndAttributes> _symbols;
// _defines and _undefines only needed to disambiguate tentative definitions
@@ -95,7 +99,8 @@ public:
std::string& errMsg);
static LTOModule *makeLTOModule(const void *mem, size_t length,
llvm::TargetOptions options,
- std::string &errMsg);
+ std::string &errMsg,
+ llvm::StringRef path = "");
/// getTargetTriple - Return the Module's target triple.
const char *getTargetTriple() {
@@ -127,6 +132,30 @@ public:
return NULL;
}
+ /// getDependentLibraryCount - Get the number of dependent libraries
+ uint32_t getDependentLibraryCount() {
+ return _deplibs.size();
+ }
+
+ /// getDependentLibrary - Get the dependent library at the specified index.
+ const char *getDependentLibrary(uint32_t index) {
+ if (index < _deplibs.size())
+ return _deplibs[index];
+ return NULL;
+ }
+
+ /// getLinkerOptCount - Get the number of linker options
+ uint32_t getLinkerOptCount() {
+ return _linkeropts.size();
+ }
+
+ /// getLinkerOpt - Get the linker option at the specified index.
+ const char *getLinkerOpt(uint32_t index) {
+ if (index < _linkeropts.size())
+ return _linkeropts[index];
+ return NULL;
+ }
+
/// getLLVVMModule - Return the Module.
llvm::Module *getLLVVMModule() { return _module.get(); }
@@ -136,6 +165,10 @@ public:
}
private:
+ /// parseMetadata - Parse metadata from the module
+ // FIXME: it only parses "Linker Options" metadata at the moment
+ void parseMetadata();
+
/// parseSymbols - Parse the symbols from the module and model-level ASM and
/// add them to either the defined or undefined lists.
bool parseSymbols(std::string &errMsg);
@@ -189,8 +222,9 @@ private:
llvm::TargetOptions options,
std::string &errMsg);
- /// makeBuffer - Create a MemoryBuffer from a memory range.
- static llvm::MemoryBuffer *makeBuffer(const void *mem, size_t length);
+ /// Create a MemoryBuffer from a memory range with an optional name.
+ static llvm::MemoryBuffer *makeBuffer(const void *mem, size_t length,
+ llvm::StringRef name = "");
};
#endif // LTO_MODULE_H
diff --git a/include/llvm/LineEditor/LineEditor.h b/include/llvm/LineEditor/LineEditor.h
new file mode 100644
index 0000000..42839ed
--- /dev/null
+++ b/include/llvm/LineEditor/LineEditor.h
@@ -0,0 +1,153 @@
+//===-- llvm/LineEditor/LineEditor.h - line editor --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINEEDITOR_LINEEDITOR_H
+#define LLVM_LINEEDITOR_LINEEDITOR_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class LineEditor {
+public:
+ /// Create a LineEditor object.
+ ///
+ /// \param ProgName The name of the current program. Used to form a default
+ /// prompt.
+ /// \param HistoryPath Path to the file in which to store history data, if
+ /// possible.
+ /// \param In The input stream used by the editor.
+ /// \param Out The output stream used by the editor.
+ /// \param Err The error stream used by the editor.
+ LineEditor(StringRef ProgName, StringRef HistoryPath = "", FILE *In = stdin,
+ FILE *Out = stdout, FILE *Err = stderr);
+ ~LineEditor();
+
+ /// Reads a line.
+ ///
+ /// \return The line, or llvm::Optional<std::string>() on EOF.
+ llvm::Optional<std::string> readLine() const;
+
+ void saveHistory();
+ void loadHistory();
+
+ static std::string getDefaultHistoryPath(StringRef ProgName);
+
+ /// The action to perform upon a completion request.
+ struct CompletionAction {
+ enum ActionKind {
+ /// Insert Text at the cursor position.
+ AK_Insert,
+ /// Show Completions, or beep if the list is empty.
+ AK_ShowCompletions
+ };
+
+ ActionKind Kind;
+
+ /// The text to insert.
+ std::string Text;
+
+ /// The list of completions to show.
+ std::vector<std::string> Completions;
+ };
+
+ /// A possible completion at a given cursor position.
+ struct Completion {
+ Completion() {}
+ Completion(const std::string &TypedText, const std::string &DisplayText)
+ : TypedText(TypedText), DisplayText(DisplayText) {}
+
+ /// The text to insert. If the user has already input some of the
+ /// completion, this should only include the rest of the text.
+ std::string TypedText;
+
+ /// A description of this completion. This may be the completion itself, or
+ /// maybe a summary of its type or arguments.
+ std::string DisplayText;
+ };
+
+ /// Set the completer for this LineEditor. A completer is a function object
+ /// which takes arguments of type StringRef (the string to complete) and
+ /// size_t (the zero-based cursor position in the StringRef) and returns a
+ /// CompletionAction.
+ template <typename T> void setCompleter(T Comp) {
+ Completer.reset(new CompleterModel<T>(Comp));
+ }
+
+ /// Set the completer for this LineEditor to the given list completer.
+ /// A list completer is a function object which takes arguments of type
+ /// StringRef (the string to complete) and size_t (the zero-based cursor
+ /// position in the StringRef) and returns a std::vector<Completion>.
+ template <typename T> void setListCompleter(T Comp) {
+ Completer.reset(new ListCompleterModel<T>(Comp));
+ }
+
+ /// Use the current completer to produce a CompletionAction for the given
+ /// completion request. If the current completer is a list completer, this
+ /// will return an AK_Insert CompletionAction if each completion has a common
+ /// prefix, or an AK_ShowCompletions CompletionAction otherwise.
+ ///
+ /// \param Buffer The string to complete
+ /// \param Pos The zero-based cursor position in the StringRef
+ CompletionAction getCompletionAction(StringRef Buffer, size_t Pos) const;
+
+ const std::string &getPrompt() const { return Prompt; }
+ void setPrompt(const std::string &P) { Prompt = P; }
+
+ // Public so callbacks in LineEditor.cpp can use it.
+ struct InternalData;
+
+private:
+ std::string Prompt;
+ std::string HistoryPath;
+ std::unique_ptr<InternalData> Data;
+
+ struct CompleterConcept {
+ virtual ~CompleterConcept();
+ virtual CompletionAction complete(StringRef Buffer, size_t Pos) const = 0;
+ };
+
+ struct ListCompleterConcept : CompleterConcept {
+ ~ListCompleterConcept();
+ CompletionAction complete(StringRef Buffer, size_t Pos) const override;
+ static std::string getCommonPrefix(const std::vector<Completion> &Comps);
+ virtual std::vector<Completion> getCompletions(StringRef Buffer,
+ size_t Pos) const = 0;
+ };
+
+ template <typename T>
+ struct CompleterModel : CompleterConcept {
+ CompleterModel(T Value) : Value(Value) {}
+ CompletionAction complete(StringRef Buffer, size_t Pos) const override {
+ return Value(Buffer, Pos);
+ }
+ T Value;
+ };
+
+ template <typename T>
+ struct ListCompleterModel : ListCompleterConcept {
+ ListCompleterModel(T Value) : Value(Value) {}
+ std::vector<Completion> getCompletions(StringRef Buffer,
+ size_t Pos) const override {
+ return Value(Buffer, Pos);
+ }
+ T Value;
+ };
+
+ std::unique_ptr<const CompleterConcept> Completer;
+};
+
+}
+
+#endif
diff --git a/include/llvm/LinkAllIR.h b/include/llvm/LinkAllIR.h
index 4c1aaca..2b0604a 100644
--- a/include/llvm/LinkAllIR.h
+++ b/include/llvm/LinkAllIR.h
@@ -16,12 +16,12 @@
#ifndef LLVM_LINKALLIR_H
#define LLVM_LINKALLIR_H
-#include "llvm/Analysis/Verifier.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MathExtras.h"
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 8183fa2..1603250 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -26,9 +26,9 @@
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/RegionPrinter.h"
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/ObjCARC.h"
@@ -129,6 +129,7 @@ namespace {
(void) llvm::createJumpThreadingPass();
(void) llvm::createUnifyFunctionExitNodesPass();
(void) llvm::createInstCountPass();
+ (void) llvm::createConstantHoistingPass();
(void) llvm::createCodeGenPreparePass();
(void) llvm::createEarlyCSEPass();
(void) llvm::createGVNPass();
@@ -139,9 +140,9 @@ namespace {
(void) llvm::createMetaRenamerPass();
(void) llvm::createFunctionAttrsPass();
(void) llvm::createMergeFunctionsPass();
- (void) llvm::createPrintModulePass(0);
- (void) llvm::createPrintFunctionPass("", 0);
- (void) llvm::createPrintBasicBlockPass(0);
+ (void) llvm::createPrintModulePass(*(llvm::raw_ostream*)0);
+ (void) llvm::createPrintFunctionPass(*(llvm::raw_ostream*)0);
+ (void) llvm::createPrintBasicBlockPass(*(llvm::raw_ostream*)0);
(void) llvm::createModuleDebugInfoPrinterPass();
(void) llvm::createPartialInliningPass();
(void) llvm::createLintPass();
@@ -154,6 +155,7 @@ namespace {
(void) llvm::createSLPVectorizerPass();
(void) llvm::createBBVectorizePass();
(void) llvm::createPartiallyInlineLibCallsPass();
+ (void) llvm::createScalarizerPass();
(void)new llvm::IntervalPartition();
(void)new llvm::FindUsedTypes();
diff --git a/include/llvm/Linker.h b/include/llvm/Linker/Linker.h
index 4f37459..42b2cb3 100644
--- a/include/llvm/Linker.h
+++ b/include/llvm/Linker/Linker.h
@@ -1,4 +1,4 @@
-//===- llvm/Linker.h - Module Linker Interface ------------------*- C++ -*-===//
+//===- Linker.h - Module Linker Interface -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LINKER_H
-#define LLVM_LINKER_H
+#ifndef LLVM_LINKER_LINKER_H
+#define LLVM_LINKER_LINKER_H
#include "llvm/ADT/SmallPtrSet.h"
#include <string>
@@ -30,7 +30,7 @@ class Linker {
PreserveSource = 1 // Preserve the source module.
};
- Linker(Module *M);
+ Linker(Module *M, bool SuppressWarnings=false);
~Linker();
Module *getModule() const { return Composite; }
@@ -52,6 +52,8 @@ class Linker {
private:
Module *Composite;
SmallPtrSet<StructType*, 32> IdentifiedStructTypes;
+
+ bool SuppressWarnings;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index f946f41..82b65fd 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -38,7 +38,6 @@ class MCAsmBackend {
protected: // Can only create subclasses.
MCAsmBackend();
- unsigned HasReliableSymbolDifference : 1;
unsigned HasDataInCodeSupport : 1;
public:
@@ -58,20 +57,6 @@ public:
"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;
- }
-
/// hasDataInCodeSupport - Check whether this target implements data-in-code
/// markers. If not, data region directives will be ignored.
bool hasDataInCodeSupport() const { return HasDataInCodeSupport; }
@@ -105,16 +90,14 @@ public:
virtual void processFixupValue(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
- MCValue &Target, uint64_t &Value,
+ const MCValue &Target, uint64_t &Value,
bool &IsResolved) {}
- /// @}
-
/// applyFixup - Apply the \p Value for given \p Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
- uint64_t Value) const = 0;
+ uint64_t Value, bool IsPCRel) const = 0;
/// @}
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 7a99394..037a24f 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -82,7 +82,7 @@ namespace llvm {
/// 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.
+ /// 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,
@@ -101,10 +101,6 @@ namespace llvm {
/// 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 "#"
@@ -115,19 +111,17 @@ namespace llvm {
/// LabelSuffix - This is appended to emitted labels.
const char *DebugLabelSuffix; // Defaults to ":"
- /// GlobalPrefix - If this is set to a non-empty string, it is prepended
- /// onto all global symbols. This is often used for "_" or ".".
- const char *GlobalPrefix; // Defaults to ""
-
- /// 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 "."
+ /// 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.
+ const char *PrivateGlobalPrefix; // Defaults to "L"
- /// 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 ""
+ /// 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.
+ /// The default of "" meast that for this system a plain private symbol
+ /// should be used.
+ const char *LinkerPrivateGlobalPrefix; // Defaults to "".
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
/// emit before and after an inline assembly statement.
@@ -198,20 +192,10 @@ namespace llvm {
/// 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.
-
bool NeedsDwarfSectionOffsetDirective;
//===--- 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
@@ -266,13 +250,16 @@ namespace llvm {
/// 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.
+ /// True if we have a directive to declare a global as being a weak
+ /// defined symbol.
+ bool HasWeakDefDirective; // Defaults to false.
- /// 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.
+ /// True if we have a directive to declare a global as being a weak
+ /// defined symbol that can be hidden (unexported).
+ bool HasWeakDefCanBeHiddenDirective; // Defaults to false.
+
+ /// True if we have a .linkonce directive. This is used on cygwin/mingw.
+ bool HasLinkOnceDirective; // Defaults to false.
/// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to
/// declare a symbol as having hidden visibility.
@@ -303,22 +290,37 @@ namespace llvm {
/// uses relocations for references to other .debug_* sections.
bool DwarfUsesRelocationsAcrossSections;
+ /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference
+ /// relocations should be replaced by an absolute difference.
+ bool DwarfFDESymbolsUseAbsDiff;
+
/// DwarfRegNumForCFI - True if dwarf register numbers are printed
/// instead of symbolic register names in .cfi_* directives.
bool DwarfRegNumForCFI; // Defaults to false;
+ /// UseParensForSymbolVariant - True if target uses parens to indicate the
+ /// symbol variant instead of @. For example, foo(plt) instead of foo@plt.
+ bool UseParensForSymbolVariant; // Defaults to false;
+
//===--- Prologue State ----------------------------------------------===//
std::vector<MCCFIInstruction> InitialFrameState;
+ //===--- Integrated Assembler State ----------------------------------===//
+ /// Should we use the integrated assembler?
+ /// The integrated assembler should be enabled by default (by the
+ /// constructors) when failing to parse a valid piece of assembly (inline
+ /// or otherwise) is considered a bug. It may then be overridden after
+ /// construction (see LLVMTargetMachine::initAsmInfo()).
+ bool UseIntegratedAssembler;
+
+ /// Compress DWARF debug sections. Defaults to false.
+ bool CompressDebugSections;
+
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
- // FIXME: move these methods to DwarfPrinter when the JIT stops using them.
- static unsigned getSLEB128Size(int64_t Value);
- static unsigned getULEB128Size(uint64_t Value);
-
/// getPointerSize - Get the pointer size in bytes.
unsigned getPointerSize() const {
return PointerSize;
@@ -371,7 +373,7 @@ namespace llvm {
unsigned Encoding,
MCStreamer &Streamer) const;
- const MCExpr *
+ virtual const MCExpr *
getExprForFDESymbol(const MCSymbol *Sym,
unsigned Encoding,
MCStreamer &Streamer) const;
@@ -384,10 +386,6 @@ namespace llvm {
return UsesELFSectionDirectiveForBSS;
}
- bool hasMicrosoftFastStdCallMangling() const {
- return HasMicrosoftFastStdCallMangling;
- }
-
bool needsDwarfSectionOffsetDirective() const {
return NeedsDwarfSectionOffsetDirective;
}
@@ -414,9 +412,13 @@ namespace llvm {
const char *getSeparatorString() const {
return SeparatorString;
}
+
+ /// This indicates the column (zero-based) at which asm comments should be
+ /// printed.
unsigned getCommentColumn() const {
- return CommentColumn;
+ return 40;
}
+
const char *getCommentString() const {
return CommentString;
}
@@ -427,15 +429,16 @@ namespace llvm {
const char *getDebugLabelSuffix() const {
return DebugLabelSuffix;
}
-
- const char *getGlobalPrefix() const {
- return GlobalPrefix;
- }
const char *getPrivateGlobalPrefix() const {
return PrivateGlobalPrefix;
}
+ bool hasLinkerPrivateGlobalPrefix() const {
+ return LinkerPrivateGlobalPrefix[0] != '\0';
+ }
const char *getLinkerPrivateGlobalPrefix() const {
- return LinkerPrivateGlobalPrefix;
+ if (hasLinkerPrivateGlobalPrefix())
+ return LinkerPrivateGlobalPrefix;
+ return getPrivateGlobalPrefix();
}
const char *getInlineAsmStart() const {
return InlineAsmStart;
@@ -470,9 +473,6 @@ namespace llvm {
const char *getAscizDirective() const {
return AscizDirective;
}
- const char *getAlignDirective() const {
- return AlignDirective;
- }
bool getAlignmentIsInBytes() const {
return AlignmentIsInBytes;
}
@@ -497,8 +497,11 @@ namespace llvm {
bool hasIdentDirective() const { return HasIdentDirective; }
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
const char *getWeakRefDirective() const { return WeakRefDirective; }
- const char *getWeakDefDirective() const { return WeakDefDirective; }
- const char *getLinkOnceDirective() const { return LinkOnceDirective; }
+ bool hasWeakDefDirective() const { return HasWeakDefDirective; }
+ bool hasWeakDefCanBeHiddenDirective() const {
+ return HasWeakDefCanBeHiddenDirective;
+ }
+ bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;}
MCSymbolAttr getHiddenDeclarationVisibilityAttr() const {
@@ -528,9 +531,15 @@ namespace llvm {
bool doesDwarfUseRelocationsAcrossSections() const {
return DwarfUsesRelocationsAcrossSections;
}
+ bool doDwarfFDESymbolsUseAbsDiff() const {
+ return DwarfFDESymbolsUseAbsDiff;
+ }
bool useDwarfRegNumForCFI() const {
return DwarfRegNumForCFI;
}
+ bool useParensForSymbolVariant() const {
+ return UseParensForSymbolVariant;
+ }
void addInitialFrameState(const MCCFIInstruction &Inst) {
InitialFrameState.push_back(Inst);
@@ -539,6 +548,20 @@ namespace llvm {
const std::vector<MCCFIInstruction> &getInitialFrameState() const {
return InitialFrameState;
}
+
+ /// Return true if assembly (inline or otherwise) should be parsed.
+ bool useIntegratedAssembler() const { return UseIntegratedAssembler; }
+
+ /// Set whether assembly (inline or otherwise) should be parsed.
+ virtual void setUseIntegratedAssembler(bool Value) {
+ UseIntegratedAssembler = Value;
+ }
+
+ bool compressDebugSections() const { return CompressDebugSections; }
+
+ void setCompressDebugSections(bool CompressDebugSections) {
+ this->CompressDebugSections = CompressDebugSections;
+ }
};
}
diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h
index 7286151..56444f3 100644
--- a/include/llvm/MC/MCAsmInfoCOFF.h
+++ b/include/llvm/MC/MCAsmInfoCOFF.h
@@ -20,13 +20,13 @@ namespace llvm {
};
class MCAsmInfoMicrosoft : public MCAsmInfoCOFF {
- virtual void anchor();
+ void anchor() override;
protected:
explicit MCAsmInfoMicrosoft();
};
class MCAsmInfoGNUCOFF : public MCAsmInfoCOFF {
- virtual void anchor();
+ void anchor() override;
protected:
explicit MCAsmInfoGNUCOFF();
};
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 0cf2b1d..34b760c 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -15,17 +15,16 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <algorithm>
#include <vector> // FIXME: Shouldn't be needed.
-namespace mcld {
-class Layout;
-}
-
namespace llvm {
class raw_ostream;
class MCAsmLayout;
@@ -37,6 +36,7 @@ class MCFragment;
class MCObjectWriter;
class MCSection;
class MCSectionData;
+class MCSubtargetInfo;
class MCSymbol;
class MCSymbolData;
class MCValue;
@@ -44,7 +44,6 @@ class MCAsmBackend;
class MCFragment : public ilist_node<MCFragment> {
friend class MCAsmLayout;
- friend class mcld::Layout;
MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
@@ -53,16 +52,14 @@ public:
enum FragmentType {
FT_Align,
FT_Data,
+ FT_Compressed,
FT_CompactEncodedInst,
FT_Fill,
FT_Relaxable,
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
- FT_LEB,
- FT_Region,
- FT_Reloc,
- FT_Target
+ FT_LEB
};
private:
@@ -72,8 +69,7 @@ private:
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().
+ /// symbol.
MCSymbolData *Atom;
/// @name Assembler Backend Data
@@ -151,11 +147,11 @@ public:
virtual SmallVectorImpl<char> &getContents() = 0;
virtual const SmallVectorImpl<char> &getContents() const = 0;
- virtual uint8_t getBundlePadding() const {
+ uint8_t getBundlePadding() const override {
return BundlePadding;
}
- virtual void setBundlePadding(uint8_t N) {
+ void setBundlePadding(uint8_t N) override {
BundlePadding = N;
}
@@ -166,6 +162,7 @@ public:
return false;
case MCFragment::FT_Relaxable:
case MCFragment::FT_CompactEncodedInst:
+ case MCFragment::FT_Compressed:
case MCFragment::FT_Data:
return true;
}
@@ -176,7 +173,7 @@ public:
/// data and also have fixups registered.
///
class MCEncodedFragmentWithFixups : public MCEncodedFragment {
- virtual void anchor();
+ void anchor() override;
public:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
@@ -200,14 +197,15 @@ public:
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
- return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
+ return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
+ Kind == MCFragment::FT_Compressed;
}
};
/// Fragment for data and encoded instructions.
///
class MCDataFragment : public MCEncodedFragmentWithFixups {
- virtual void anchor();
+ void anchor() override;
/// \brief Does this fragment contain encoded instructions anywhere in it?
bool HasInstructions;
@@ -219,6 +217,11 @@ class MCDataFragment : public MCEncodedFragmentWithFixups {
/// Fixups - The list of fixups in this fragment.
SmallVector<MCFixup, 4> Fixups;
+protected:
+ MCDataFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+ : MCEncodedFragmentWithFixups(FType, SD), HasInstructions(false),
+ AlignToBundleEnd(false) {}
+
public:
MCDataFragment(MCSectionData *SD = 0)
: MCEncodedFragmentWithFixups(FT_Data, SD),
@@ -226,41 +229,54 @@ public:
{
}
- virtual SmallVectorImpl<char> &getContents() { return Contents; }
- virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+ SmallVectorImpl<char> &getContents() override { return Contents; }
+ const SmallVectorImpl<char> &getContents() const override {
+ return Contents;
+ }
- SmallVectorImpl<MCFixup> &getFixups() {
+ SmallVectorImpl<MCFixup> &getFixups() override {
return Fixups;
}
- const SmallVectorImpl<MCFixup> &getFixups() const {
+ const SmallVectorImpl<MCFixup> &getFixups() const override {
return Fixups;
}
- virtual bool hasInstructions() const { return HasInstructions; }
+ bool hasInstructions() const override { return HasInstructions; }
virtual void setHasInstructions(bool V) { HasInstructions = V; }
- virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
- virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+ bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
- fixup_iterator fixup_begin() { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+ fixup_iterator fixup_begin() override { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
- fixup_iterator fixup_end() {return Fixups.end();}
- const_fixup_iterator fixup_end() const {return Fixups.end();}
+ fixup_iterator fixup_end() override {return Fixups.end();}
+ const_fixup_iterator fixup_end() const override {return Fixups.end();}
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Data;
+ return F->getKind() == MCFragment::FT_Data ||
+ F->getKind() == MCFragment::FT_Compressed;
}
};
+class MCCompressedFragment: public MCDataFragment {
+ mutable SmallVector<char, 32> CompressedContents;
+public:
+ MCCompressedFragment(MCSectionData *SD = nullptr)
+ : MCDataFragment(FT_Compressed, SD) {}
+ const SmallVectorImpl<char> &getCompressedContents() const;
+ using MCDataFragment::getContents;
+ SmallVectorImpl<char> &getContents() override;
+};
+
/// This is a compact (memory-size-wise) fragment for holding an encoded
/// instruction (non-relaxable) that has no fixups registered. When applicable,
/// it can be used instead of MCDataFragment and lead to lower memory
/// consumption.
///
class MCCompactEncodedInstFragment : public MCEncodedFragment {
- virtual void anchor();
+ void anchor() override;
/// \brief Should this fragment be aligned to the end of a bundle?
bool AlignToBundleEnd;
@@ -272,15 +288,15 @@ public:
{
}
- virtual bool hasInstructions() const {
+ bool hasInstructions() const override {
return true;
}
- virtual SmallVectorImpl<char> &getContents() { return Contents; }
- virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+ SmallVectorImpl<char> &getContents() override { return Contents; }
+ const SmallVectorImpl<char> &getContents() const override { return Contents; }
- virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
- virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+ bool alignToBundleEnd() const override { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_CompactEncodedInst;
@@ -291,11 +307,16 @@ public:
/// relaxed during the assembler layout and relaxation stage.
///
class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
- virtual void anchor();
+ void anchor() override;
/// Inst - The instruction this is a fragment for.
MCInst Inst;
+ /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
+ /// Keep a copy instead of a reference to make sure that updates to STI
+ /// in the assembler are not seen here.
+ const MCSubtargetInfo STI;
+
/// Contents - Binary data for the currently encoded instruction.
SmallVector<char, 8> Contents;
@@ -303,31 +324,35 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
SmallVector<MCFixup, 1> Fixups;
public:
- MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
- : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
+ MCRelaxableFragment(const MCInst &_Inst,
+ const MCSubtargetInfo &_STI,
+ MCSectionData *SD = 0)
+ : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
}
- virtual SmallVectorImpl<char> &getContents() { return Contents; }
- virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+ SmallVectorImpl<char> &getContents() override { return Contents; }
+ const SmallVectorImpl<char> &getContents() const override { return Contents; }
const MCInst &getInst() const { return Inst; }
void setInst(const MCInst& Value) { Inst = Value; }
- SmallVectorImpl<MCFixup> &getFixups() {
+ const MCSubtargetInfo &getSubtargetInfo() { return STI; }
+
+ SmallVectorImpl<MCFixup> &getFixups() override {
return Fixups;
}
- const SmallVectorImpl<MCFixup> &getFixups() const {
+ const SmallVectorImpl<MCFixup> &getFixups() const override {
return Fixups;
}
- virtual bool hasInstructions() const { return true; }
+ bool hasInstructions() const override { return true; }
- fixup_iterator fixup_begin() { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
+ fixup_iterator fixup_begin() override { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
- fixup_iterator fixup_end() {return Fixups.end();}
- const_fixup_iterator fixup_end() const {return Fixups.end();}
+ fixup_iterator fixup_end() override {return Fixups.end();}
+ const_fixup_iterator fixup_end() const override {return Fixups.end();}
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Relaxable;
@@ -836,6 +861,15 @@ public:
const_data_region_iterator;
typedef std::vector<DataRegionData>::iterator data_region_iterator;
+ /// MachO specific deployment target version info.
+ // A Major version of 0 indicates that no version information was supplied
+ // and so the corresponding load command should not be emitted.
+ typedef struct {
+ MCVersionMinType Kind;
+ unsigned Major;
+ unsigned Minor;
+ unsigned Update;
+ } VersionMinInfoType;
private:
MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
@@ -846,7 +880,7 @@ private:
MCCodeEmitter &Emitter;
- MCObjectWriter *Writer;
+ MCObjectWriter &Writer;
raw_ostream &OS;
@@ -898,6 +932,12 @@ private:
// Access to the flags is necessary in cases where assembler directives affect
// which flags to be set.
unsigned ELFHeaderEFlags;
+
+ /// Used to communicate Linker Optimization Hint information between
+ /// the Streamer and the .o writer
+ MCLOHContainer LOHContainer;
+
+ VersionMinInfoType VersionMinInfo;
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
@@ -944,8 +984,8 @@ private:
/// finishLayout - Finalize a layout, including fragment lowering.
void finishLayout(MCAsmLayout &Layout);
- uint64_t handleFixup(const MCAsmLayout &Layout,
- MCFragment &F, const MCFixup &Fixup);
+ std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
+ MCFragment &F, const MCFixup &Fixup);
public:
/// Compute the effective fragment size assuming it is laid out at the given
@@ -979,6 +1019,16 @@ public:
unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+ /// MachO deployment target version information.
+ const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
+ void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+ unsigned Update) {
+ VersionMinInfo.Kind = Kind;
+ VersionMinInfo.Major = Major;
+ VersionMinInfo.Minor = Minor;
+ VersionMinInfo.Update = Update;
+ }
+
public:
/// Construct a new assembler instance.
///
@@ -1003,9 +1053,7 @@ public:
MCCodeEmitter &getEmitter() const { return Emitter; }
- MCObjectWriter &getWriter() const { return *Writer; }
-
- void setWriter(MCObjectWriter &ObjectWriter);
+ MCObjectWriter &getWriter() const { return Writer; }
/// Finish - Do final processing and write the object to the output stream.
/// \p Writer is used for custom object writer (as the MCJIT does),
@@ -1132,6 +1180,19 @@ public:
size_t data_region_size() const { return DataRegions.size(); }
/// @}
+ /// @name Data Region 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.
+ MCLOHContainer & getLOHContainer() {
+ return LOHContainer;
+ }
+ const MCLOHContainer & getLOHContainer() const {
+ return const_cast<MCAssembler *>(this)->getLOHContainer();
+ }
+ /// @}
/// @name Backend Data Access
/// @{
@@ -1152,6 +1213,10 @@ public:
return *Entry;
}
+ bool hasSymbolData(const MCSymbol &Symbol) const {
+ return SymbolMap.lookup(&Symbol) != 0;
+ }
+
MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
assert(Entry && "Missing symbol data!");
diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h
index eab32d6..e9d0fba 100644
--- a/include/llvm/MC/MCAtom.h
+++ b/include/llvm/MC/MCAtom.h
@@ -145,8 +145,8 @@ public:
/// \name Atom type specific split/truncate logic.
/// @{
- MCTextAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
- void truncate(uint64_t TruncPt) LLVM_OVERRIDE;
+ MCTextAtom *split(uint64_t SplitPt) override;
+ void truncate(uint64_t TruncPt) override;
/// @}
// Class hierarchy.
@@ -179,8 +179,8 @@ public:
/// \name Atom type specific split/truncate logic.
/// @{
- MCDataAtom *split(uint64_t SplitPt) LLVM_OVERRIDE;
- void truncate(uint64_t TruncPt) LLVM_OVERRIDE;
+ MCDataAtom *split(uint64_t SplitPt) override;
+ void truncate(uint64_t TruncPt) override;
/// @}
// Class hierarchy.
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index 9bfa08e..d3b5617 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -15,6 +15,7 @@
namespace llvm {
class MCFixup;
class MCInst;
+class MCSubtargetInfo;
class raw_ostream;
template<typename T> class SmallVectorImpl;
@@ -35,7 +36,8 @@ public:
/// EncodeInstruction - Encode the given \p Inst to bytes on the output
/// stream \p OS.
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups) const = 0;
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const = 0;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index c8b6626..9091ed9 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -28,7 +28,7 @@ namespace llvm {
class MCSection;
class MCSymbol;
class MCLabel;
- class MCDwarfFile;
+ struct MCDwarfFile;
class MCDwarfLoc;
class MCObjectFileInfo;
class MCRegisterInfo;
@@ -70,6 +70,14 @@ namespace llvm {
/// Symbols - Bindings of names to symbols.
SymbolTable Symbols;
+ /// A maping from a local label number and an instance count to a symbol.
+ /// For example, in the assembly
+ /// 1:
+ /// 2:
+ /// 1:
+ /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1)
+ DenseMap<std::pair<unsigned, unsigned>, MCSymbol*> LocalSymbols;
+
/// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols.
StringMap<bool, BumpPtrAllocator&> UsedNames;
@@ -82,10 +90,10 @@ namespace llvm {
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);
+ unsigned NextInstance(unsigned 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);
+ unsigned GetInstance(unsigned 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
@@ -108,9 +116,7 @@ namespace llvm {
/// We now emit a line table for each compile unit. To reduce the prologue
/// size of each line table, the files and directories used by each compile
/// unit are separated.
- typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap;
- MCDwarfFilesMap MCDwarfFilesCUMap;
- std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;
+ std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap;
/// The current dwarf line information from the last dwarf .loc directive.
MCDwarfLoc CurrentDwarfLoc;
@@ -146,16 +152,8 @@ namespace llvm {
/// 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;
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID;
- /// The line table start symbol for each Compile Unit.
- DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
@@ -164,6 +162,9 @@ namespace llvm {
MCSymbol *CreateSymbol(StringRef Name);
+ MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
+ unsigned Instance);
+
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
@@ -192,6 +193,10 @@ namespace llvm {
/// @name Symbol Management
/// @{
+ /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
+ /// symbol with a unique but unspecified name.
+ MCSymbol *CreateLinkerPrivateTempSymbol();
+
/// CreateTempSymbol - Create and return a new assembler temporary symbol
/// with a unique but unspecified name.
MCSymbol *CreateTempSymbol();
@@ -200,13 +205,13 @@ namespace llvm {
/// symbol names.
unsigned getUniqueSymbolID() { return NextUniqueID++; }
- /// CreateDirectionalLocalSymbol - Create the definition of a directional
- /// local symbol for numbered label (used for "1:" definitions).
- MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
+ /// Create the definition of a directional local symbol for numbered label
+ /// (used for "1:" definitions).
+ MCSymbol *CreateDirectionalLocalSymbol(unsigned 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);
+ /// Create and return a directional local symbol for numbered label (used
+ /// for "1b" or 1f" references).
+ MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before);
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @p Name. If it exists, return it. If not, create a forward
@@ -278,6 +283,7 @@ namespace llvm {
/// This can be overridden by clients which want to control the reported
/// compilation directory and have it be something other than the current
/// working directory.
+ /// Returns an empty string if the current directory cannot be determined.
StringRef getCompilationDir() const { return CompilationDir; }
/// \brief Set the compilation directory for DW_AT_comp_dir
@@ -290,7 +296,7 @@ namespace llvm {
const std::string &getMainFileName() const { return MainFileName; }
/// \brief Set the main file name and override the default.
- void setMainFileName(StringRef S) { MainFileName = S.str(); }
+ void setMainFileName(StringRef S) { MainFileName = S; }
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
@@ -300,31 +306,38 @@ namespace llvm {
bool hasDwarfFiles() const {
// Traverse MCDwarfFilesCUMap and check whether each entry is empty.
- MCDwarfFilesMap::const_iterator MapB, MapE;
- for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end();
- MapB != MapE; MapB++)
- if (!MapB->second.empty())
+ for (const auto &FileTable : MCDwarfLineTablesCUMap)
+ if (!FileTable.second.getMCDwarfFiles().empty())
return true;
return false;
}
- const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
- return MCDwarfFilesCUMap[CUID];
+ const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const {
+ return MCDwarfLineTablesCUMap;
}
- const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
- return MCDwarfDirsCUMap[CUID];
+
+ MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) {
+ return MCDwarfLineTablesCUMap[CUID];
}
- const DenseMap<const MCSection *, MCLineSection *>
- &getMCLineSections() const {
- return MCLineSections;
+ const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const {
+ auto I = MCDwarfLineTablesCUMap.find(CUID);
+ assert(I != MCDwarfLineTablesCUMap.end());
+ return I->second;
}
- const std::vector<const MCSection *> &getMCLineSectionOrder() const {
- return MCLineSectionOrder;
+
+ const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) {
+ return getMCDwarfLineTable(CUID).getMCDwarfFiles();
}
- void addMCLineSection(const MCSection *Sec, MCLineSection *Line) {
- MCLineSections[Sec] = Line;
- MCLineSectionOrder.push_back(Sec);
+ const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
+ return getMCDwarfLineTable(CUID).getMCDwarfDirs();
+ }
+
+ bool hasMCLineSections() const {
+ for (const auto &Table : MCDwarfLineTablesCUMap)
+ if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
+ return true;
+ return false;
}
unsigned getDwarfCompileUnitID() {
return DwarfCompileUnitID;
@@ -332,18 +345,8 @@ namespace llvm {
void setDwarfCompileUnitID(unsigned CUIndex) {
DwarfCompileUnitID = CUIndex;
}
- const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
- return MCLineTableSymbols;
- }
- MCSymbol *getMCLineTableSymbol(unsigned ID) const {
- DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
- MCLineTableSymbols.find(ID);
- if (CIter == MCLineTableSymbols.end())
- return NULL;
- return CIter->second;
- }
- void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
- MCLineTableSymbols[ID] = Sym;
+ void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) {
+ getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
/// setCurrentDwarfLoc - saves the information from the currently parsed
@@ -369,7 +372,9 @@ namespace llvm {
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
- unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; }
+ void setGenDwarfFileNumber(unsigned FileNumber) {
+ GenDwarfFileNumber = FileNumber;
+ }
const MCSection *getGenDwarfSection() { return GenDwarfSection; }
void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h
index 0461766..f9d66e0 100644
--- a/include/llvm/MC/MCDirectives.h
+++ b/include/llvm/MC/MCDirectives.h
@@ -60,6 +60,11 @@ enum MCDataRegionType {
MCDR_DataRegionEnd ///< .end_data_region
};
+enum MCVersionMinType {
+ MCVM_IOSVersionMin, ///< .ios_version_min
+ MCVM_OSXVersionMin ///< .macosx_version_min
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 83f26ef..d545fc7 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -11,8 +11,8 @@
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/MC/MCSymbolizer.h"
#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm/MC/MCSymbolizer.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -56,10 +56,9 @@ public:
};
/// Constructor - Performs initial setup for the disassembler.
- MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0),
- DisInfo(0), Ctx(0),
- STI(STI), Symbolizer(0),
- CommentStream(0) {}
+ MCDisassembler(const MCSubtargetInfo &STI)
+ : GetOpInfo(0), SymbolLookUp(0), DisInfo(0), Ctx(0), STI(STI),
+ Symbolizer(), CommentStream(0) {}
virtual ~MCDisassembler();
@@ -102,7 +101,7 @@ private:
protected:
// Subtarget information, for instruction decoding predicates if required.
const MCSubtargetInfo &STI;
- OwningPtr<MCSymbolizer> Symbolizer;
+ std::unique_ptr<MCSymbolizer> Symbolizer;
public:
// Helpers around MCSymbolizer
@@ -115,14 +114,14 @@ public:
/// Set \p Symzer as the current symbolizer.
/// This takes ownership of \p Symzer, and deletes the previously set one.
- void setSymbolizer(OwningPtr<MCSymbolizer> &Symzer);
+ void setSymbolizer(std::unique_ptr<MCSymbolizer> Symzer);
/// Sets up an external symbolizer that uses the C API callbacks.
void setupForSymbolicDisassembly(LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp,
void *DisInfo,
MCContext *Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo);
+ std::unique_ptr<MCRelocationInfo> &RelInfo);
LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; }
LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const {
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 65b920b..6e77c6c 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -15,12 +15,17 @@
#ifndef LLVM_MC_MCDWARF_H
#define LLVM_MC_MCDWARF_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <vector>
+#include <string>
+#include <utility>
namespace llvm {
class MCAsmBackend;
@@ -36,41 +41,15 @@ class SMLoc;
/// 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 {
+struct MCDwarfFile {
// Name - the base name of the file without its directory path.
// The StringRef references memory allocated in the MCContext.
- StringRef Name;
+ std::string 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 &) LLVM_DELETED_FUNCTION;
- void operator=(const MCDwarfFile &) LLVM_DELETED_FUNCTION;
-
-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 \p 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 {
@@ -172,58 +151,107 @@ public:
};
/// MCLineSection - Instances of this class represent the line information
-/// for a section where machine instructions have been assembled after seeing
+/// for a compile unit 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 &) LLVM_DELETED_FUNCTION;
- void operator=(const MCLineSection &) LLVM_DELETED_FUNCTION;
-
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, unsigned CUID) {
- MCLineDivisions[CUID].push_back(LineEntry);
+ void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
+ MCLineDivisions[Sec].push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
- typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;
+ typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
private:
- // A collection of MCLineEntry for each Compile Unit ID.
+ // A collection of MCLineEntry for each section.
MCLineDivisionMap MCLineDivisions;
public:
- // Returns whether MCLineSection contains entries for a given Compile
- // Unit ID.
- bool containEntriesForID(unsigned CUID) const {
- return MCLineDivisions.count(CUID);
- }
// Returns the collection of MCLineEntry for a given Compile Unit ID.
- const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const {
- MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID);
- assert(CIter != MCLineDivisions.end());
- return CIter->second;
+ const MCLineDivisionMap &getMCLineEntries() const {
+ return MCLineDivisions;
}
};
-class MCDwarfFileTable {
+struct MCDwarfLineTableHeader {
+ MCSymbol *Label;
+ SmallVector<std::string, 3> MCDwarfDirs;
+ SmallVector<MCDwarfFile, 3> MCDwarfFiles;
+ StringMap<unsigned> SourceIdMap;
+ StringRef CompilationDir;
+
+ MCDwarfLineTableHeader() : Label(nullptr) {}
+ unsigned getFile(StringRef &Directory, StringRef &FileName,
+ unsigned FileNumber = 0);
+ std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
+ std::pair<MCSymbol *, MCSymbol *>
+ Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const;
+};
+
+class MCDwarfDwoLineTable {
+ MCDwarfLineTableHeader Header;
+public:
+ void setCompilationDir(StringRef CompilationDir) {
+ Header.CompilationDir = CompilationDir;
+ }
+ unsigned getFile(StringRef Directory, StringRef FileName) {
+ return Header.getFile(Directory, FileName);
+ }
+ void Emit(MCStreamer &MCOS) const;
+};
+
+class MCDwarfLineTable {
+ MCDwarfLineTableHeader Header;
+ MCLineSection MCLineSections;
+
public:
- //
// This emits the Dwarf file and the line tables for all Compile Units.
- //
- static const MCSymbol *Emit(MCStreamer *MCOS);
- //
+ static void Emit(MCStreamer *MCOS);
+
// This emits the Dwarf file and the line tables for a given Compile Unit.
- //
- static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
+ void EmitCU(MCStreamer *MCOS) const;
+
+ unsigned getFile(StringRef &Directory, StringRef &FileName,
+ unsigned FileNumber = 0);
+
+ MCSymbol *getLabel() const {
+ return Header.Label;
+ }
+
+ void setLabel(MCSymbol *Label) {
+ Header.Label = Label;
+ }
+
+ void setCompilationDir(StringRef CompilationDir) {
+ Header.CompilationDir = CompilationDir;
+ }
+
+ const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
+ return Header.MCDwarfDirs;
+ }
+
+ SmallVectorImpl<std::string> &getMCDwarfDirs() {
+ return Header.MCDwarfDirs;
+ }
+
+ const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
+ return Header.MCDwarfFiles;
+ }
+
+ SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
+ return Header.MCDwarfFiles;
+ }
+
+ const MCLineSection &getMCLineSections() const {
+ return MCLineSections;
+ }
+ MCLineSection &getMCLineSections() {
+ return MCLineSections;
+ }
};
class MCDwarfLineAddr {
@@ -242,7 +270,7 @@ public:
// When generating dwarf for assembly source files this emits the Dwarf
// sections.
//
- static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
+ static void Emit(MCStreamer *MCOS);
};
// When generating dwarf for assembly source files this is the info that is
@@ -438,7 +466,7 @@ struct MCDwarfFrameInfo {
MCDwarfFrameInfo()
: Begin(0), End(0), Personality(0), Lsda(0), Function(0), Instructions(),
PersonalityEncoding(), LsdaEncoding(0), CompactUnwindEncoding(0),
- IsSignalFrame(false) {}
+ IsSignalFrame(false), IsSimple(false) {}
MCSymbol *Begin;
MCSymbol *End;
const MCSymbol *Personality;
@@ -449,6 +477,7 @@ struct MCDwarfFrameInfo {
unsigned LsdaEncoding;
uint32_t CompactUnwindEncoding;
bool IsSignalFrame;
+ bool IsSimple;
};
class MCDwarfFrameEmitter {
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 92ad1b1..127f162 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -20,30 +20,10 @@ class MCAssembler;
class MCFixup;
class MCFragment;
class MCObjectWriter;
+class MCSectionData;
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) {}
-};
-
class MCELFObjectTargetWriter {
const uint8_t OSABI;
const uint16_t EMachine;
@@ -72,19 +52,9 @@ public:
virtual ~MCELFObjectTargetWriter() {}
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
- bool IsPCRel, bool IsRelocWithSymbol,
- int64_t Addend) const = 0;
- virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
- const MCValue &Target,
- const MCFragment &F,
- const MCFixup &Fixup,
- bool IsPCRel) const;
- virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
- const MCFixup &Fixup,
- bool IsPCRel) const;
-
- virtual void sortRelocs(const MCAssembler &Asm,
- std::vector<ELFRelocationEntry> &Relocs);
+ bool IsPCRel) const = 0;
+
+ virtual bool needsRelocateWithSymbol(unsigned Type) const;
/// @name Accessors
/// @{
@@ -107,16 +77,16 @@ public:
#define R_SSYM_MASK 0x00ffffff
// N64 relocation type accessors
- unsigned getRType(uint32_t Type) const {
+ uint8_t getRType(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
}
- unsigned getRType2(uint32_t Type) const {
+ uint8_t getRType2(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
}
- unsigned getRType3(uint32_t Type) const {
+ uint8_t getRType3(uint32_t Type) const {
return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
}
- unsigned getRSsym(uint32_t Type) const {
+ uint8_t getRSsym(uint32_t Type) const {
return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
}
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index 4e24dcf..ebd5d57 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -29,70 +29,68 @@ class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
public:
- MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter),
- SeenIdent(false) {}
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Context, TAB, OS, Emitter),
+ SeenIdent(false) {}
- MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter,
- MCAssembler *Assembler)
- : MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler),
- SeenIdent(false) {}
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, MCAssembler *Assembler)
+ : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
+ SeenIdent(false) {}
virtual ~MCELFStreamer();
/// @name MCStreamer Interface
/// @{
- virtual void InitSections();
- virtual void InitToTextSection();
- virtual void ChangeSection(const MCSection *Section,
- const MCExpr *Subsection);
- virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
- virtual void EmitThumbFunc(MCSymbol *Func);
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
- virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
- virtual void EmitCOFFSymbolStorageClass(int StorageClass);
- virtual void EmitCOFFSymbolType(int Type);
- virtual void EndCOFFSymbolDef();
+ void InitSections() override;
+ void ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) override;
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitDebugLabel(MCSymbol *Symbol) override;
+ void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void EmitThumbFunc(MCSymbol *Func) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
+ void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
+ void EmitCOFFSymbolStorageClass(int StorageClass) override;
+ void EmitCOFFSymbolType(int Type) override;
+ void EndCOFFSymbolDef() override;
- virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+ MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override;
- virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+ void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment);
+ void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override;
- virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
- uint64_t Size = 0, unsigned ByteAlignment = 0);
- virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
- uint64_t Size, unsigned ByteAlignment = 0);
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size);
+ void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+ uint64_t Size = 0, unsigned ByteAlignment = 0) override;
+ void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size) override;
- virtual void EmitFileDirective(StringRef Filename);
+ void EmitFileDirective(StringRef Filename) override;
- virtual void EmitIdent(StringRef IdentString);
+ void EmitIdent(StringRef IdentString) override;
- virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
+ void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
- virtual void Flush();
+ void Flush() override;
- virtual void FinishImpl();
+ void FinishImpl() override;
-private:
- virtual void EmitInstToFragment(const MCInst &Inst);
- virtual void EmitInstToData(const MCInst &Inst);
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ void EmitBundleUnlock() override;
- virtual void EmitBundleAlignMode(unsigned AlignPow2);
- virtual void EmitBundleLock(bool AlignToEnd);
- virtual void EmitBundleUnlock();
+private:
+ void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
void fixSymbolsInTLSFixups(const MCExpr *expr);
@@ -107,13 +105,6 @@ private:
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
-
-
- void SetSection(StringRef Section, unsigned Type, unsigned Flags,
- SectionKind Kind);
- void SetSectionData();
- void SetSectionText();
- void SetSectionBss();
};
MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
diff --git a/include/llvm/MC/MCELFSymbolFlags.h b/include/llvm/MC/MCELFSymbolFlags.h
index d0e1dac..5b82a58 100644
--- a/include/llvm/MC/MCELFSymbolFlags.h
+++ b/include/llvm/MC/MCELFSymbolFlags.h
@@ -21,10 +21,12 @@
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.
+ 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_STO_Shift = 10, // Shift value for STO_* flags.
+ ELF_Other_Shift = 16 // Shift value for llvm local flags,
+ // not part of the final object file
};
enum ELFSymbolFlags {
@@ -49,8 +51,7 @@ namespace llvm {
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)
+ ELF_Other_ThumbFunc = (1 << ELF_Other_Shift)
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 5d55974..0033a54 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -15,6 +15,7 @@
#include "llvm/Support/DataTypes.h"
namespace llvm {
+class MCAsmInfo;
class MCAsmLayout;
class MCAssembler;
class MCContext;
@@ -90,7 +91,7 @@ public:
/// @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;
+ 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
@@ -157,19 +158,24 @@ public:
VK_TLSLDM,
VK_TPOFF,
VK_DTPOFF,
- VK_TLVP, // Mach-O thread local variable relocation
+ VK_TLVP, // Mach-O thread local variable relocations
+ VK_TLVPPAGE,
+ VK_TLVPPAGEOFF,
+ VK_PAGE,
+ VK_PAGEOFF,
+ VK_GOTPAGE,
+ VK_GOTPAGEOFF,
VK_SECREL,
- // FIXME: We'd really like to use the generic Kinds listed above for these.
+ VK_WEAKREF, // The link between the symbols in .weakref foo, bar
+
VK_ARM_NONE,
- VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT
- VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
- VK_ARM_GOT,
- VK_ARM_GOTOFF,
- VK_ARM_TPOFF,
- VK_ARM_GOTTPOFF,
VK_ARM_TARGET1,
VK_ARM_TARGET2,
VK_ARM_PREL31,
+ VK_ARM_TLSLDO, // symbol(tlsldo)
+ VK_ARM_TLSCALL, // symbol(tlscall)
+ VK_ARM_TLSDESC, // symbol(tlsdesc)
+ VK_ARM_TLSDESCSEQ,
VK_PPC_LO, // symbol@l
VK_PPC_HI, // symbol@h
@@ -258,9 +264,14 @@ private:
/// The symbol reference modifier.
const VariantKind Kind;
- explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
- : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {
+ /// MCAsmInfo that is used to print symbol variants correctly.
+ const MCAsmInfo *MAI;
+
+ explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind,
+ const MCAsmInfo *_MAI)
+ : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) {
assert(Symbol);
+ assert(MAI);
}
public:
@@ -281,6 +292,7 @@ public:
/// @{
const MCSymbol &getSymbol() const { return *Symbol; }
+ const MCAsmInfo &getMCAsmInfo() const { return *MAI; }
VariantKind getKind() const { return Kind; }
diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCExternalSymbolizer.h
index c942adc..cab9152 100644
--- a/include/llvm/MC/MCExternalSymbolizer.h
+++ b/include/llvm/MC/MCExternalSymbolizer.h
@@ -18,6 +18,7 @@
#include "llvm-c/Disassembler.h"
#include "llvm/MC/MCSymbolizer.h"
+#include <memory>
namespace llvm {
@@ -38,19 +39,18 @@ class MCExternalSymbolizer : public MCSymbolizer {
public:
MCExternalSymbolizer(MCContext &Ctx,
- OwningPtr<MCRelocationInfo> &RelInfo,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
LLVMOpInfoCallback getOpInfo,
- LLVMSymbolLookupCallback symbolLookUp,
- void *disInfo)
- : MCSymbolizer(Ctx, RelInfo),
- GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), DisInfo(disInfo) {}
+ LLVMSymbolLookupCallback symbolLookUp, void *disInfo)
+ : MCSymbolizer(Ctx, std::move(RelInfo)), GetOpInfo(getOpInfo),
+ SymbolLookUp(symbolLookUp), DisInfo(disInfo) {}
bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream,
- int64_t Value,
- uint64_t Address, bool IsBranch,
- uint64_t Offset, uint64_t InstSize);
+ int64_t Value, uint64_t Address, bool IsBranch,
+ uint64_t Offset, uint64_t InstSize) override;
void tryAddingPcLoadReferenceComment(raw_ostream &CommentStream,
- int64_t Value, uint64_t Address);
+ int64_t Value,
+ uint64_t Address) override;
};
}
diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h
index 16e9eb7..e6d675f 100644
--- a/include/llvm/MC/MCFixup.h
+++ b/include/llvm/MC/MCFixup.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H
+#include "llvm/MC/MCExpr.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SMLoc.h"
@@ -87,6 +88,8 @@ public:
MCFixupKind getKind() const { return MCFixupKind(Kind); }
+ MCSymbolRefExpr::VariantKind getAccessVariant() const;
+
uint32_t getOffset() const { return Offset; }
void setOffset(uint32_t Value) { Offset = Value; }
diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h
index 17bfd15..e921f76 100644
--- a/include/llvm/MC/MCInstrAnalysis.h
+++ b/include/llvm/MC/MCInstrAnalysis.h
@@ -12,6 +12,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCINSTRANALYSIS_H
+#define LLVM_MC_MCINSTRANALYSIS_H
+
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
@@ -63,4 +66,6 @@ public:
uint64_t &Target) const;
};
-}
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h
new file mode 100644
index 0000000..3b0d933
--- /dev/null
+++ b/include/llvm/MC/MCLinkerOptimizationHint.h
@@ -0,0 +1,194 @@
+//===- MCLinkerOptimizationHint.h - LOH 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 declares some helpers classes to handle Linker Optimization Hint
+// (LOH).
+//
+// FIXME: LOH interface supports only MachO format at the moment.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCMachObjectWriter.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+// Forward declarations.
+class MCAsmLayout;
+class MCSymbol;
+
+/// Linker Optimization Hint Type.
+enum MCLOHType {
+ MCLOH_AdrpAdrp = 0x1u, ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
+ MCLOH_AdrpLdr = 0x2u, ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
+ MCLOH_AdrpAddLdr = 0x3u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
+ MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
+ MCLOH_AdrpAddStr = 0x5u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
+ MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
+ MCLOH_AdrpAdd = 0x7u, ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
+ MCLOH_AdrpLdrGot = 0x8u ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
+};
+
+static inline StringRef MCLOHDirectiveName() {
+ return StringRef(".loh");
+}
+
+static inline bool isValidMCLOHType(MCLOHType Kind) {
+ return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
+}
+
+static inline int MCLOHNameToId(StringRef Name) {
+#define MCLOHCaseNameToId(Name) .Case(#Name, MCLOH_ ## Name)
+ return StringSwitch<int>(Name)
+ MCLOHCaseNameToId(AdrpAdrp)
+ MCLOHCaseNameToId(AdrpLdr)
+ MCLOHCaseNameToId(AdrpAddLdr)
+ MCLOHCaseNameToId(AdrpLdrGotLdr)
+ MCLOHCaseNameToId(AdrpAddStr)
+ MCLOHCaseNameToId(AdrpLdrGotStr)
+ MCLOHCaseNameToId(AdrpAdd)
+ MCLOHCaseNameToId(AdrpLdrGot)
+ .Default(-1);
+}
+
+static inline StringRef MCLOHIdToName(MCLOHType Kind) {
+#define MCLOHCaseIdToName(Name) case MCLOH_ ## Name: return StringRef(#Name);
+ switch (Kind) {
+ MCLOHCaseIdToName(AdrpAdrp);
+ MCLOHCaseIdToName(AdrpLdr);
+ MCLOHCaseIdToName(AdrpAddLdr);
+ MCLOHCaseIdToName(AdrpLdrGotLdr);
+ MCLOHCaseIdToName(AdrpAddStr);
+ MCLOHCaseIdToName(AdrpLdrGotStr);
+ MCLOHCaseIdToName(AdrpAdd);
+ MCLOHCaseIdToName(AdrpLdrGot);
+ }
+ return StringRef();
+}
+
+static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
+ switch (Kind) {
+ // LOH with two arguments
+ case MCLOH_AdrpAdrp:
+ case MCLOH_AdrpLdr:
+ case MCLOH_AdrpAdd:
+ case MCLOH_AdrpLdrGot:
+ return 2;
+ // LOH with three arguments
+ case MCLOH_AdrpAddLdr:
+ case MCLOH_AdrpLdrGotLdr:
+ case MCLOH_AdrpAddStr:
+ case MCLOH_AdrpLdrGotStr:
+ return 3;
+ }
+ return -1;
+}
+
+/// Store Linker Optimization Hint information (LOH).
+class MCLOHDirective {
+ MCLOHType Kind;
+
+ /// Arguments of this directive. Order matters.
+ SmallVector<MCSymbol *, 3> Args;
+
+ /// Emit this directive in @p OutStream using the information available
+ /// in the given @p ObjWriter and @p Layout to get the address of the
+ /// arguments within the object file.
+ void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const;
+
+public:
+ typedef SmallVectorImpl<MCSymbol *> LOHArgs;
+
+ MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
+ : Kind(Kind), Args(Args.begin(), Args.end()) {
+ assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
+ }
+
+ MCLOHType getKind() const { return Kind; }
+
+ const LOHArgs &getArgs() const { return Args; }
+
+ /// Emit this directive as:
+ /// <kind, numArgs, addr1, ..., addrN>
+ void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ raw_ostream &OutStream = ObjWriter.getStream();
+ Emit_impl(OutStream, ObjWriter, Layout);
+ }
+
+ /// Get the size in bytes of this directive if emitted in @p ObjWriter with
+ /// the given @p Layout.
+ uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ std::string Buffer;
+ raw_string_ostream OutStream(Buffer);
+ Emit_impl(OutStream, ObjWriter, Layout);
+ return OutStream.tell();
+ }
+};
+
+class MCLOHContainer {
+ /// Keep track of the emit size of all the LOHs.
+ mutable uint64_t EmitSize;
+
+ /// Keep track of all LOH directives.
+ SmallVector<MCLOHDirective, 32> Directives;
+
+public:
+ typedef SmallVectorImpl<MCLOHDirective> LOHDirectives;
+
+ MCLOHContainer() : EmitSize(0) {};
+
+ /// Const accessor to the directives.
+ const LOHDirectives &getDirectives() const {
+ return Directives;
+ }
+
+ /// Add the directive of the given kind @p Kind with the given arguments
+ /// @p Args to the container.
+ void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
+ Directives.push_back(MCLOHDirective(Kind, Args));
+ }
+
+ /// Get the size of the directives if emitted.
+ uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ if (!EmitSize) {
+ for (const MCLOHDirective &D : Directives)
+ EmitSize += D.getEmitSize(ObjWriter, Layout);
+ }
+ return EmitSize;
+ }
+
+ /// Emit all Linker Optimization Hint in one big table.
+ /// Each line of the table is emitted by LOHDirective::Emit.
+ void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
+ for (const MCLOHDirective &D : Directives)
+ D.Emit(ObjWriter, Layout);
+ }
+
+ void reset() {
+ Directives.clear();
+ EmitSize = 0;
+ }
+};
+
+// Add types for specialized template using MCSymbol.
+typedef MCLOHDirective::LOHArgs MCLOHArgs;
+typedef MCLOHContainer::LOHDirectives MCLOHDirectives;
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 3ba6e65..e7d5bbd 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -11,7 +11,6 @@
#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"
@@ -92,7 +91,7 @@ class MachObjectWriter : public MCObjectWriter {
};
/// The target specific Mach-O writer instance.
- llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter;
+ std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
/// @name Relocation Data
/// @{
@@ -121,7 +120,7 @@ public:
/// @name Lifetime management Methods
/// @{
- virtual void reset();
+ void reset() override;
/// @}
@@ -154,9 +153,9 @@ public:
/// @{
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
- bool isARM() const {
- uint32_t CPUType = TargetObjectWriter->getCPUType() & ~MachO::CPU_ARCH_MASK;
- return CPUType == MachO::CPU_TYPE_ARM;
+ bool isX86_64() const {
+ uint32_t CPUType = TargetObjectWriter->getCPUType();
+ return CPUType == MachO::CPU_TYPE_X86_64;
}
/// @}
@@ -231,7 +230,8 @@ public:
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
- MCValue Target, uint64_t &FixedValue);
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
void BindIndirectSymbols(MCAssembler &Asm);
@@ -248,15 +248,16 @@ public:
void markAbsoluteVariableSymbols(MCAssembler &Asm,
const MCAsmLayout &Layout);
- void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
- virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const;
+ bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const override;
- void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
diff --git a/include/llvm/MC/MCModuleYAML.h b/include/llvm/MC/MCModuleYAML.h
index 281e3d8..c4ae829 100644
--- a/include/llvm/MC/MCModuleYAML.h
+++ b/include/llvm/MC/MCModuleYAML.h
@@ -16,7 +16,6 @@
#ifndef LLVM_MC_MCMODULEYAML_H
#define LLVM_MC_MCMODULEYAML_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCModule.h"
#include "llvm/Support/raw_ostream.h"
@@ -33,7 +32,7 @@ StringRef mcmodule2yaml(raw_ostream &OS, const MCModule &MCM,
/// \brief Creates a new module and returns it in \p MCM.
/// \returns The empty string on success, an error message on failure.
-StringRef yaml2mcmodule(OwningPtr<MCModule> &MCM, StringRef YamlContent,
+StringRef yaml2mcmodule(std::unique_ptr<MCModule> &MCM, StringRef YamlContent,
const MCInstrInfo &MII, const MCRegisterInfo &MRI);
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectDisassembler.h b/include/llvm/MC/MCObjectDisassembler.h
index 0d87d33..5b935db 100644
--- a/include/llvm/MC/MCObjectDisassembler.h
+++ b/include/llvm/MC/MCObjectDisassembler.h
@@ -16,7 +16,6 @@
#define LLVM_MC_MCOBJECTDISASSEMBLER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MemoryObject.h"
@@ -67,8 +66,8 @@ public:
/// \brief Set the region on which to fallback if disassembly was requested
/// somewhere not accessible in the object file.
/// This is used for dynamic disassembly (see RawMemoryObject).
- void setFallbackRegion(OwningPtr<MemoryObject> &Region) {
- FallbackRegion.reset(Region.take());
+ void setFallbackRegion(std::unique_ptr<MemoryObject> &Region) {
+ FallbackRegion.reset(Region.release());
}
/// \brief Set the symbolizer to use to get information on external functions.
@@ -113,7 +112,7 @@ protected:
MCObjectSymbolizer *MOS;
/// \brief The fallback memory region, outside the object file.
- OwningPtr<MemoryObject> FallbackRegion;
+ std::unique_ptr<MemoryObject> FallbackRegion;
/// \brief Return a memory region suitable for reading starting at \p Addr.
/// In most cases, this returns a StringRefMemoryObject backed by the
@@ -162,12 +161,12 @@ public:
uint64_t HeaderLoadAddress);
protected:
- uint64_t getEffectiveLoadAddr(uint64_t Addr) LLVM_OVERRIDE;
- uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) LLVM_OVERRIDE;
- uint64_t getEntrypoint() LLVM_OVERRIDE;
+ uint64_t getEffectiveLoadAddr(uint64_t Addr) override;
+ uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) override;
+ uint64_t getEntrypoint() override;
- ArrayRef<uint64_t> getStaticInitFunctions() LLVM_OVERRIDE;
- ArrayRef<uint64_t> getStaticExitFunctions() LLVM_OVERRIDE;
+ ArrayRef<uint64_t> getStaticInitFunctions() override;
+ ArrayRef<uint64_t> getStaticExitFunctions() override;
};
}
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index c48dcb0..1c5c19e 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -39,6 +39,11 @@ protected:
/// non-.globl label. This defaults to true.
bool IsFunctionEHFrameSymbolPrivate;
+ /// SupportsCompactUnwindWithoutEHFrame - True if the target object file
+ /// supports emitting a compact unwind section without an associated EH frame
+ /// section.
+ bool SupportsCompactUnwindWithoutEHFrame;
+
/// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some
/// encoding values for EH.
unsigned PersonalityEncoding;
@@ -129,6 +134,8 @@ protected:
const MCSection *DwarfGnuPubNamesSection;
const MCSection *DwarfGnuPubTypesSection;
+ const MCSection *COFFDebugSymbolsSection;
+
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
const MCSection *TLSExtraDataSection;
@@ -201,6 +208,9 @@ public:
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
}
+ bool getSupportsCompactUnwindWithoutEHFrame() const {
+ return SupportsCompactUnwindWithoutEHFrame;
+ }
bool getCommDirectiveSupportsAlignment() const {
return CommDirectiveSupportsAlignment;
}
@@ -262,6 +272,8 @@ public:
const MCSection *getDwarfInfoDWOSection() const {
return DwarfInfoDWOSection;
}
+ const MCSection *getDwarfTypesSection(uint64_t Hash) const;
+ const MCSection *getDwarfTypesDWOSection(uint64_t Hash) const;
const MCSection *getDwarfAbbrevDWOSection() const {
return DwarfAbbrevDWOSection;
}
@@ -281,6 +293,10 @@ public:
return DwarfAddrSection;
}
+ const MCSection *getCOFFDebugSymbolsSection() const {
+ return COFFDebugSymbolsSection;
+ }
+
const MCSection *getTLSExtraDataSection() const {
return TLSExtraDataSection;
}
@@ -353,8 +369,16 @@ public:
return EHFrameSection;
}
-private:
enum Environment { IsMachO, IsELF, IsCOFF };
+ Environment getObjectFileType() const {
+ return Env;
+ }
+
+ Reloc::Model getRelocM() const {
+ return RelocM;
+ }
+
+private:
Environment Env;
Reloc::Model RelocM;
CodeModel::Model CMModel;
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 5667544..a42b7a05 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -17,6 +17,7 @@ namespace llvm {
class MCAssembler;
class MCCodeEmitter;
class MCSectionData;
+class MCSubtargetInfo;
class MCExpr;
class MCFragment;
class MCDataFragment;
@@ -35,22 +36,23 @@ class MCObjectStreamer : public MCStreamer {
MCSectionData *CurSectionData;
MCSectionData::iterator CurInsertionPoint;
- virtual void EmitInstToData(const MCInst &Inst) = 0;
- virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
- virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
+ virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
+ void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+ void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
protected:
- MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &_OS,
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
MCCodeEmitter *_Emitter);
- MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter,
- MCAssembler *_Assembler);
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
+ MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
~MCObjectStreamer();
public:
/// state management
- virtual void reset();
+ void reset() override;
+
+ /// Object streamers require the integrated assembler.
+ bool isIntegratedAssemblerRequired() const override { return true; }
protected:
MCSectionData *getCurrentSectionData() const {
@@ -76,47 +78,45 @@ public:
/// @name MCStreamer Interface
/// @{
- virtual void EmitLabel(MCSymbol *Symbol);
- virtual void EmitDebugLabel(MCSymbol *Symbol);
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size);
- 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,
- const MCExpr *Subsection);
- virtual void EmitInstruction(const MCInst &Inst);
+ void EmitLabel(MCSymbol *Symbol) override;
+ void EmitDebugLabel(MCSymbol *Symbol) override;
+ void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ void EmitValueImpl(const MCExpr *Value, unsigned Size) override;
+ void EmitULEB128Value(const MCExpr *Value) override;
+ void EmitSLEB128Value(const MCExpr *Value) override;
+ void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ void ChangeSection(const MCSection *Section,
+ const MCExpr *Subsection) override;
+ void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo& STI) override;
/// \brief Emit an instruction to a special fragment, because this instruction
/// can change its size during relaxation.
- virtual void EmitInstToFragment(const MCInst &Inst);
-
- virtual void EmitBundleAlignMode(unsigned AlignPow2);
- virtual void EmitBundleLock(bool AlignToEnd);
- virtual void EmitBundleUnlock();
- virtual void EmitBytes(StringRef Data);
- virtual void EmitValueToAlignment(unsigned ByteAlignment,
- int64_t Value = 0,
- unsigned ValueSize = 1,
- unsigned MaxBytesToEmit = 0);
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
- unsigned MaxBytesToEmit = 0);
- virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
- virtual void 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);
- virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
- const MCSymbol *Label);
- virtual void EmitGPRel32Value(const MCExpr *Value);
- virtual void EmitGPRel64Value(const MCExpr *Value);
- virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
- virtual void EmitZeros(uint64_t NumBytes);
- virtual void FinishImpl();
+ virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
+
+ void EmitBundleAlignMode(unsigned AlignPow2) override;
+ void EmitBundleLock(bool AlignToEnd) override;
+ void EmitBundleUnlock() override;
+ void EmitBytes(StringRef Data) override;
+ void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0) override;
+ void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0) override;
+ bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value) override;
+ void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ unsigned Column, unsigned Flags,
+ unsigned Isa, unsigned Discriminator,
+ StringRef FileName) override;
+ void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
+ const MCSymbol *Label,
+ unsigned PointerSize) override;
+ void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label) override;
+ void EmitGPRel32Value(const MCExpr *Value) override;
+ void EmitGPRel64Value(const MCExpr *Value) override;
+ void EmitFill(uint64_t NumBytes, uint8_t FillValue) override;
+ void EmitZeros(uint64_t NumBytes) override;
+ void FinishImpl() override;
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectSymbolizer.h b/include/llvm/MC/MCObjectSymbolizer.h
index 64b932e..f75b7f5 100644
--- a/include/llvm/MC/MCObjectSymbolizer.h
+++ b/include/llvm/MC/MCObjectSymbolizer.h
@@ -41,7 +41,7 @@ protected:
const object::RelocationRef *findRelocationAt(uint64_t Addr);
const object::SectionRef *findSectionContaining(uint64_t Addr);
- MCObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
+ MCObjectSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo,
const object::ObjectFile *Obj);
public:
@@ -50,10 +50,11 @@ public:
bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream,
int64_t Value, uint64_t Address,
bool IsBranch, uint64_t Offset,
- uint64_t InstSize);
+ uint64_t InstSize) override;
void tryAddingPcLoadReferenceComment(raw_ostream &cStream,
- int64_t Value, uint64_t Address);
+ int64_t Value,
+ uint64_t Address) override;
/// @}
/// \brief Look for an external function symbol at \p Addr.
@@ -63,8 +64,9 @@ public:
/// \brief Create an object symbolizer for \p Obj.
static MCObjectSymbolizer *
- createObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo,
- const object::ObjectFile *Obj);
+ createObjectSymbolizer(MCContext &Ctx,
+ std::unique_ptr<MCRelocationInfo> RelInfo,
+ const object::ObjectFile *Obj);
private:
typedef DenseMap<uint64_t, object::RelocationRef> AddrToRelocMap;
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 4939a3f..55c828c 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -80,6 +80,7 @@ public:
const MCAsmLayout &Layout,
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
+ bool &IsPCRel,
uint64_t &FixedValue) = 0;
/// \brief Check whether the difference (A - B) between two symbol
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index 1b3ab57..f36011c 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -36,7 +36,7 @@ class AsmLexer : public MCAsmLexer {
protected:
/// LexToken - Read the next token and return its code.
- virtual AsmToken LexToken();
+ AsmToken LexToken() override;
public:
AsmLexer(const MCAsmInfo &MAI);
@@ -44,9 +44,11 @@ public:
void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL);
- virtual StringRef LexUntilEndOfStatement();
+ StringRef LexUntilEndOfStatement() override;
StringRef LexUntilEndOfLine();
+ const AsmToken peekTok(bool ShouldSkipSpace = true) override;
+
bool isAtStartOfComment(char Char);
bool isAtStatementSeparator(const char *Ptr);
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index 53b380f..e3d4181 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
#define LLVM_MC_MCPARSER_MCASMLEXER_H
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
@@ -30,6 +31,7 @@ public:
// Integer values.
Integer,
+ BigNum, // larger than 64 bits
// Real values.
Real,
@@ -57,12 +59,14 @@ private:
/// a memory buffer owned by the source manager.
StringRef Str;
- int64_t IntVal;
+ APInt IntVal;
public:
AsmToken() {}
- AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+ AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal)
: Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
+ AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+ : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {}
TokenKind getKind() const { return Kind; }
bool is(TokenKind K) const { return Kind == K; }
@@ -99,6 +103,12 @@ public:
// 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.getZExtValue();
+ }
+
+ APInt getAPIntVal() const {
+ assert((Kind == Integer || Kind == BigNum) &&
+ "This token isn't an integer!");
return IntVal;
}
};
@@ -118,6 +128,7 @@ class MCAsmLexer {
protected: // Can only create subclasses.
const char *TokStart;
bool SkipSpace;
+ bool AllowAtInIdentifier;
MCAsmLexer();
@@ -149,6 +160,9 @@ public:
return CurTok;
}
+ /// peekTok - Look ahead at the next token to be lexed.
+ virtual const AsmToken peekTok(bool ShouldSkipSpace = true) = 0;
+
/// getErrLoc - Get the current error location
const SMLoc &getErrLoc() {
return ErrLoc;
@@ -170,6 +184,9 @@ public:
/// setSkipSpace - Set whether spaces should be ignored by the lexer
void setSkipSpace(bool val) { SkipSpace = val; }
+
+ bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
+ void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index 1d15534..0389caa 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -118,6 +118,10 @@ public:
const MCInstPrinter *IP,
MCAsmParserSemaCallback &SI) = 0;
+ /// Note - Emit a note at the location \p L, with the message \p Msg.
+ virtual void Note(SMLoc L, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = None) = 0;
+
/// Warning - Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index 6881e1d..d1ab411 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -32,11 +32,16 @@ struct MCProcResourceDesc {
// Number of resources that may be buffered.
//
- // Buffered resources (BufferSize > 0 || BufferSize == -1) may be consumed at
- // some indeterminate cycle after dispatch (e.g. for instructions that may
- // issue out-of-order). Unbuffered resources (BufferSize == 0) always consume
- // their resource some fixed number of cycles after dispatch (e.g. for
- // instruction interlocking that may stall the pipeline).
+ // Buffered resources (BufferSize != 0) may be consumed at some indeterminate
+ // cycle after dispatch. This should be used for out-of-order cpus when
+ // instructions that use this resource can be buffered in a reservaton
+ // station.
+ //
+ // Unbuffered resources (BufferSize == 0) always consume their resource some
+ // fixed number of cycles after dispatch. If a resource is unbuffered, then
+ // the scheduler will avoid scheduling instructions with conflicting resources
+ // in the same cycle. This is for in-order cpus, or the in-order portion of
+ // an out-of-order cpus.
int BufferSize;
bool operator==(const MCProcResourceDesc &Other) const {
@@ -149,7 +154,7 @@ public:
// but we balance those stalls against other heuristics.
//
// "> 1" means the processor is out-of-order. This is a machine independent
- // estimate of highly machine specific characteristics such are the register
+ // estimate of highly machine specific characteristics such as the register
// renaming pool and reorder buffer.
unsigned MicroOpBufferSize;
static const unsigned DefaultMicroOpBufferSize = 0;
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index 944bfcb..de2678a 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -31,8 +31,7 @@ namespace llvm {
enum SectionVariant {
SV_COFF = 0,
SV_ELF,
- SV_MachO,
- SV_LDContext
+ SV_MachO
};
private:
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 45c84ae..aa02d9a 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -69,10 +69,10 @@ class MCSymbol;
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- virtual std::string getLabelBeginName() const {
+ std::string getLabelBeginName() const override {
return SectionName.str() + "_begin";
}
- virtual std::string getLabelEndName() const {
+ std::string getLabelEndName() const override {
return SectionName.str() + "_end";
}
unsigned getCharacteristics() const { return Characteristics; }
@@ -81,11 +81,10 @@ class MCSymbol;
void setSelection(int Selection, const MCSectionCOFF *Assoc = 0) const;
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS,
- const MCExpr *Subsection) const;
- virtual bool UseCodeAlign() const;
- virtual bool isVirtualSection() const;
+ void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 5979915..89c02cc 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
@@ -59,9 +60,14 @@ public:
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- virtual std::string getLabelBeginName() const {
- return SectionName.str() + "_begin"; }
- virtual std::string getLabelEndName() const {
+ std::string getLabelBeginName() const override {
+ if (Group)
+ return (SectionName.str() + '_' + Group->getName() + "_begin").str();
+ return SectionName.str() + "_begin";
+ }
+ std::string getLabelEndName() const override {
+ if (Group)
+ return (SectionName.str() + '_' + Group->getName() + "_end").str();
return SectionName.str() + "_end";
}
unsigned getType() const { return Type; }
@@ -69,15 +75,14 @@ public:
unsigned getEntrySize() const { return EntrySize; }
const MCSymbol *getGroup() const { return Group; }
- void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS,
- const MCExpr *Subsection) const;
- virtual bool UseCodeAlign() const;
- virtual bool isVirtualSection() const;
+ void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
/// isBaseAddressKnownZero - We know that non-allocatable sections (like
/// debug info) have a base of zero.
- virtual bool isBaseAddressKnownZero() const {
+ bool isBaseAddressKnownZero() const override {
return (getFlags() & ELF::SHF_ALLOC) == 0;
}
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index d7e88ea..a5a2089 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/Support/MachO.h"
namespace llvm {
@@ -39,99 +40,6 @@ class MCSectionMachO : public MCSection {
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 LLVM_ENUM_INT_TYPE(uint32_t) {
- // 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])
@@ -145,18 +53,21 @@ public:
return StringRef(SectionName);
}
- virtual std::string getLabelBeginName() const {
+ std::string getLabelBeginName() const override {
return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
}
- virtual std::string getLabelEndName() const {
+ std::string getLabelEndName() const override {
return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
}
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
- unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; }
+ MachO::SectionType getType() const {
+ return static_cast<MachO::SectionType>(TypeAndAttributes &
+ MachO::SECTION_TYPE);
+ }
bool hasAttribute(unsigned Value) const {
return (TypeAndAttributes & Value) != 0;
}
@@ -174,11 +85,10 @@ public:
bool &TAAParsed, // Out.
unsigned &StubSize); // Out.
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS,
- const MCExpr *Subsection) const;
- virtual bool UseCodeAlign() const;
- virtual bool isVirtualSection() const;
+ void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const override;
+ bool UseCodeAlign() const override;
+ bool isVirtualSection() const override;
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 0b1fe6e..8ee60c1 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -19,6 +19,7 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -33,10 +34,13 @@ class MCInstPrinter;
class MCSection;
class MCStreamer;
class MCSymbol;
+class MCSymbolRefExpr;
+class MCSubtargetInfo;
class StringRef;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
+class AssemblerConstantPools;
typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
@@ -66,34 +70,70 @@ typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
/// be treated differently. Callers should always talk to a FooTargetStreamer.
class MCTargetStreamer {
protected:
- MCStreamer *Streamer;
+ MCStreamer &Streamer;
public:
+ MCTargetStreamer(MCStreamer &S);
virtual ~MCTargetStreamer();
- void setStreamer(MCStreamer *S) { Streamer = S; }
+
+ const MCStreamer &getStreamer() { return Streamer; }
+
+ // Allow a target to add behavior to the EmitLabel of MCStreamer.
+ virtual void emitLabel(MCSymbol *Symbol);
+ // Allow a target to add behavior to the emitAssignment of MCStreamer.
+ virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+
+ virtual void finish();
};
// FIXME: declared here because it is used from
// lib/CodeGen/AsmPrinter/ARMException.cpp.
class ARMTargetStreamer : public MCTargetStreamer {
- virtual void anchor();
public:
- virtual void emitFnStart() = 0;
- virtual void emitFnEnd() = 0;
- virtual void emitCantUnwind() = 0;
- virtual void emitPersonality(const MCSymbol *Personality) = 0;
- virtual void emitHandlerData() = 0;
+ ARMTargetStreamer(MCStreamer &S);
+ ~ARMTargetStreamer();
+
+ virtual void emitFnStart();
+ virtual void emitFnEnd();
+ virtual void emitCantUnwind();
+ virtual void emitPersonality(const MCSymbol *Personality);
+ virtual void emitPersonalityIndex(unsigned Index);
+ virtual void emitHandlerData();
virtual void emitSetFP(unsigned FpReg, unsigned SpReg,
- int64_t Offset = 0) = 0;
- virtual void emitPad(int64_t Offset) = 0;
+ int64_t Offset = 0);
+ virtual void emitMovSP(unsigned Reg, int64_t Offset = 0);
+ virtual void emitPad(int64_t Offset);
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
- bool isVector) = 0;
-
- virtual void switchVendor(StringRef Vendor) = 0;
- virtual void emitAttribute(unsigned Attribute, unsigned Value) = 0;
- virtual void emitTextAttribute(unsigned Attribute, StringRef String) = 0;
- virtual void emitFPU(unsigned FPU) = 0;
- virtual void finishAttributeSection() = 0;
+ bool isVector);
+ virtual void emitUnwindRaw(int64_t StackOffset,
+ const SmallVectorImpl<uint8_t> &Opcodes);
+
+ virtual void switchVendor(StringRef Vendor);
+ virtual void emitAttribute(unsigned Attribute, unsigned Value);
+ virtual void emitTextAttribute(unsigned Attribute, StringRef String);
+ virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
+ StringRef StringValue = "");
+ virtual void emitFPU(unsigned FPU);
+ virtual void emitArch(unsigned Arch);
+ virtual void emitObjectArch(unsigned Arch);
+ virtual void finishAttributeSection();
+ virtual void emitInst(uint32_t Inst, char Suffix = '\0');
+
+ virtual void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE);
+
+ void finish() override;
+
+ /// Callback used to implement the ldr= pseudo.
+ /// Add a new entry to the constant pool for the current section and return an
+ /// MCExpr that can be used to refer to the constant pool location.
+ const MCExpr *addConstantPoolEntry(const MCExpr *);
+
+ /// Callback used to implemnt the .ltorg directive.
+ /// Emit contents of constant pool for the current section.
+ void emitCurrentConstantPool();
+
+private:
+ std::unique_ptr<AssemblerConstantPools> ConstantPools;
};
/// MCStreamer - Streaming machine code generation interface. This interface
@@ -107,7 +147,7 @@ public:
///
class MCStreamer {
MCContext &Context;
- OwningPtr<MCTargetStreamer> TargetStreamer;
+ std::unique_ptr<MCTargetStreamer> TargetStreamer;
MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION;
MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION;
@@ -135,10 +175,8 @@ class MCStreamer {
/// values saved by PushSection.
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
- bool AutoInitSections;
-
protected:
- MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer);
+ MCStreamer(MCContext &Ctx);
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
const MCSymbol *B);
@@ -161,15 +199,18 @@ protected:
public:
virtual ~MCStreamer();
+ void setTargetStreamer(MCTargetStreamer *TS) {
+ TargetStreamer.reset(TS);
+ }
+
/// State management
///
virtual void reset();
MCContext &getContext() const { return Context; }
- MCTargetStreamer &getTargetStreamer() {
- assert(TargetStreamer);
- return *TargetStreamer;
+ MCTargetStreamer *getTargetStreamer() {
+ return TargetStreamer.get();
}
unsigned getNumFrameInfos() { return FrameInfos.size(); }
@@ -197,6 +238,10 @@ public:
/// unformatted text to the .s file with EmitRawText.
virtual bool hasRawTextSupport() const { return false; }
+ /// Is the integrated assembler required for this streamer to function
+ /// correctly?
+ virtual bool isIntegratedAssemblerRequired() 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
@@ -211,6 +256,12 @@ public:
/// use this method.
virtual raw_ostream &GetCommentOS();
+ /// Print T and prefix it with the comment string (normally #) and optionally
+ /// a tab. This prints the comment immediately, not at the end of the
+ /// current line. It is basically a safe version of EmitRawText: since it
+ /// only prints comments, the object streamer ignores it instead of asserting.
+ virtual void emitRawComment(const Twine &T, bool TabPrefix = true);
+
/// AddBlankLine - Emit a blank line to a .s file to pretty it up.
virtual void AddBlankLine() {}
@@ -303,22 +354,8 @@ public:
SectionStack.back().first = MCSectionSubPair(Section, Subsection);
}
- /// Initialize the streamer.
- void InitStreamer() {
- if (AutoInitSections)
- InitSections();
- }
-
- /// Tell this MCStreamer to call InitSections upon initialization.
- void setAutoInitSections(bool AutoInitSections) {
- this->AutoInitSections = AutoInitSections;
- }
-
- /// InitSections - Create the default sections and set the initial one.
- virtual void InitSections() = 0;
-
- /// InitToTextSection - Create a text section and switch the streamer to it.
- virtual void InitToTextSection() = 0;
+ /// Create the default sections and set the initial one.
+ virtual void InitSections();
/// AssignSection - Sets the symbol's section.
///
@@ -334,6 +371,8 @@ public:
/// @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.
+ // FIXME: These emission are non-const because we mutate the symbol to
+ // add the section we're emitting it to later.
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitDebugLabel(MCSymbol *Symbol);
@@ -350,12 +389,16 @@ public:
/// EmitDataRegion - Note in the output the specified region @p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
+ /// EmitVersionMin - Specify the MachO minimum deployment target version.
+ virtual void EmitVersionMin(MCVersionMinType, unsigned Major, unsigned Minor,
+ unsigned Update) {}
+
/// EmitThumbFunc - Note in the output that the specified @p Func is
/// a Thumb mode function (ARM target only).
virtual void EmitThumbFunc(MCSymbol *Func) = 0;
/// getOrCreateSymbolData - Get symbol data for given symbol.
- virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+ virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol);
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
@@ -368,7 +411,7 @@ public:
///
/// @param Symbol - The symbol being assigned to.
/// @param Value - The value for the symbol.
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0;
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
/// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
///
@@ -407,9 +450,14 @@ public:
/// EndCOFFSymbolDef - Marks the end of the symbol definition.
virtual void EndCOFFSymbolDef() = 0;
+ /// EmitCOFFSectionIndex - Emits a COFF section index.
+ ///
+ /// @param Symbol - Symbol the section number relocation should point to.
+ virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol);
+
/// EmitCOFFSecRel32 - Emits a COFF section relative relocation.
///
- /// @param Symbol - Symbol the section relative realocation should point to.
+ /// @param Symbol - Symbol the section relative relocation should point to.
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol);
/// EmitELFSize - Emit an ELF .size directive.
@@ -419,6 +467,10 @@ public:
///
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
+ /// \brief Emit a Linker Optimization Hint (LOH) directive.
+ /// \param Args - Arguments of the LOH.
+ virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
+
/// EmitCommonSymbol - Emit a common symbol.
///
/// @param Symbol - The common symbol to emit.
@@ -587,8 +639,9 @@ public:
/// 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, unsigned CUID = 0);
+ virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+ StringRef Filename,
+ unsigned CUID = 0);
/// EmitDwarfLocDirective - This implements the DWARF2
// '.loc fileno lineno ...' assembler directive.
@@ -605,12 +658,14 @@ public:
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label) {}
+ virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
+
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 EmitCFIStartProc(bool IsSimple);
void EmitCFIEndProc();
virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
virtual void EmitCFIDefCfaOffset(int64_t Offset);
@@ -647,7 +702,7 @@ public:
/// EmitInstruction - Emit the given @p Instruction into the current
/// section.
- virtual void EmitInstruction(const MCInst &Inst) = 0;
+ virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) = 0;
/// \brief Set the bundle alignment mode from now on in the section.
/// The argument is the power of 2 to which the alignment is set. The
@@ -698,12 +753,11 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
-MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
- formatted_raw_ostream &OS, bool isVerboseAsm,
- bool useLoc, bool useCFI, bool useDwarfDirectory,
- MCInstPrinter *InstPrint = 0,
- MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0,
- bool ShowInst = false);
+MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm, bool useCFI,
+ bool useDwarfDirectory, MCInstPrinter *InstPrint,
+ MCCodeEmitter *CE, MCAsmBackend *TAB,
+ bool ShowInst);
/// createMachOStreamer - Create a machine code streamer which will generate
/// Mach-O format object files.
@@ -711,7 +765,8 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
/// Takes ownership of \p TAB and \p CE.
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll = false);
+ bool RelaxAll = false,
+ bool LabelSections = false);
/// createWinCOFFStreamer - Create a machine code streamer which will
/// generate Microsoft COFF format object files.
@@ -723,18 +778,10 @@ MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
/// createELFStreamer - Create a machine code streamer which will generate
/// ELF format object files.
-MCStreamer *createELFStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
- MCAsmBackend &TAB, raw_ostream &OS,
- MCCodeEmitter *CE, bool RelaxAll,
+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 \p TAB and \p CE.
-MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE);
-
} // end namespace llvm
#endif
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index fe92755..ea14da1 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -141,7 +141,7 @@ namespace llvm {
}
// AliasedSymbol() - If this is an alias (a = b), return the symbol
- // we ultimately point to. For a non alias, this just returns the symbol
+ // we ultimately point to. For a non-alias, this just returns the symbol
// itself.
const MCSymbol &AliasedSymbol() const;
diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h
index e42a214..cbbb591 100644
--- a/include/llvm/MC/MCSymbolizer.h
+++ b/include/llvm/MC/MCSymbolizer.h
@@ -16,10 +16,11 @@
#ifndef LLVM_MC_MCSYMBOLIZER_H
#define LLVM_MC_MCSYMBOLIZER_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <memory>
namespace llvm {
@@ -42,11 +43,14 @@ class MCSymbolizer {
protected:
MCContext &Ctx;
- OwningPtr<MCRelocationInfo> RelInfo;
+ std::unique_ptr<MCRelocationInfo> RelInfo;
public:
/// \brief Construct an MCSymbolizer, taking ownership of \p RelInfo.
- MCSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo);
+ MCSymbolizer(MCContext &Ctx, std::unique_ptr<MCRelocationInfo> RelInfo)
+ : Ctx(Ctx), RelInfo(std::move(RelInfo)) {
+ }
+
virtual ~MCSymbolizer();
/// \brief Try to add a symbolic operand instead of \p Value to the MCInst.
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index d132a73..0073136 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -10,8 +10,8 @@
#ifndef LLVM_MC_TARGETPARSER_H
#define LLVM_MC_TARGETPARSER_H
-#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
namespace llvm {
class MCStreamer;
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index a4e7301..f4ea511 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -24,9 +24,16 @@ 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.
+/// MCValue - This represents an "assembler immediate". In its most
+/// general form, this can hold ":Kind:(SymbolA - SymbolB + imm64)".
+/// Not all targets supports relocations of this general form, but we
+/// need to represent this anyway.
+///
+/// In general both SymbolA and SymbolB will also have a modifier
+/// analogous to the top-level Kind. Current targets are not expected
+/// to make use of both though. The choice comes down to whether
+/// relocation modifiers apply to the closest symbol or the whole
+/// expression.
///
/// 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
@@ -37,11 +44,13 @@ class raw_ostream;
class MCValue {
const MCSymbolRefExpr *SymA, *SymB;
int64_t Cst;
+ uint32_t RefKind;
public:
int64_t getConstant() const { return Cst; }
const MCSymbolRefExpr *getSymA() const { return SymA; }
const MCSymbolRefExpr *getSymB() const { return SymB; }
+ uint32_t getRefKind() const { return RefKind; }
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
@@ -53,12 +62,13 @@ public:
void dump() const;
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0,
- int64_t Val = 0) {
+ int64_t Val = 0, uint32_t RefKind = 0) {
MCValue R;
assert((!SymB || SymA) && "Invalid relocatable MCValue!");
R.Cst = Val;
R.SymA = SymA;
R.SymB = SymB;
+ R.RefKind = RefKind;
return R;
}
@@ -67,6 +77,7 @@ public:
R.Cst = Val;
R.SymA = 0;
R.SymB = 0;
+ R.RefKind = 0;
return R;
}
diff --git a/include/llvm/MC/MachineLocation.h b/include/llvm/MC/MachineLocation.h
index b3fbee7..2a18615 100644
--- a/include/llvm/MC/MachineLocation.h
+++ b/include/llvm/MC/MachineLocation.h
@@ -28,7 +28,7 @@ private:
unsigned Register; // gcc/gdb register number.
int Offset; // Displacement if not register.
public:
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// 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
@@ -73,6 +73,11 @@ public:
void dump();
#endif
};
+
+inline bool operator!=(const MachineLocation &LHS, const MachineLocation &RHS) {
+ return !(LHS == RHS);
+}
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 1cba519..4fae76f 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Binary.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -90,8 +91,13 @@ public:
error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
bool FullPath = false) const;
+ error_code getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
+ bool FullPath = false) const;
- error_code getAsBinary(OwningPtr<Binary> &Result) const;
+ error_code getAsBinary(OwningPtr<Binary> &Result,
+ LLVMContext *Context = 0) const;
+ error_code getAsBinary(std::unique_ptr<Binary> &Result,
+ LLVMContext *Context = 0) const;
};
class child_iterator {
@@ -163,6 +169,7 @@ public:
};
Archive(MemoryBuffer *source, error_code &ec);
+ static ErrorOr<Archive *> create(MemoryBuffer *Source);
enum Kind {
K_GNU,
@@ -174,11 +181,11 @@ public:
return Format;
}
- child_iterator begin_children(bool SkipInternal = true) const;
- child_iterator end_children() const;
+ child_iterator child_begin(bool SkipInternal = true) const;
+ child_iterator child_end() const;
- symbol_iterator begin_symbols() const;
- symbol_iterator end_symbols() const;
+ symbol_iterator symbol_begin() const;
+ symbol_iterator symbol_end() const;
// Cast methods.
static inline bool classof(Binary const *v) {
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index a3f5625..b10e40a 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -14,11 +14,13 @@
#ifndef LLVM_OBJECT_BINARY_H
#define LLVM_OBJECT_BINARY_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Object/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
namespace llvm {
+class LLVMContext;
class MemoryBuffer;
class StringRef;
@@ -30,15 +32,18 @@ private:
Binary(const Binary &other) LLVM_DELETED_FUNCTION;
unsigned int TypeID;
+ bool BufferOwned;
protected:
MemoryBuffer *Data;
- Binary(unsigned int Type, MemoryBuffer *Source);
+ Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
enum {
ID_Archive,
ID_MachOUniversalBinary,
+ ID_IR, // LLVM IR
+
// Object and children.
ID_StartObjects,
ID_COFF,
@@ -84,6 +89,10 @@ public:
return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
}
+ bool isSymbolic() const {
+ return isIR() || isObject();
+ }
+
bool isArchive() const {
return TypeID == ID_Archive;
}
@@ -104,6 +113,10 @@ public:
return TypeID == ID_COFF;
}
+ bool isIR() const {
+ return TypeID == ID_IR;
+ }
+
bool isLittleEndian() const {
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
@@ -113,13 +126,11 @@ public:
/// @brief Create a Binary from Source, autodetecting the file type.
///
/// @param Source The data to create the Binary from. Ownership is transferred
-/// 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);
+/// to the Binary if successful. If an error is returned,
+/// Source is destroyed by createBinary before returning.
+ErrorOr<Binary *> createBinary(MemoryBuffer *Source, LLVMContext *Context = 0);
+ErrorOr<Binary *> createBinary(StringRef Path);
}
}
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index e05ae6c..6e05c2d 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -19,12 +19,13 @@
#include "llvm/Support/Endian.h"
namespace llvm {
- template <typename T>
- class ArrayRef;
+template <typename T> class ArrayRef;
namespace object {
class ImportDirectoryEntryRef;
+class ExportDirectoryEntryRef;
typedef content_iterator<ImportDirectoryEntryRef> import_directory_iterator;
+typedef content_iterator<ExportDirectoryEntryRef> export_directory_iterator;
/// The DOS compatible header at the front of all PE/COFF executables.
struct dos_header {
@@ -64,8 +65,8 @@ struct coff_file_header {
/// The 32-bit PE header that follows the COFF header.
struct pe32_header {
support::ulittle16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
support::ulittle32_t SizeOfCode;
support::ulittle32_t SizeOfInitializedData;
support::ulittle32_t SizeOfUninitializedData;
@@ -98,8 +99,8 @@ struct pe32_header {
/// The 64-bit PE header that follows the COFF header.
struct pe32plus_header {
support::ulittle16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
support::ulittle32_t SizeOfCode;
support::ulittle32_t SizeOfInitializedData;
support::ulittle32_t SizeOfUninitializedData;
@@ -157,6 +158,28 @@ struct import_lookup_table_entry32 {
}
};
+struct export_directory_table_entry {
+ support::ulittle32_t ExportFlags;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t OrdinalBase;
+ support::ulittle32_t AddressTableEntries;
+ support::ulittle32_t NumberOfNamePointers;
+ support::ulittle32_t ExportAddressTableRVA;
+ support::ulittle32_t NamePointerRVA;
+ support::ulittle32_t OrdinalTableRVA;
+};
+
+union export_address_table_entry {
+ support::ulittle32_t ExportRVA;
+ support::ulittle32_t ForwarderRVA;
+};
+
+typedef support::ulittle32_t export_name_pointer_table_entry;
+typedef support::ulittle16_t export_ordinal_table_entry;
+
struct coff_symbol {
struct StringTableOffset {
support::ulittle32_t Zeroes;
@@ -169,19 +192,50 @@ struct coff_symbol {
} Name;
support::ulittle32_t Value;
- support::little16_t SectionNumber;
+ support::ulittle16_t SectionNumber;
support::ulittle16_t Type;
- support::ulittle8_t StorageClass;
- support::ulittle8_t NumberOfAuxSymbols;
+ support::ulittle8_t StorageClass;
+ support::ulittle8_t NumberOfAuxSymbols;
+
+ uint8_t getBaseType() const { return Type & 0x0F; }
+
+ uint8_t getComplexType() const { return (Type & 0xF0) >> 4; }
+
+ bool isFunctionDefinition() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+ getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
+ !COFF::isReservedSectionNumber(SectionNumber);
+ }
+
+ bool isFunctionLineInfo() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_FUNCTION;
+ }
+
+ bool isWeakExternal() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
+ (StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ SectionNumber == COFF::IMAGE_SYM_UNDEFINED && Value == 0);
+ }
+
+ bool isFileRecord() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_FILE;
+ }
- uint8_t getBaseType() const {
- return Type & 0x0F;
+ bool isSectionDefinition() const {
+ // C++/CLI creates external ABS symbols for non-const appdomain globals.
+ // These are also followed by an auxiliary section definition.
+ bool isAppdomainGlobal = StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ SectionNumber == COFF::IMAGE_SYM_ABSOLUTE;
+ bool isOrdinarySection =
+ StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && Value == 0;
+ return isAppdomainGlobal || isOrdinarySection;
}
- uint8_t getComplexType() const {
- return (Type & 0xF0) >> 4;
+ bool isCLRToken() const {
+ return StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
}
};
@@ -196,6 +250,13 @@ struct coff_section {
support::ulittle16_t NumberOfRelocations;
support::ulittle16_t NumberOfLinenumbers;
support::ulittle32_t Characteristics;
+
+ // Returns true if the actual number of relocations is stored in
+ // VirtualAddress field of the first relocation table entry.
+ bool hasExtendedRelocations() const {
+ return Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL &&
+ NumberOfRelocations == UINT16_MAX;
+ };
};
struct coff_relocation {
@@ -204,6 +265,22 @@ struct coff_relocation {
support::ulittle16_t Type;
};
+struct coff_aux_function_definition {
+ support::ulittle32_t TagIndex;
+ support::ulittle32_t TotalSize;
+ support::ulittle32_t PointerToLinenumber;
+ support::ulittle32_t PointerToNextFunction;
+ char Unused[2];
+};
+
+struct coff_aux_bf_and_ef_symbol {
+ char Unused1[4];
+ support::ulittle16_t Linenumber;
+ char Unused2[6];
+ support::ulittle32_t PointerToNextFunction;
+ char Unused3[2];
+};
+
struct coff_aux_weak_external {
support::ulittle32_t TagIndex;
support::ulittle32_t Characteristics;
@@ -220,104 +297,143 @@ struct coff_aux_section_definition {
char Unused[3];
};
+struct coff_aux_clr_token {
+ support::ulittle8_t AuxType;
+ support::ulittle8_t Reserved;
+ support::ulittle32_t SymbolTableIndex;
+ char Unused[12];
+};
+
+struct coff_load_configuration32 {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t GlobalFlagsClear;
+ support::ulittle32_t GlobalFlagsSet;
+ support::ulittle32_t CriticalSectionDefaultTimeout;
+ support::ulittle32_t DeCommitFreeBlockThreshold;
+ support::ulittle32_t DeCommitTotalFreeThreshold;
+ support::ulittle32_t LockPrefixTable;
+ support::ulittle32_t MaximumAllocationSize;
+ support::ulittle32_t VirtualMemoryThreshold;
+ support::ulittle32_t ProcessAffinityMask;
+ support::ulittle32_t ProcessHeapFlags;
+ support::ulittle16_t CSDVersion;
+ uint16_t Reserved;
+ support::ulittle32_t EditList;
+ support::ulittle32_t SecurityCookie;
+ support::ulittle32_t SEHandlerTable;
+ support::ulittle32_t SEHandlerCount;
+};
+
+struct coff_runtime_function_x64 {
+ support::ulittle32_t BeginAddress;
+ support::ulittle32_t EndAddress;
+ support::ulittle32_t UnwindInformation;
+};
+
class COFFObjectFile : public ObjectFile {
private:
friend class ImportDirectoryEntryRef;
+ friend class ExportDirectoryEntryRef;
const coff_file_header *COFFHeader;
- const pe32_header *PE32Header;
- const data_directory *DataDirectory;
- const coff_section *SectionTable;
- const coff_symbol *SymbolTable;
- const char *StringTable;
- uint32_t StringTableSize;
+ const pe32_header *PE32Header;
+ const pe32plus_header *PE32PlusHeader;
+ const data_directory *DataDirectory;
+ const coff_section *SectionTable;
+ const coff_symbol *SymbolTable;
+ const char *StringTable;
+ uint32_t StringTableSize;
const import_directory_table_entry *ImportDirectory;
- uint32_t NumberOfImportDirectory;
+ uint32_t NumberOfImportDirectory;
+ const export_directory_table_entry *ExportDirectory;
- error_code getString(uint32_t offset, StringRef &Res) const;
+ 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;
+ const coff_symbol *toSymb(DataRefImpl Symb) const;
+ const coff_section *toSec(DataRefImpl Sec) const;
+ const coff_relocation *toRel(DataRefImpl Rel) const;
- error_code initSymbolTablePtr();
- error_code initImportTablePtr();
+ error_code initSymbolTablePtr();
+ error_code initImportTablePtr();
+ error_code initExportTablePtr();
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 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 getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
-
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
- 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 isSectionReadOnlyData(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 section_rel_begin(DataRefImpl Sec) const;
- virtual relocation_iterator section_rel_end(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 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
- virtual error_code getRelocationType(DataRefImpl Rel,
- uint64_t &Res) const;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) 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;
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override;
+ error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override;
+ error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override;
+ error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override;
+ error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ bool section_rel_empty(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override;
+ error_code
+ getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ error_code
+ getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Result) const override;
+ error_code getLibraryPath(DataRefImpl LibData,
+ StringRef &Result) const override;
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;
-
- const coff_section *getCOFFSection(section_iterator &It) const;
- const coff_symbol *getCOFFSymbol(symbol_iterator &It) const;
- const coff_relocation *getCOFFRelocation(relocation_iterator &It) const;
-
- virtual uint8_t getBytesInAddress() const;
- virtual StringRef getFileFormatName() const;
- virtual unsigned getArch() const;
- virtual StringRef getLoadName() const;
+ COFFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true);
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
+ library_iterator needed_library_begin() const override;
+ library_iterator needed_library_end() const override;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ const coff_section *getCOFFSection(const SectionRef &Section) const;
+ const coff_symbol *getCOFFSymbol(const SymbolRef &Symbol) const;
+ const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ unsigned getArch() const override;
+ StringRef getLoadName() const override;
import_directory_iterator import_directory_begin() const;
import_directory_iterator import_directory_end() const;
+ export_directory_iterator export_directory_begin() const;
+ export_directory_iterator export_directory_end() const;
error_code getHeader(const coff_file_header *&Res) const;
error_code getCOFFHeader(const coff_file_header *&Res) const;
error_code getPE32Header(const pe32_header *&Res) const;
+ error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
error_code getDataDirectory(uint32_t index, const data_directory *&Res) const;
error_code getSection(int32_t index, const coff_section *&Res) const;
error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
@@ -325,7 +441,7 @@ public:
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);
+ Res = reinterpret_cast<const T *>(s);
return ec;
}
error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
@@ -335,24 +451,23 @@ public:
error_code getSectionContents(const coff_section *Sec,
ArrayRef<uint8_t> &Res) const;
+ error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const;
- static inline bool classof(const Binary *v) {
- return v->isCOFF();
- }
+ static inline bool classof(const Binary *v) { return v->isCOFF(); }
};
// The iterator for the import directory table.
class ImportDirectoryEntryRef {
public:
ImportDirectoryEntryRef() : OwningObject(0) {}
- ImportDirectoryEntryRef(DataRefImpl ImportDirectory,
+ ImportDirectoryEntryRef(const import_directory_table_entry *Table, uint32_t I,
const COFFObjectFile *Owner)
- : ImportDirectoryPimpl(ImportDirectory), OwningObject(Owner) {}
+ : ImportTable(Table), Index(I), OwningObject(Owner) {}
bool operator==(const ImportDirectoryEntryRef &Other) const;
- error_code getNext(ImportDirectoryEntryRef &Result) const;
+ void moveNext();
error_code getName(StringRef &Result) const;
error_code
@@ -362,7 +477,31 @@ public:
getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
private:
- DataRefImpl ImportDirectoryPimpl;
+ const import_directory_table_entry *ImportTable;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject;
+};
+
+// The iterator for the export directory table entry.
+class ExportDirectoryEntryRef {
+public:
+ ExportDirectoryEntryRef() : OwningObject(0) {}
+ ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
+ const COFFObjectFile *Owner)
+ : ExportTable(Table), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ExportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ error_code getDllName(StringRef &Result) const;
+ error_code getOrdinalBase(uint32_t &Result) const;
+ error_code getOrdinal(uint32_t &Result) const;
+ error_code getExportRVA(uint32_t &Result) const;
+ error_code getSymbolName(StringRef &Result) const;
+
+private:
+ const export_directory_table_entry *ExportTable;
+ uint32_t Index;
const COFFObjectFile *OwningObject;
};
} // end namespace object
diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h
index 3fa3ec6..b5f9ccc 100644
--- a/include/llvm/Object/COFFYAML.h
+++ b/include/llvm/Object/COFFYAML.h
@@ -14,6 +14,7 @@
#ifndef LLVM_OBJECT_COFFYAML_H
#define LLVM_OBJECT_COFFYAML_H
+#include "llvm/ADT/Optional.h"
#include "llvm/Object/YAML.h"
#include "llvm/Support/COFF.h"
@@ -35,6 +36,10 @@ inline SectionCharacteristics operator|(SectionCharacteristics a,
// The structure of the yaml files is not an exact 1:1 match to COFF. In order
// to use yaml::IO, we use these structures which are closer to the source.
namespace COFFYAML {
+ LLVM_YAML_STRONG_TYPEDEF(uint8_t, COMDATType)
+ LLVM_YAML_STRONG_TYPEDEF(uint32_t, WeakExternalCharacteristics)
+ LLVM_YAML_STRONG_TYPEDEF(uint8_t, AuxSymbolType)
+
struct Relocation {
uint32_t VirtualAddress;
uint16_t Type;
@@ -54,7 +59,12 @@ namespace COFFYAML {
COFF::symbol Header;
COFF::SymbolBaseType SimpleType;
COFF::SymbolComplexType ComplexType;
- object::yaml::BinaryRef AuxiliaryData;
+ Optional<COFF::AuxiliaryFunctionDefinition> FunctionDefinition;
+ Optional<COFF::AuxiliarybfAndefSymbol> bfAndefSymbol;
+ Optional<COFF::AuxiliaryWeakExternal> WeakExternal;
+ StringRef File;
+ Optional<COFF::AuxiliarySectionDefinition> SectionDefinition;
+ Optional<COFF::AuxiliaryCLRToken> CLRToken;
StringRef Name;
Symbol();
};
@@ -76,6 +86,21 @@ namespace llvm {
namespace yaml {
template <>
+struct ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics> {
+ static void enumeration(IO &IO, COFFYAML::WeakExternalCharacteristics &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::AuxSymbolType> {
+ static void enumeration(IO &IO, COFFYAML::AuxSymbolType &Value);
+};
+
+template <>
+struct ScalarEnumerationTraits<COFFYAML::COMDATType> {
+ static void enumeration(IO &IO, COFFYAML::COMDATType &Value);
+};
+
+template <>
struct ScalarEnumerationTraits<COFF::MachineTypes> {
static void enumeration(IO &IO, COFF::MachineTypes &Value);
};
@@ -120,6 +145,26 @@ struct MappingTraits<COFF::header> {
static void mapping(IO &IO, COFF::header &H);
};
+template <> struct MappingTraits<COFF::AuxiliaryFunctionDefinition> {
+ static void mapping(IO &IO, COFF::AuxiliaryFunctionDefinition &AFD);
+};
+
+template <> struct MappingTraits<COFF::AuxiliarybfAndefSymbol> {
+ static void mapping(IO &IO, COFF::AuxiliarybfAndefSymbol &AAS);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryWeakExternal> {
+ static void mapping(IO &IO, COFF::AuxiliaryWeakExternal &AWE);
+};
+
+template <> struct MappingTraits<COFF::AuxiliarySectionDefinition> {
+ static void mapping(IO &IO, COFF::AuxiliarySectionDefinition &ASD);
+};
+
+template <> struct MappingTraits<COFF::AuxiliaryCLRToken> {
+ static void mapping(IO &IO, COFF::AuxiliaryCLRToken &ACT);
+};
+
template <>
struct MappingTraits<COFFYAML::Symbol> {
static void mapping(IO &IO, COFFYAML::Symbol &S);
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 6c000bb..824e06e 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -33,8 +33,6 @@
#include <limits>
#include <utility>
-#include <ctype.h>
-
namespace llvm {
namespace object {
@@ -53,8 +51,8 @@ template <class ELFT>
class ELFFile {
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- typedef typename conditional<ELFT::Is64Bits,
- uint64_t, uint32_t>::type uintX_t;
+ typedef typename std::conditional<ELFT::Is64Bits,
+ uint64_t, uint32_t>::type uintX_t;
/// \brief Iterate over constant sized entities.
template <class EntT>
diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
index 962a3e2..2958067 100644
--- a/include/llvm/Object/ELFObjectFile.h
+++ b/include/llvm/Object/ELFObjectFile.h
@@ -44,6 +44,7 @@ public:
typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+ typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela;
typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
@@ -55,53 +56,52 @@ public:
protected:
ELFFile<ELFT> EF;
- 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 getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &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 getSymbolValue(DataRefImpl Symb, uint64_t &Val) 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 isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const;
- virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const;
- virtual relocation_iterator section_rel_end(DataRefImpl Sec) const;
- virtual section_iterator getRelocatedSection(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 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
- virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
- virtual error_code
- getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const;
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override;
+ error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override;
+ error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const override;
+ error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
+
+ error_code getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const override;
+ error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override;
+ error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override;
+ error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override;
+ error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ bool section_rel_empty(DataRefImpl Sec) const override;
+ section_iterator getRelocatedSection(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override;
+ error_code getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ error_code getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
uint64_t getROffset(DataRefImpl Rel) const;
StringRef getRelocationTypeName(uint32_t Type) const;
@@ -165,31 +165,31 @@ protected:
bool isDyldELFObject;
public:
- ELFObjectFile(MemoryBuffer *Object, error_code &ec);
+ ELFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true);
const Elf_Sym *getSymbol(DataRefImpl Symb) const;
- virtual symbol_iterator begin_symbols() const;
- virtual symbol_iterator end_symbols() const;
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
- virtual symbol_iterator begin_dynamic_symbols() const;
- virtual symbol_iterator end_dynamic_symbols() const;
+ symbol_iterator dynamic_symbol_begin() const;
+ symbol_iterator dynamic_symbol_end() const;
- virtual section_iterator begin_sections() const;
- virtual section_iterator end_sections() const;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
- virtual library_iterator begin_libraries_needed() const;
- virtual library_iterator end_libraries_needed() const;
+ library_iterator needed_library_begin() const override;
+ library_iterator needed_library_end() const override;
error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const;
error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
bool &IsDefault) const;
- virtual uint8_t getBytesInAddress() const;
- virtual StringRef getFileFormatName() const;
- virtual StringRef getObjectType() const { return "ELF"; }
- virtual unsigned getArch() const;
- virtual StringRef getLoadName() const;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ unsigned getArch() const override;
+ StringRef getLoadName() const override;
const ELFFile<ELFT> *getELFFile() const { return &EF; }
@@ -208,10 +208,8 @@ typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile;
typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile;
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb,
- SymbolRef &Result) const {
- Result = SymbolRef(toDRI(++toELFSymIter(Symb)), this);
- return object_error::success;
+void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const {
+ Symb = toDRI(++toELFSymIter(Symb));
}
template <class ELFT>
@@ -219,7 +217,7 @@ error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb));
if (!Name)
- return Name;
+ return Name.getError();
Result = *Name;
return object_error::success;
}
@@ -233,49 +231,15 @@ error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
ErrorOr<StringRef> Ver =
EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault);
if (!Ver)
- return Ver;
+ return Ver.getError();
Version = *Ver;
return object_error::success;
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb,
- uint64_t &Result) const {
- const Elf_Sym *ESym = getSymbol(Symb);
- const Elf_Shdr *ESec;
- switch (EF.getSymbolTableIndex(ESym)) {
- 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 = ESym->st_value;
- return object_error::success;
- default:
- ESec = EF.getSection(ESym);
- }
-
- switch (ESym->getType()) {
- case ELF::STT_SECTION:
- Result = ESec ? ESec->sh_offset : UnknownAddressOrSize;
- return object_error::success;
- case ELF::STT_FUNC:
- case ELF::STT_OBJECT:
- case ELF::STT_NOTYPE:
- Result = ESym->st_value + (ESec ? ESec->sh_offset : 0);
- return object_error::success;
- default:
- Result = UnknownAddressOrSize;
- return object_error::success;
- }
-}
-
-template <class ELFT>
error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
uint64_t &Result) const {
const Elf_Sym *ESym = getSymbol(Symb);
- const Elf_Shdr *ESec;
switch (EF.getSymbolTableIndex(ESym)) {
case ELF::SHN_COMMON:
case ELF::SHN_UNDEF:
@@ -285,38 +249,21 @@ error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
Result = ESym->st_value;
return object_error::success;
default:
- ESec = EF.getSection(ESym);
+ break;
}
- switch (ESym->getType()) {
- case ELF::STT_SECTION:
- Result = ESec ? ESec->sh_addr : UnknownAddressOrSize;
- return object_error::success;
- case ELF::STT_FUNC:
- case ELF::STT_OBJECT:
- case ELF::STT_NOTYPE:
- bool IsRelocatable;
- switch (EF.getHeader()->e_type) {
- case ELF::ET_EXEC:
- case ELF::ET_DYN:
- IsRelocatable = false;
- break;
- default:
- IsRelocatable = true;
- }
- Result = ESym->st_value;
+ const Elf_Ehdr *Header = EF.getHeader();
+ Result = ESym->st_value;
- // Clear the ARM/Thumb indicator flag.
- if (EF.getHeader()->e_machine == ELF::EM_ARM)
- Result &= ~1;
+ // Clear the ARM/Thumb indicator flag.
+ if (EF.getHeader()->e_machine == ELF::EM_ARM &&
+ ESym->getType() == ELF::STT_FUNC)
+ Result &= ~1;
- if (IsRelocatable && ESec != 0)
- Result += ESec->sh_addr;
- return object_error::success;
- default:
- Result = UnknownAddressOrSize;
- return object_error::success;
- }
+ if (Header->e_type == ELF::ET_REL)
+ Result += EF.getSection(ESym)->sh_addr;
+
+ return object_error::success;
}
template <class ELFT>
@@ -368,11 +315,11 @@ error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
- uint32_t &Result) const {
- const Elf_Sym *ESym = getSymbol(Symb);
+uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const {
+ Elf_Sym_Iter EIter = toELFSymIter(Symb);
+ const Elf_Sym *ESym = &*EIter;
- Result = SymbolRef::SF_None;
+ uint32_t Result = SymbolRef::SF_None;
if (ESym->getBinding() != ELF::STB_LOCAL)
Result |= SymbolRef::SF_Global;
@@ -384,7 +331,7 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
Result |= SymbolRef::SF_Absolute;
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
- ESym == &*EF.begin_symbols())
+ EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols())
Result |= SymbolRef::SF_FormatSpecific;
if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
@@ -394,10 +341,7 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON)
Result |= SymbolRef::SF_Common;
- if (ESym->getType() == ELF::STT_TLS)
- Result |= SymbolRef::SF_ThreadLocal;
-
- return object_error::success;
+ return Result;
}
template <class ELFT>
@@ -406,7 +350,7 @@ error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
const Elf_Sym *ESym = getSymbol(Symb);
const Elf_Shdr *ESec = EF.getSection(ESym);
if (!ESec)
- Res = end_sections();
+ Res = section_end();
else {
DataRefImpl Sec;
Sec.p = reinterpret_cast<intptr_t>(ESec);
@@ -416,18 +360,8 @@ error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
}
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb,
- uint64_t &Val) const {
- const Elf_Sym *ESym = getSymbol(Symb);
- Val = ESym->st_value;
- return object_error::success;
-}
-
-template <class ELFT>
-error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec,
- SectionRef &Result) const {
- Result = SectionRef(toDRI(++toELFShdrIter(Sec)), this);
- return object_error::success;
+void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
+ Sec = toDRI(++toELFShdrIter(Sec));
}
template <class ELFT>
@@ -435,7 +369,7 @@ error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec));
if (!Name)
- return Name;
+ return Name.getError();
Result = *Name;
return object_error::success;
}
@@ -563,15 +497,21 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
}
template <class ELFT>
+bool ELFObjectFile<ELFT>::section_rel_empty(DataRefImpl Sec) const {
+ const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ return S->sh_size == 0;
+}
+
+template <class ELFT>
section_iterator
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
if (EF.getHeader()->e_type != ELF::ET_REL)
- return end_sections();
+ return section_end();
Elf_Shdr_Iter EShdr = toELFShdrIter(Sec);
uintX_t Type = EShdr->sh_type;
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
- return end_sections();
+ return section_end();
const Elf_Shdr *R = EF.getSection(EShdr->sh_info);
return section_iterator(SectionRef(toDRI(R), this));
@@ -579,11 +519,8 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
// Relocations
template <class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
- RelocationRef &Result) const {
+void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
++Rel.d.b;
- Result = RelocationRef(Rel, this);
- return object_error::success;
}
template <class ELFT>
@@ -604,7 +541,7 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
}
}
if (!symbolIdx)
- return end_symbols();
+ return symbol_end();
const Elf_Shdr *SymSec = EF.getSection(sec->sh_link);
@@ -626,6 +563,9 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
template <class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
uint64_t &Result) const {
+ assert((EF.getHeader()->e_type == ELF::ET_EXEC ||
+ EF.getHeader()->e_type == ELF::ET_DYN) &&
+ "Only executable and shared objects files have relocation addresses");
Result = getROffset(Rel);
return object_error::success;
}
@@ -633,6 +573,8 @@ error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
template <class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
uint64_t &Result) const {
+ assert(EF.getHeader()->e_type == ELF::ET_REL &&
+ "Only relocatable object files have relocation offsets");
Result = getROffset(Rel);
return object_error::success;
}
@@ -743,7 +685,7 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString(
ErrorOr<StringRef> SymName =
EF.getSymbolName(EF.getSection(sec->sh_link), symb);
if (!SymName)
- return SymName;
+ return SymName.getError();
switch (EF.getHeader()->e_machine) {
case ELF::EM_X86_64:
switch (type) {
@@ -783,6 +725,7 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString(
}
case ELF::EM_ARM:
case ELF::EM_HEXAGON:
+ case ELF::EM_MIPS:
res = *SymName;
break;
default:
@@ -812,40 +755,41 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
}
template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec,
+ bool BufferOwned)
: ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
support::little,
ELFT::Is64Bits),
- Object),
+ Object, BufferOwned),
EF(Object, ec) {}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const {
- return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const {
+ return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this));
}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::end_symbols() const {
- return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
+ return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this));
}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const {
+symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
}
template <class ELFT>
-symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const {
+symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
}
template <class ELFT>
-section_iterator ELFObjectFile<ELFT>::begin_sections() const {
+section_iterator ELFObjectFile<ELFT>::section_begin() const {
return section_iterator(SectionRef(toDRI(EF.begin_sections()), this));
}
template <class ELFT>
-section_iterator ELFObjectFile<ELFT>::end_sections() const {
+section_iterator ELFObjectFile<ELFT>::section_end() const {
return section_iterator(SectionRef(toDRI(EF.end_sections()), this));
}
@@ -863,7 +807,7 @@ StringRef ELFObjectFile<ELFT>::getLoadName() const {
}
template <class ELFT>
-library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const {
+library_iterator ELFObjectFile<ELFT>::needed_library_begin() const {
Elf_Dyn_Iter DI = EF.begin_dynamic_table();
Elf_Dyn_Iter DE = EF.end_dynamic_table();
@@ -896,7 +840,7 @@ error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
}
template <class ELFT>
-library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const {
+library_iterator ELFObjectFile<ELFT>::needed_library_end() const {
return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this));
}
@@ -922,6 +866,9 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF32-mips";
case ELF::EM_PPC:
return "ELF32-ppc";
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return "ELF32-sparc";
default:
return "ELF32-unknown";
}
@@ -937,6 +884,10 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
return "ELF64-ppc64";
case ELF::EM_S390:
return "ELF64-s390";
+ case ELF::EM_SPARCV9:
+ return "ELF64-sparc";
+ case ELF::EM_MIPS:
+ return "ELF64-mips";
default:
return "ELF64-unknown";
}
@@ -967,6 +918,13 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
: Triple::ppc64;
case ELF::EM_S390:
return Triple::systemz;
+
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return Triple::sparc;
+ case ELF::EM_SPARCV9:
+ return Triple::sparcv9;
+
default:
return Triple::UnknownArch;
}
@@ -974,8 +932,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
/// FIXME: Maybe we should have a base ElfObjectFile that is not a template
/// and make these member functions?
-static inline error_code getELFRelocationAddend(const RelocationRef R,
- int64_t &Addend) {
+inline error_code getELFRelocationAddend(const RelocationRef R,
+ int64_t &Addend) {
const ObjectFile *Obj = R.getObjectFile();
DataRefImpl DRI = R.getRawDataRefImpl();
// Little-endian 32-bit
@@ -997,12 +955,30 @@ static inline error_code getELFRelocationAddend(const RelocationRef R,
llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF");
}
+inline std::pair<symbol_iterator, symbol_iterator>
+getELFDynamicSymbolIterators(SymbolicFile *Obj) {
+ if (const ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+ if (const ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+ if (const ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+ if (const ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(Obj))
+ return std::make_pair(ELF->dynamic_symbol_begin(),
+ ELF->dynamic_symbol_end());
+
+ llvm_unreachable(
+ "Object passed to getELFDynamicSymbolIterators() is not ELF");
+}
+
/// 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) {
+inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
+ const SymbolRef &Sym, StringRef &Version,
+ bool &IsDefault) {
// Little-endian 32-bit
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index fca965f..1eba660 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -37,6 +37,8 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
+// Just use 64, since it can hold 32-bit values too.
+LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
// Just use 64, since it can hold 32-bit values too.
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
@@ -50,6 +52,7 @@ struct FileHeader {
ELF_ELFOSABI OSABI;
ELF_ET Type;
ELF_EM Machine;
+ ELF_EF Flags;
llvm::yaml::Hex64 Entry;
};
struct Symbol {
@@ -118,6 +121,11 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
};
template <>
+struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
+ static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
+};
+
+template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
};
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
index 8b0570b..779c747 100644
--- a/include/llvm/Object/Error.h
+++ b/include/llvm/Object/Error.h
@@ -41,10 +41,10 @@ inline error_code make_error_code(object_error e) {
} // end namespace object.
-template <> struct is_error_code_enum<object::object_error> : true_type { };
+template <> struct is_error_code_enum<object::object_error> : std::true_type {};
-template <> struct is_error_code_enum<object::object_error::Impl> : true_type {
-};
+template <>
+struct is_error_code_enum<object::object_error::Impl> : std::true_type {};
} // end namespace llvm.
diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h
new file mode 100644
index 0000000..78f5b2b
--- /dev/null
+++ b/include/llvm/Object/IRObjectFile.h
@@ -0,0 +1,46 @@
+//===- IRObjectFile.h - LLVM IR 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 IRObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IR_OBJECT_FILE_H
+#define LLVM_OBJECT_IR_OBJECT_FILE_H
+
+#include "llvm/Object/SymbolicFile.h"
+
+namespace llvm {
+class Mangler;
+class Module;
+class GlobalValue;
+
+namespace object {
+class IRObjectFile : public SymbolicFile {
+ std::unique_ptr<Module> M;
+ std::unique_ptr<Mangler> Mang;
+
+public:
+ IRObjectFile(MemoryBuffer *Object, error_code &EC, LLVMContext &Context,
+ bool BufferOwned);
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ const GlobalValue &getSymbolGV(DataRefImpl Symb) const;
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
+
+ static inline bool classof(const Binary *v) {
+ return v->isIR();
+ }
+};
+}
+}
+
+#endif
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 100613a..f242611 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -38,7 +38,7 @@ public:
bool operator==(const DiceRef &Other) const;
bool operator<(const DiceRef &Other) const;
- error_code getNext(DiceRef &Result) const;
+ void moveNext();
error_code getOffset(uint32_t &Result) const;
error_code getLength(uint16_t &Result) const;
@@ -57,76 +57,73 @@ public:
};
MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
- error_code &ec);
-
- virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
- virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
- virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
- virtual error_code getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Res) const;
- virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
- virtual error_code getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const;
- virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
-
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
- virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
- 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 isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
- virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
- bool &Result) const;
- virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const;
- virtual relocation_iterator section_rel_end(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 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
- virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
- virtual error_code getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) 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;
+ error_code &EC, bool BufferOwned = true);
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override;
+ error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override;
+ error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const override;
+ error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override;
+ error_code getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Res) const override;
+ uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ error_code getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override;
+ error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override;
+ error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override;
+ error_code isSectionText(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionData(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionRequiredForExecution(DataRefImpl Sec,
+ bool &Res) const override;
+ error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override;
+ error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override;
+ error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
+ bool &Result) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ bool section_rel_empty(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ error_code getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Res) const override;
+ error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override;
+ error_code getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ error_code getRelocationValueString(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override;
+
+ error_code getLibraryNext(DataRefImpl LibData,
+ LibraryRef &Res) const override;
+ error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const override;
// TODO: Would be useful to have an iterator based version
// of the load command interface too.
- virtual symbol_iterator begin_symbols() const;
- virtual symbol_iterator end_symbols() const;
+ basic_symbol_iterator symbol_begin_impl() const override;
+ basic_symbol_iterator symbol_end_impl() const override;
- virtual symbol_iterator begin_dynamic_symbols() const;
- virtual symbol_iterator end_dynamic_symbols() const;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
- virtual section_iterator begin_sections() const;
- virtual section_iterator end_sections() const;
+ library_iterator needed_library_begin() const override;
+ library_iterator needed_library_end() const override;
- virtual library_iterator begin_libraries_needed() const;
- virtual library_iterator end_libraries_needed() const;
+ uint8_t getBytesInAddress() const override;
- virtual uint8_t getBytesInAddress() const;
+ StringRef getFileFormatName() const override;
+ unsigned getArch() const override;
- virtual StringRef getFileFormatName() const;
- virtual unsigned getArch() const;
-
- virtual StringRef getLoadName() const;
+ StringRef getLoadName() const override;
relocation_iterator section_rel_begin(unsigned Index) const;
relocation_iterator section_rel_end(unsigned Index) const;
@@ -179,6 +176,8 @@ public:
getSegment64LoadCommand(const LoadCommandInfo &L) const;
MachO::linker_options_command
getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
+ MachO::version_min_command
+ getVersionMinLoadCommand(const LoadCommandInfo &L) const;
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
@@ -223,13 +222,10 @@ inline bool DiceRef::operator<(const DiceRef &Other) const {
return DicePimpl < Other.DicePimpl;
}
-inline error_code DiceRef::getNext(DiceRef &Result) const {
- DataRefImpl Rel = DicePimpl;
+inline void DiceRef::moveNext() {
const MachO::data_in_code_entry *P =
- reinterpret_cast<const MachO::data_in_code_entry *>(Rel.p);
- Rel.p = reinterpret_cast<uintptr_t>(P + 1);
- Result = DiceRef(Rel, OwningObject);
- return object_error::success;
+ reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
+ DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
}
// Since a Mach-O data in code reference, a DiceRef, can only be created when
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
index c5d1359..9b1afd2 100644
--- a/include/llvm/Object/MachOUniversal.h
+++ b/include/llvm/Object/MachOUniversal.h
@@ -14,10 +14,10 @@
#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
#define LLVM_OBJECT_MACHOUNIVERSAL_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Object/Binary.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MachO.h"
namespace llvm {
@@ -52,7 +52,7 @@ public:
ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
uint32_t getCPUType() const { return Header.cputype; }
- error_code getAsObjectFile(OwningPtr<ObjectFile> &Result) const;
+ error_code getAsObjectFile(std::unique_ptr<ObjectFile> &Result) const;
};
class object_iterator {
@@ -77,6 +77,7 @@ public:
};
MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
+ static ErrorOr<MachOUniversalBinary*> create(MemoryBuffer *Source);
object_iterator begin_objects() const {
return ObjectForArch(this, 0);
@@ -93,7 +94,7 @@ public:
}
error_code getObjectForArch(Triple::ArchType Arch,
- OwningPtr<ObjectFile> &Result) const;
+ std::unique_ptr<ObjectFile> &Result) const;
};
}
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index 9aea639..8298b63 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -15,9 +15,10 @@
#define LLVM_OBJECT_OBJECTFILE_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/Binary.h"
+#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cstring>
#include <vector>
@@ -27,65 +28,8 @@ namespace object {
class ObjectFile;
-union DataRefImpl {
- // This entire union should probably be a
- // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
- 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;
- }
-};
-
-inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
- // Check bitwise identical. This is the only legal way to compare a union w/o
- // knowing which member is in use.
- return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
-}
-
-inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
- // 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;
-typedef content_iterator<SymbolRef> symbol_iterator;
+class symbol_iterator;
/// RelocationRef - This is a value type class that represents a single
/// relocation in the list of relocations in the object file.
@@ -100,7 +44,7 @@ public:
bool operator==(const RelocationRef &Other) const;
- error_code getNext(RelocationRef &Result) const;
+ void moveNext();
error_code getAddress(uint64_t &Result) const;
error_code getOffset(uint64_t &Result) const;
@@ -143,9 +87,10 @@ public:
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
bool operator==(const SectionRef &Other) const;
+ bool operator!=(const SectionRef &Other) const;
bool operator<(const SectionRef &Other) const;
- error_code getNext(SectionRef &Result) const;
+ void moveNext();
error_code getName(StringRef &Result) const;
error_code getAddress(uint64_t &Result) const;
@@ -166,8 +111,13 @@ public:
error_code containsSymbol(SymbolRef S, bool &Result) const;
- relocation_iterator begin_relocations() const;
- relocation_iterator end_relocations() const;
+ relocation_iterator relocation_begin() const;
+ relocation_iterator relocation_end() const;
+ typedef iterator_range<relocation_iterator> relocation_iterator_range;
+ relocation_iterator_range relocations() const {
+ return relocation_iterator_range(relocation_begin(), relocation_end());
+ }
+ bool relocation_empty() const;
section_iterator getRelocatedSection() const;
DataRefImpl getRawDataRefImpl() const;
@@ -175,13 +125,11 @@ public:
/// SymbolRef - This is a value type class that represents a single symbol in
/// the list of symbols in the object file.
-class SymbolRef {
+class SymbolRef : public BasicSymbolRef {
friend class SectionRef;
- DataRefImpl SymbolPimpl;
- const ObjectFile *OwningObject;
public:
- SymbolRef() : OwningObject(NULL) { }
+ SymbolRef() : BasicSymbolRef() {}
enum Type {
ST_Unknown, // Type not specified
@@ -192,25 +140,8 @@ public:
ST_Other
};
- enum Flags LLVM_ENUM_INT_TYPE(unsigned) {
- 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;
/// Returns the symbol virtual address (i.e. address at which it will be
/// mapped).
@@ -221,17 +152,29 @@ public:
error_code getSize(uint64_t &Result) const;
error_code getType(SymbolRef::Type &Result) const;
- /// Get symbol flags (bitwise OR of SymbolRef::Flags)
- error_code getFlags(uint32_t &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;
- /// @brief Get value of the symbol in the symbol table.
- error_code getValue(uint64_t &Val) const;
+ const ObjectFile *getObject() const;
+};
- DataRefImpl getRawDataRefImpl() const;
+class symbol_iterator : public basic_symbol_iterator {
+public:
+ symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
+ symbol_iterator(const basic_symbol_iterator &B)
+ : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+ cast<ObjectFile>(B->getObject()))) {}
+
+ const SymbolRef *operator->() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef*>(&P);
+ }
+
+ const SymbolRef &operator*() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef&>(P);
+ }
};
/// LibraryRef - This is a value type class that represents a single library in
@@ -258,18 +201,16 @@ public:
};
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
/// figures out which type to create.
-class ObjectFile : public Binary {
+class ObjectFile : public SymbolicFile {
virtual void anchor();
ObjectFile() LLVM_DELETED_FUNCTION;
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
protected:
- ObjectFile(unsigned int Type, MemoryBuffer *source);
+ ObjectFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
const uint8_t *base() const {
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
@@ -284,23 +225,19 @@ protected:
// 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;
+ error_code printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
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 getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const;
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 getSymbolFlags(DataRefImpl Symb,
- uint32_t &Res) const = 0;
virtual error_code getSymbolSection(DataRefImpl Symb,
section_iterator &Res) const = 0;
- virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0;
// Same as above for SectionRef.
friend class SectionRef;
- virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
+ virtual void moveSectionNext(DataRefImpl &Sec) 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;
@@ -319,12 +256,12 @@ protected:
bool &Result) const = 0;
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
+ virtual bool section_rel_empty(DataRefImpl Sec) const = 0;
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
// Same as above for RelocationRef.
friend class RelocationRef;
- virtual error_code getRelocationNext(DataRefImpl Rel,
- RelocationRef &Res) const = 0;
+ virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
virtual error_code getRelocationAddress(DataRefImpl Rel,
uint64_t &Res) const =0;
virtual error_code getRelocationOffset(DataRefImpl Rel,
@@ -347,18 +284,21 @@ protected:
virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
public:
+ typedef iterator_range<symbol_iterator> symbol_iterator_range;
+ symbol_iterator_range symbols() const {
+ return symbol_iterator_range(symbol_begin(), symbol_end());
+ }
- 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 section_begin() const = 0;
+ virtual section_iterator section_end() const = 0;
- virtual section_iterator begin_sections() const = 0;
- virtual section_iterator end_sections() const = 0;
+ typedef iterator_range<section_iterator> section_iterator_range;
+ section_iterator_range sections() const {
+ return section_iterator_range(section_begin(), section_end());
+ }
- virtual library_iterator begin_libraries_needed() const = 0;
- virtual library_iterator end_libraries_needed() const = 0;
+ virtual library_iterator needed_library_begin() const = 0;
+ virtual library_iterator needed_library_end() const = 0;
/// @brief The number of bytes used to represent an address in this object
/// file format.
@@ -376,74 +316,95 @@ public:
/// @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 ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
+ static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
+ bool BufferOwned,
+ sys::fs::file_magic Type);
+ static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object) {
+ return createObjectFile(Object, true, sys::fs::file_magic::unknown);
+ }
+
static inline bool classof(const Binary *v) {
return v->isObject();
}
public:
- static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
- static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
- static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
+ static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object,
+ bool BufferOwned = true);
+ static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object,
+ bool BufferOwned = true);
+ static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object,
+ bool BufferOwned = true);
};
// 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);
-}
+ : BasicSymbolRef(SymbolP, Owner) {}
inline error_code SymbolRef::getName(StringRef &Result) const {
- return OwningObject->getSymbolName(SymbolPimpl, Result);
+ return getObject()->getSymbolName(getRawDataRefImpl(), Result);
}
inline error_code SymbolRef::getAddress(uint64_t &Result) const {
- return OwningObject->getSymbolAddress(SymbolPimpl, Result);
+ return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
}
inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
- return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
+ uint64_t Address;
+ if (error_code EC = getAddress(Address))
+ return EC;
+ if (Address == UnknownAddressOrSize) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+
+ const ObjectFile *Obj = getObject();
+ section_iterator SecI(Obj->section_begin());
+ if (error_code EC = getSection(SecI))
+ return EC;
+
+ if (SecI == Obj->section_end()) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
+
+ uint64_t SectionAddress;
+ if (error_code EC = SecI->getAddress(SectionAddress))
+ return EC;
+
+ uint64_t OffsetInSection = Address - SectionAddress;
+
+ StringRef SecContents;
+ if (error_code EC = SecI->getContents(SecContents))
+ return EC;
+
+ // FIXME: this is a hack.
+ uint64_t SectionOffset = (uint64_t)SecContents.data() - (uint64_t)Obj->base();
+
+ Result = SectionOffset + OffsetInSection;
+ return object_error::success;
}
inline error_code SymbolRef::getAlignment(uint32_t &Result) const {
- return OwningObject->getSymbolAlignment(SymbolPimpl, Result);
+ return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result);
}
inline error_code SymbolRef::getSize(uint64_t &Result) const {
- return OwningObject->getSymbolSize(SymbolPimpl, Result);
-}
-
-inline error_code SymbolRef::getFlags(uint32_t &Result) const {
- return OwningObject->getSymbolFlags(SymbolPimpl, Result);
+ return getObject()->getSymbolSize(getRawDataRefImpl(), Result);
}
inline error_code SymbolRef::getSection(section_iterator &Result) const {
- return OwningObject->getSymbolSection(SymbolPimpl, Result);
+ return getObject()->getSymbolSection(getRawDataRefImpl(), Result);
}
inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
- return OwningObject->getSymbolType(SymbolPimpl, Result);
-}
-
-inline error_code SymbolRef::getValue(uint64_t &Val) const {
- return OwningObject->getSymbolValue(SymbolPimpl, Val);
+ return getObject()->getSymbolType(getRawDataRefImpl(), Result);
}
-inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
- return SymbolPimpl;
+inline const ObjectFile *SymbolRef::getObject() const {
+ const SymbolicFile *O = BasicSymbolRef::getObject();
+ return cast<ObjectFile>(O);
}
@@ -457,12 +418,16 @@ 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 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 void SectionRef::moveNext() {
+ return OwningObject->moveSectionNext(SectionPimpl);
}
inline error_code SectionRef::getName(StringRef &Result) const {
@@ -514,18 +479,22 @@ inline error_code SectionRef::isReadOnlyData(bool &Result) const {
}
inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
- return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
- Result);
+ return OwningObject->sectionContainsSymbol(SectionPimpl,
+ S.getRawDataRefImpl(), Result);
}
-inline relocation_iterator SectionRef::begin_relocations() const {
+inline relocation_iterator SectionRef::relocation_begin() const {
return OwningObject->section_rel_begin(SectionPimpl);
}
-inline relocation_iterator SectionRef::end_relocations() const {
+inline relocation_iterator SectionRef::relocation_end() const {
return OwningObject->section_rel_end(SectionPimpl);
}
+inline bool SectionRef::relocation_empty() const {
+ return OwningObject->section_rel_empty(SectionPimpl);
+}
+
inline section_iterator SectionRef::getRelocatedSection() const {
return OwningObject->getRelocatedSection(SectionPimpl);
}
@@ -544,8 +513,8 @@ 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 void RelocationRef::moveNext() {
+ return OwningObject->moveRelocationNext(RelocationPimpl);
}
inline error_code RelocationRef::getAddress(uint64_t &Result) const {
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 97912fe..a3aaf17 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -17,8 +17,8 @@
#define LLVM_OBJECT_RELOCVISITOR_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
@@ -33,7 +33,6 @@ struct RelocToApply {
// The width of the value; how many bytes to touch when applying the
// relocation.
char Width;
- RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) {}
RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
RelocToApply() : Value(0), Width(0) {}
};
@@ -103,6 +102,16 @@ public:
HasError = true;
return RelocToApply();
}
+ } else if (FileFormat == "ELF64-mips") {
+ switch (RelocType) {
+ case llvm::ELF::R_MIPS_32:
+ return visitELF_MIPS_32(R, Value);
+ case llvm::ELF::R_MIPS_64:
+ return visitELF_MIPS_64(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
} else if (FileFormat == "ELF64-aarch64") {
switch (RelocType) {
case llvm::ELF::R_AARCH64_ABS32:
@@ -123,6 +132,35 @@ public:
HasError = true;
return RelocToApply();
}
+ } else if (FileFormat == "ELF32-sparc") {
+ switch (RelocType) {
+ case llvm::ELF::R_SPARC_32:
+ case llvm::ELF::R_SPARC_UA32:
+ return visitELF_SPARC_32(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF64-sparc") {
+ switch (RelocType) {
+ case llvm::ELF::R_SPARC_32:
+ case llvm::ELF::R_SPARC_UA32:
+ return visitELF_SPARCV9_32(R, Value);
+ case llvm::ELF::R_SPARC_64:
+ case llvm::ELF::R_SPARC_UA64:
+ return visitELF_SPARCV9_64(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF32-arm") {
+ switch (RelocType) {
+ default:
+ HasError = true;
+ return RelocToApply();
+ case llvm::ELF::R_ARM_ABS32:
+ return visitELF_ARM_ABS32(R, Value);
+ }
}
HasError = true;
return RelocToApply();
@@ -239,6 +277,13 @@ private:
return RelocToApply(Res, 4);
}
+ RelocToApply visitELF_MIPS_64(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ getELFRelocationAddend(R, Addend);
+ uint64_t Res = (Value + Addend);
+ return RelocToApply(Res, 8);
+ }
+
// AArch64 ELF
RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) {
int64_t Addend = getAddend64LE(R);
@@ -272,6 +317,27 @@ private:
int64_t Addend = getAddend64BE(R);
return RelocToApply(Value + Addend, 8);
}
+
+ RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
+ int32_t Addend = getAddend32BE(R);
+ return RelocToApply(Value + Addend, 4);
+ }
+
+ RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
+ int32_t Addend = getAddend64BE(R);
+ return RelocToApply(Value + Addend, 4);
+ }
+
+ RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getAddend64BE(R);
+ return RelocToApply(Value + Addend, 8);
+ }
+
+ RelocToApply visitELF_ARM_ABS32(RelocationRef R, uint64_t Value) {
+ int64_t Addend = getAddend32LE(R);
+ return RelocToApply(Value + Addend, 4);
+ }
+
};
}
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
new file mode 100644
index 0000000..bead2c3
--- /dev/null
+++ b/include/llvm/Object/SymbolicFile.h
@@ -0,0 +1,194 @@
+//===- SymbolicFile.h - Interface that only provides 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 declares the SymbolicFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLIC_FILE_H
+#define LLVM_OBJECT_SYMBOLIC_FILE_H
+
+#include "llvm/Object/Binary.h"
+
+namespace llvm {
+namespace object {
+
+union DataRefImpl {
+ // This entire union should probably be a
+ // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
+ struct {
+ uint32_t a, b;
+ } d;
+ uintptr_t p;
+ DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
+};
+
+inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
+}
+
+inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
+ return !operator==(a, b);
+}
+
+inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
+}
+
+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 &operator++() { // preincrement
+ Current.moveNext();
+ return *this;
+ }
+};
+
+class SymbolicFile;
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class BasicSymbolRef {
+ DataRefImpl SymbolPimpl;
+ const SymbolicFile *OwningObject;
+
+public:
+ // FIXME: should we add a SF_Text?
+ enum Flags : unsigned {
+ 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_Common = 1U << 4, // Symbol has common linkage
+ SF_FormatSpecific = 1U << 5 // Specific to the object file format
+ // (e.g. section symbols)
+ };
+
+ BasicSymbolRef() : OwningObject(NULL) { }
+ BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
+
+ bool operator==(const BasicSymbolRef &Other) const;
+ bool operator<(const BasicSymbolRef &Other) const;
+
+ void moveNext();
+
+ error_code printName(raw_ostream &OS) const;
+
+ /// Get symbol flags (bitwise OR of SymbolRef::Flags)
+ uint32_t getFlags() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const SymbolicFile *getObject() const;
+};
+
+typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
+
+const uint64_t UnknownAddressOrSize = ~0ULL;
+
+class SymbolicFile : public Binary {
+public:
+ virtual ~SymbolicFile();
+ SymbolicFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned);
+
+ // virtual interface.
+ virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
+
+ virtual error_code printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const = 0;
+
+ virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
+
+ virtual basic_symbol_iterator symbol_begin_impl() const = 0;
+
+ virtual basic_symbol_iterator symbol_end_impl() const = 0;
+
+ // convenience wrappers.
+ basic_symbol_iterator symbol_begin() const {
+ return symbol_begin_impl();
+ }
+ basic_symbol_iterator symbol_end() const {
+ return symbol_end_impl();
+ }
+
+ // construction aux.
+ static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
+ LLVMContext &Context,
+ bool BufferOwned = true);
+
+ static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
+ bool BufferOwned,
+ sys::fs::file_magic Type,
+ LLVMContext *Context);
+
+ static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
+ return createSymbolicFile(Object, true, sys::fs::file_magic::unknown, 0);
+ }
+ static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);
+
+ static inline bool classof(const Binary *v) {
+ return v->isSymbolic();
+ }
+};
+
+inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
+ const SymbolicFile *Owner)
+ : SymbolPimpl(SymbolP), OwningObject(Owner) {}
+
+inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
+ return SymbolPimpl == Other.SymbolPimpl;
+}
+
+inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
+ return SymbolPimpl < Other.SymbolPimpl;
+}
+
+inline void BasicSymbolRef::moveNext() {
+ return OwningObject->moveSymbolNext(SymbolPimpl);
+}
+
+inline error_code BasicSymbolRef::printName(raw_ostream &OS) const {
+ return OwningObject->printSymbolName(OS, SymbolPimpl);
+}
+
+inline uint32_t BasicSymbolRef::getFlags() const {
+ return OwningObject->getSymbolFlags(SymbolPimpl);
+}
+
+inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
+ return SymbolPimpl;
+}
+
+inline const SymbolicFile *BasicSymbolRef::getObject() const {
+ return OwningObject;
+}
+
+}
+}
+
+#endif
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
index 06ba679..98ba6ec 100644
--- a/include/llvm/Option/ArgList.h
+++ b/include/llvm/Option/ArgList.h
@@ -307,11 +307,11 @@ public:
InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
~InputArgList();
- virtual const char *getArgString(unsigned Index) const {
+ const char *getArgString(unsigned Index) const override {
return ArgStrings[Index];
}
- virtual unsigned getNumInputArgStrings() const {
+ unsigned getNumInputArgStrings() const override {
return NumInputArgStrings;
}
@@ -323,7 +323,7 @@ public:
unsigned MakeIndex(StringRef String0) const;
unsigned MakeIndex(StringRef String0, StringRef String1) const;
- virtual const char *MakeArgString(StringRef Str) const;
+ const char *MakeArgString(StringRef Str) const override;
/// @}
};
@@ -341,11 +341,11 @@ public:
DerivedArgList(const InputArgList &BaseArgs);
~DerivedArgList();
- virtual const char *getArgString(unsigned Index) const {
+ const char *getArgString(unsigned Index) const override {
return BaseArgs.getArgString(Index);
}
- virtual unsigned getNumInputArgStrings() const {
+ unsigned getNumInputArgStrings() const override {
return BaseArgs.getNumInputArgStrings();
}
@@ -362,7 +362,7 @@ public:
SynthesizedArgs.push_back(A);
}
- virtual const char *MakeArgString(StringRef Str) const;
+ const char *MakeArgString(StringRef Str) const override;
/// AddFlagArg - Construct a new FlagArg for the given option \p Id and
/// append it to the argument list.
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
index 35ec022..ff700cf 100644
--- a/include/llvm/Pass.h
+++ b/include/llvm/Pass.h
@@ -235,17 +235,17 @@ public:
class ModulePass : public Pass {
public:
/// createPrinterPass - Get a module printer pass.
- Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
/// 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);
+ void assignPassManager(PMStack &PMS, PassManagerType T) override;
/// Return what kind of Pass Manager can manage this pass.
- virtual PassManagerType getPotentialPassManagerType() const;
+ PassManagerType getPotentialPassManagerType() const override;
explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
// Force out-of-line virtual method.
@@ -268,11 +268,11 @@ public:
///
virtual void initializePass();
- virtual ImmutablePass *getAsImmutablePass() { return this; }
+ ImmutablePass *getAsImmutablePass() override { return this; }
/// ImmutablePasses are never run.
///
- bool runOnModule(Module &) { return false; }
+ bool runOnModule(Module &) override { return false; }
explicit ImmutablePass(char &pid)
: ModulePass(pid) {}
@@ -295,18 +295,23 @@ 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;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
/// runOnFunction - Virtual method overriden by subclasses to do the
/// per-function processing of the pass.
///
virtual bool runOnFunction(Function &F) = 0;
- virtual void assignPassManager(PMStack &PMS,
- PassManagerType T);
+ void assignPassManager(PMStack &PMS, PassManagerType T) override;
/// Return what kind of Pass Manager can manage this pass.
- virtual PassManagerType getPotentialPassManagerType() const;
+ PassManagerType getPotentialPassManagerType() const override;
+
+protected:
+ /// skipOptnoneFunction - This function has Attribute::OptimizeNone
+ /// and most transformation passes should skip it.
+ bool skipOptnoneFunction(const Function &F) const;
};
@@ -326,7 +331,8 @@ 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;
+ Pass *createPrinterPass(raw_ostream &O,
+ const std::string &Banner) const override;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
@@ -346,11 +352,15 @@ public:
///
virtual bool doFinalization(Function &);
- virtual void assignPassManager(PMStack &PMS,
- PassManagerType T);
+ void assignPassManager(PMStack &PMS, PassManagerType T) override;
/// Return what kind of Pass Manager can manage this pass.
- virtual PassManagerType getPotentialPassManagerType() const;
+ PassManagerType getPotentialPassManagerType() const override;
+
+protected:
+ /// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
+ /// and most transformation passes should skip it.
+ bool skipOptnoneFunction(const BasicBlock &BB) const;
};
/// If the user specifies the -time-passes argument on an LLVM tool command line
diff --git a/include/llvm/PassRegistry.h b/include/llvm/PassRegistry.h
index f49c953..756b1b8 100644
--- a/include/llvm/PassRegistry.h
+++ b/include/llvm/PassRegistry.h
@@ -17,9 +17,9 @@
#ifndef LLVM_PASSREGISTRY_H
#define LLVM_PASSREGISTRY_H
+#include "llvm-c/Core.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm-c/Core.h"
namespace llvm {
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index ccc7934..baee77f 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -30,6 +30,7 @@
namespace llvm {
+class TargetMachine;
//===---------------------------------------------------------------------------
/// 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
@@ -39,6 +40,7 @@ namespace llvm {
class PassInfo {
public:
typedef Pass* (*NormalCtor_t)();
+ typedef Pass *(*TargetMachineCtor_t)(TargetMachine *);
private:
const char *const PassName; // Nice name for Pass
@@ -50,22 +52,26 @@ private:
std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
NormalCtor_t NormalCtor;
+ TargetMachineCtor_t TargetMachineCtor;
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)
+ NormalCtor_t normal, bool isCFGOnly, bool is_analysis,
+ TargetMachineCtor_t machine = NULL)
: PassName(name), PassArgument(arg), PassID(pi),
IsCFGOnlyPass(isCFGOnly),
- IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal) { }
+ IsAnalysis(is_analysis), IsAnalysisGroup(false), NormalCtor(normal),
+ TargetMachineCtor(machine) {}
/// 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) { }
+ IsAnalysis(false), IsAnalysisGroup(true), NormalCtor(0),
+ TargetMachineCtor(0) {}
/// getPassName - Return the friendly name for the pass, never returns null
///
@@ -107,6 +113,16 @@ public:
NormalCtor = Ctor;
}
+ /// getTargetMachineCtor - Return a pointer to a function, that when called
+ /// with a TargetMachine, creates an instance of the pass and returns it.
+ /// This pointer may be null if there is no constructor with a TargetMachine
+ /// for the pass.
+ ///
+ TargetMachineCtor_t getTargetMachineCtor() const { return TargetMachineCtor; }
+ void setTargetMachineCtor(TargetMachineCtor_t Ctor) {
+ TargetMachineCtor = Ctor;
+ }
+
/// createPass() - Use this method to create an instance of this pass.
Pass *createPass() const;
@@ -182,6 +198,10 @@ private:
template<typename PassName>
Pass *callDefaultCtor() { return new PassName(); }
+template <typename PassName> Pass *callTargetMachineCtor(TargetMachine *TM) {
+ return new PassName(TM);
+}
+
//===---------------------------------------------------------------------------
/// 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
diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h
new file mode 100644
index 0000000..d8f3ca6
--- /dev/null
+++ b/include/llvm/ProfileData/InstrProf.h
@@ -0,0 +1,56 @@
+//=-- InstrProf.h - Instrumented profiling format support ---------*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Instrumentation-based profiling data is generated by instrumented
+// binaries through library functions in compiler-rt, and read by the clang
+// frontend to feed PGO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PROFILEDATA_INSTRPROF_H_
+#define LLVM_PROFILEDATA_INSTRPROF_H_
+
+#include "llvm/Support/system_error.h"
+
+namespace llvm {
+
+const error_category &instrprof_category();
+
+struct instrprof_error {
+ enum ErrorType {
+ success = 0,
+ eof,
+ bad_magic,
+ bad_header,
+ unsupported_version,
+ too_large,
+ truncated,
+ malformed,
+ unknown_function,
+ hash_mismatch,
+ count_mismatch,
+ counter_overflow
+ };
+ ErrorType V;
+
+ instrprof_error(ErrorType V) : V(V) {}
+ operator ErrorType() const { return V; }
+};
+
+inline error_code make_error_code(instrprof_error E) {
+ return error_code(static_cast<int>(E), instrprof_category());
+}
+
+template <> struct is_error_code_enum<instrprof_error> : std::true_type {};
+template <> struct is_error_code_enum<instrprof_error::ErrorType>
+ : std::true_type {};
+
+} // end namespace llvm
+
+#endif // LLVM_PROFILEDATA_INSTRPROF_H_
diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h
new file mode 100644
index 0000000..2c070b9
--- /dev/null
+++ b/include/llvm/ProfileData/InstrProfReader.h
@@ -0,0 +1,196 @@
+//=-- InstrProfReader.h - Instrumented profiling readers ----------*- 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 support for reading profiling data for instrumentation
+// based PGO and coverage.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PROFILEDATA_INSTRPROF_READER_H_
+#define LLVM_PROFILEDATA_INSTRPROF_READER_H_
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Endian.h"
+
+#include <iterator>
+
+namespace llvm {
+
+class InstrProfReader;
+
+/// Profiling information for a single function.
+struct InstrProfRecord {
+ StringRef Name;
+ uint64_t Hash;
+ ArrayRef<uint64_t> Counts;
+};
+
+/// A file format agnostic iterator over profiling data.
+class InstrProfIterator : public std::iterator<std::input_iterator_tag,
+ InstrProfRecord> {
+ InstrProfReader *Reader;
+ InstrProfRecord Record;
+
+ void Increment();
+public:
+ InstrProfIterator() : Reader(nullptr) {}
+ InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }
+
+ InstrProfIterator &operator++() { Increment(); return *this; }
+ bool operator==(const InstrProfIterator &RHS) { return Reader == RHS.Reader; }
+ bool operator!=(const InstrProfIterator &RHS) { return Reader != RHS.Reader; }
+ InstrProfRecord &operator*() { return Record; }
+ InstrProfRecord *operator->() { return &Record; }
+};
+
+/// Base class and interface for reading profiling data of any known instrprof
+/// format. Provides an iterator over InstrProfRecords.
+class InstrProfReader {
+ error_code LastError;
+public:
+ InstrProfReader() : LastError(instrprof_error::success) {}
+ virtual ~InstrProfReader() {}
+
+ /// Read the header. Required before reading first record.
+ virtual error_code readHeader() = 0;
+ /// Read a single record.
+ virtual error_code readNextRecord(InstrProfRecord &Record) = 0;
+ /// Iterator over profile data.
+ InstrProfIterator begin() { return InstrProfIterator(this); }
+ InstrProfIterator end() { return InstrProfIterator(); }
+
+protected:
+ /// Set the current error_code and return same.
+ error_code error(error_code EC) {
+ LastError = EC;
+ return EC;
+ }
+
+ /// Clear the current error code and return a successful one.
+ error_code success() { return error(instrprof_error::success); }
+
+public:
+ /// Return true if the reader has finished reading the profile data.
+ bool isEOF() { return LastError == instrprof_error::eof; }
+ /// Return true if the reader encountered an error reading profiling data.
+ bool hasError() { return LastError && !isEOF(); }
+ /// Get the current error code.
+ error_code getError() { return LastError; }
+
+ /// Factory method to create an appropriately typed reader for the given
+ /// instrprof file.
+ static error_code create(std::string Path,
+ std::unique_ptr<InstrProfReader> &Result);
+};
+
+/// Reader for the simple text based instrprof format.
+///
+/// This format is a simple text format that's suitable for test data. Records
+/// are separated by one or more blank lines, and record fields are separated by
+/// new lines.
+///
+/// Each record consists of a function name, a function hash, a number of
+/// counters, and then each counter value, in that order.
+class TextInstrProfReader : public InstrProfReader {
+private:
+ /// The profile data file contents.
+ std::unique_ptr<MemoryBuffer> DataBuffer;
+ /// Iterator over the profile data.
+ line_iterator Line;
+ /// The current set of counter values.
+ std::vector<uint64_t> Counts;
+
+ TextInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION;
+ TextInstrProfReader &operator=(const TextInstrProfReader &)
+ LLVM_DELETED_FUNCTION;
+public:
+ TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_)
+ : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, '#') {}
+
+ /// Read the header.
+ error_code readHeader() override { return success(); }
+ /// Read a single record.
+ error_code readNextRecord(InstrProfRecord &Record) override;
+};
+
+/// Reader for the raw instrprof binary format from runtime.
+///
+/// This format is a raw memory dump of the instrumentation-baed profiling data
+/// from the runtime. It has no index.
+///
+/// Templated on the unsigned type whose size matches pointers on the platform
+/// that wrote the profile.
+template <class IntPtrT>
+class RawInstrProfReader : public InstrProfReader {
+private:
+ /// The profile data file contents.
+ std::unique_ptr<MemoryBuffer> DataBuffer;
+ /// The current set of counter values.
+ std::vector<uint64_t> Counts;
+ struct ProfileData {
+ const uint32_t NameSize;
+ const uint32_t NumCounters;
+ const uint64_t FuncHash;
+ const IntPtrT NamePtr;
+ const IntPtrT CounterPtr;
+ };
+ struct RawHeader {
+ const uint64_t Magic;
+ const uint64_t Version;
+ const uint64_t DataSize;
+ const uint64_t CountersSize;
+ const uint64_t NamesSize;
+ const uint64_t CountersDelta;
+ const uint64_t NamesDelta;
+ };
+
+ bool ShouldSwapBytes;
+ uint64_t CountersDelta;
+ uint64_t NamesDelta;
+ const ProfileData *Data;
+ const ProfileData *DataEnd;
+ const uint64_t *CountersStart;
+ const char *NamesStart;
+
+ RawInstrProfReader(const TextInstrProfReader &) LLVM_DELETED_FUNCTION;
+ RawInstrProfReader &operator=(const TextInstrProfReader &)
+ LLVM_DELETED_FUNCTION;
+public:
+ RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
+ : DataBuffer(std::move(DataBuffer)) { }
+
+ static bool hasFormat(const MemoryBuffer &DataBuffer);
+ error_code readHeader() override;
+ error_code readNextRecord(InstrProfRecord &Record) override;
+
+private:
+ error_code readHeader(const RawHeader &Header);
+ template <class IntT>
+ IntT swap(IntT Int) const {
+ return ShouldSwapBytes ? sys::SwapByteOrder(Int) : Int;
+ }
+ const uint64_t *getCounter(IntPtrT CounterPtr) const {
+ ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
+ return CountersStart + Offset;
+ }
+ const char *getName(IntPtrT NamePtr) const {
+ ptrdiff_t Offset = (swap(NamePtr) - NamesDelta) / sizeof(char);
+ return NamesStart + Offset;
+ }
+};
+
+typedef RawInstrProfReader<uint32_t> RawInstrProfReader32;
+typedef RawInstrProfReader<uint64_t> RawInstrProfReader64;
+
+} // end namespace llvm
+
+#endif // LLVM_PROFILEDATA_INSTRPROF_READER_H_
diff --git a/include/llvm/ProfileData/InstrProfWriter.h b/include/llvm/ProfileData/InstrProfWriter.h
new file mode 100644
index 0000000..f818fa0
--- /dev/null
+++ b/include/llvm/ProfileData/InstrProfWriter.h
@@ -0,0 +1,49 @@
+//=-- InstrProfWriter.h - Instrumented profiling writer -----------*- 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 support for writing profiling data for instrumentation
+// based PGO and coverage.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PROFILEDATA_INSTRPROF_WRITER_H_
+#define LLVM_PROFILEDATA_INSTRPROF_WRITER_H_
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <vector>
+
+namespace llvm {
+
+/// Writer for instrumentation based profile data.
+class InstrProfWriter {
+public:
+ struct CounterData {
+ uint64_t Hash;
+ std::vector<uint64_t> Counts;
+ };
+private:
+ StringMap<CounterData> FunctionData;
+public:
+ /// Add function counts for the given function. If there are already counts
+ /// for this function and the hash and number of counts match, each counter is
+ /// summed.
+ error_code addFunctionCounts(StringRef FunctionName, uint64_t FunctionHash,
+ ArrayRef<uint64_t> Counters);
+ /// Ensure that all data is written to disk.
+ void write(raw_ostream &OS);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_PROFILE_INSTRPROF_WRITER_H_
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
new file mode 100644
index 0000000..69732fc
--- /dev/null
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -0,0 +1,189 @@
+//===-- ARMBuildAttributes.h - ARM Build 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 enumerations and support routines for ARM build attributes
+// as defined in ARM ABI addenda document (ABI release 2.08).
+//
+// ELF for the ARM Architecture r2.09 - November 30, 2012
+//
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
+#define LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
+
+namespace llvm {
+class StringRef;
+
+namespace ARMBuildAttrs {
+
+enum SpecialAttr {
+ // This is for the .cpu asm attr. It translates into one or more
+ // AttrType (below) entries in the .ARM.attributes section in the ELF.
+ SEL_CPU
+};
+
+enum AttrType {
+ // Rest correspond to ELF/.ARM.attributes
+ File = 1,
+ CPU_raw_name = 4,
+ CPU_name = 5,
+ CPU_arch = 6,
+ CPU_arch_profile = 7,
+ ARM_ISA_use = 8,
+ THUMB_ISA_use = 9,
+ FP_arch = 10,
+ WMMX_arch = 11,
+ Advanced_SIMD_arch = 12,
+ PCS_config = 13,
+ ABI_PCS_R9_use = 14,
+ ABI_PCS_RW_data = 15,
+ ABI_PCS_RO_data = 16,
+ ABI_PCS_GOT_use = 17,
+ ABI_PCS_wchar_t = 18,
+ ABI_FP_rounding = 19,
+ ABI_FP_denormal = 20,
+ ABI_FP_exceptions = 21,
+ ABI_FP_user_exceptions = 22,
+ ABI_FP_number_model = 23,
+ ABI_align_needed = 24,
+ ABI_align_preserved = 25,
+ ABI_enum_size = 26,
+ ABI_HardFP_use = 27,
+ ABI_VFP_args = 28,
+ ABI_WMMX_args = 29,
+ ABI_optimization_goals = 30,
+ ABI_FP_optimization_goals = 31,
+ compatibility = 32,
+ CPU_unaligned_access = 34,
+ FP_HP_extension = 36,
+ ABI_FP_16bit_format = 38,
+ MPextension_use = 42, // recoded from 70 (ABI r2.08)
+ DIV_use = 44,
+ also_compatible_with = 65,
+ conformance = 67,
+ Virtualization_use = 68,
+
+ /// Legacy Tags
+ Section = 2, // deprecated (ABI r2.09)
+ Symbol = 3, // deprecated (ABI r2.09)
+ ABI_align8_needed = 24, // renamed to ABI_align_needed (ABI r2.09)
+ ABI_align8_preserved = 25, // renamed to ABI_align_preserved (ABI r2.09)
+ nodefaults = 64, // deprecated (ABI r2.09)
+ T2EE_use = 66, // deprecated (ABI r2.09)
+ MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08)
+};
+
+StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix = true);
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix = true);
+int AttrTypeFromString(StringRef Tag);
+
+// Magic numbers for .ARM.attributes
+enum AttrMagic {
+ Format_Version = 0x41
+};
+
+// Legal Values for CPU_arch, (=6), uleb128
+enum CPUArch {
+ Pre_v4 = 0,
+ v4 = 1, // e.g. SA110
+ v4T = 2, // e.g. ARM7TDMI
+ v5T = 3, // e.g. ARM9TDMI
+ v5TE = 4, // e.g. ARM946E_S
+ v5TEJ = 5, // e.g. ARM926EJ_S
+ v6 = 6, // e.g. ARM1136J_S
+ v6KZ = 7, // e.g. ARM1176JZ_S
+ v6T2 = 8, // e.g. ARM1156T2F_S
+ v6K = 9, // e.g. ARM1136J_S
+ v7 = 10, // e.g. Cortex A8, Cortex M3
+ v6_M = 11, // e.g. Cortex M1
+ v6S_M = 12, // v6_M with the System extensions
+ v7E_M = 13, // v7_M with DSP extensions
+ v8 = 14 // v8, AArch32
+};
+
+enum CPUArchProfile { // (=7), uleb128
+ Not_Applicable = 0, // pre v7, or cross-profile code
+ ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8)
+ RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4)
+ MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3)
+ SystemProfile = (0x53) // 'S' Application or real-time profile
+};
+
+// The following have a lot of common use cases
+enum {
+ Not_Allowed = 0,
+ Allowed = 1,
+
+ // Tag_ARM_ISA_use (=8), uleb128
+
+ // Tag_THUMB_ISA_use, (=9), uleb128
+ AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions)
+
+ // Tag_FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10)
+ AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA)
+ AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA)
+ AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31
+ AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA)
+ AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31
+ AllowFPARMv8A = 7, // Use of the ARM v8-A FP ISA was permitted
+ AllowFPARMv8B = 8, // Use of the ARM v8-A FP ISA was permitted, but only
+ // D0-D15, S0-S31
+
+ // Tag_WMMX_arch, (=11), uleb128
+ AllowWMMXv1 = 1, // The user permitted this entity to use WMMX v1
+ AllowWMMXv2 = 2, // The user permitted this entity to use WMMX v2
+
+ // Tag_Advanced_SIMD_arch, (=12), uleb128
+ AllowNeon = 1, // SIMDv1 was permitted
+ AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations)
+ AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
+
+ // Tag_ABI_FP_denormal, (=20), uleb128
+ PreserveFPSign = 2, // sign when flushed-to-zero is preserved
+
+ // Tag_ABI_FP_number_model, (=23), uleb128
+ AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
+ AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
+
+ // Tag_ABI_HardFP_use, (=27), uleb128
+ HardFPImplied = 0, // FP use should be implied by Tag_FP_arch
+ HardFPSinglePrecision = 1, // Single-precision only
+
+ // Tag_ABI_VFP_args, (=28), uleb128
+ BaseAAPCS = 0,
+ HardFPAAPCS = 1,
+
+ // Tag_FP_HP_extension, (=36), uleb128
+ AllowHPFP = 1, // Allow use of Half Precision FP
+
+ // Tag_MPextension_use, (=42), uleb128
+ AllowMP = 1, // Allow use of MP extensions
+
+ // Tag_DIV_use, (=44), uleb128
+ // Note: AllowDIVExt must be emitted if and only if the permission to use
+ // hardware divide cannot be conveyed using AllowDIVIfExists or DisallowDIV
+ AllowDIVIfExists = 0, // Allow hardware divide if available in arch, or no
+ // info exists.
+ DisallowDIV = 1, // Hardware divide explicitly disallowed.
+ AllowDIVExt = 2, // Allow hardware divide as optional architecture
+ // extension above the base arch specified by
+ // Tag_CPU_arch and Tag_CPU_arch_profile.
+
+ // Tag_Virtualization_use, (=68), uleb128
+ AllowTZ = 1,
+ AllowVirtualization = 2,
+ AllowTZVirtualization = 3
+};
+
+} // namespace ARMBuildAttrs
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H
diff --git a/include/llvm/Support/ARMEHABI.h b/include/llvm/Support/ARMEHABI.h
new file mode 100644
index 0000000..c7ac54a
--- /dev/null
+++ b/include/llvm/Support/ARMEHABI.h
@@ -0,0 +1,134 @@
+//===--- ARMEHABI.h - ARM Exception Handling ABI ----------------*- 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 constants for the ARM unwind opcodes and exception
+// handling table entry kinds.
+//
+// The enumerations and constants in this file reflect the ARM EHABI
+// Specification as published by ARM.
+//
+// Exception Handling ABI for the ARM Architecture r2.09 - November 30, 2012
+//
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ARM_EHABI_H
+#define LLVM_SUPPORT_ARM_EHABI_H
+
+namespace llvm {
+namespace ARM {
+namespace EHABI {
+ /// ARM exception handling table entry kinds
+ enum EHTEntryKind {
+ EHT_GENERIC = 0x00,
+ EHT_COMPACT = 0x80
+ };
+
+ enum {
+ /// Special entry for the function never unwind
+ EXIDX_CANTUNWIND = 0x1
+ };
+
+ /// ARM-defined frame unwinding opcodes
+ enum UnwindOpcodes {
+ // Format: 00xxxxxx
+ // Purpose: vsp = vsp + ((x << 2) + 4)
+ UNWIND_OPCODE_INC_VSP = 0x00,
+
+ // Format: 01xxxxxx
+ // Purpose: vsp = vsp - ((x << 2) + 4)
+ UNWIND_OPCODE_DEC_VSP = 0x40,
+
+ // Format: 10000000 00000000
+ // Purpose: refuse to unwind
+ UNWIND_OPCODE_REFUSE = 0x8000,
+
+ // Format: 1000xxxx xxxxxxxx
+ // Purpose: pop r[15:12], r[11:4]
+ // Constraint: x != 0
+ UNWIND_OPCODE_POP_REG_MASK_R4 = 0x8000,
+
+ // Format: 1001xxxx
+ // Purpose: vsp = r[x]
+ // Constraint: x != 13 && x != 15
+ UNWIND_OPCODE_SET_VSP = 0x90,
+
+ // Format: 10100xxx
+ // Purpose: pop r[(4+x):4]
+ UNWIND_OPCODE_POP_REG_RANGE_R4 = 0xa0,
+
+ // Format: 10101xxx
+ // Purpose: pop r14, r[(4+x):4]
+ UNWIND_OPCODE_POP_REG_RANGE_R4_R14 = 0xa8,
+
+ // Format: 10110000
+ // Purpose: finish
+ UNWIND_OPCODE_FINISH = 0xb0,
+
+ // Format: 10110001 0000xxxx
+ // Purpose: pop r[3:0]
+ // Constraint: x != 0
+ UNWIND_OPCODE_POP_REG_MASK = 0xb100,
+
+ // Format: 10110010 x(uleb128)
+ // Purpose: vsp = vsp + ((x << 2) + 0x204)
+ UNWIND_OPCODE_INC_VSP_ULEB128 = 0xb2,
+
+ // Format: 10110011 xxxxyyyy
+ // Purpose: pop d[(x+y):x]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX = 0xb300,
+
+ // Format: 10111xxx
+ // Purpose: pop d[(8+x):8]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX_D8 = 0xb8,
+
+ // Format: 11000xxx
+ // Purpose: pop wR[(10+x):10]
+ UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE_WR10 = 0xc0,
+
+ // Format: 11000110 xxxxyyyy
+ // Purpose: pop wR[(x+y):x]
+ UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE = 0xc600,
+
+ // Format: 11000111 0000xxxx
+ // Purpose: pop wCGR[3:0]
+ // Constraint: x != 0
+ UNWIND_OPCODE_POP_WIRELESS_MMX_REG_MASK = 0xc700,
+
+ // Format: 11001000 xxxxyyyy
+ // Purpose: pop d[(16+x+y):(16+x)]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 = 0xc800,
+
+ // Format: 11001001 xxxxyyyy
+ // Purpose: pop d[(x+y):x]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD = 0xc900,
+
+ // Format: 11010xxx
+ // Purpose: pop d[(8+x):8]
+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D8 = 0xd0
+ };
+
+ /// ARM-defined Personality Routine Index
+ enum PersonalityRoutineIndex {
+ // To make the exception handling table become more compact, ARM defined
+ // several personality routines in EHABI. There are 3 different
+ // personality routines in ARM EHABI currently. It is possible to have 16
+ // pre-defined personality routines at most.
+ AEABI_UNWIND_CPP_PR0 = 0,
+ AEABI_UNWIND_CPP_PR1 = 1,
+ AEABI_UNWIND_CPP_PR2 = 2,
+
+ NUM_PERSONALITY_INDEX
+ };
+}
+}
+}
+
+#endif // ARM_UNWIND_OP_H
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index bba3424..061d5ac 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -170,19 +170,22 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
namespace detail {
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char>
+ typename T5 = char, typename T6 = char, typename T7 = char,
+ typename T8 = char, typename T9 = char, typename T10 = char>
class AlignerImpl {
- T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7;
+ T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
AlignerImpl(); // Never defined or instantiated.
};
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char>
+ typename T5 = char, typename T6 = char, typename T7 = char,
+ typename T8 = char, typename T9 = char, typename T10 = char>
union SizerImpl {
char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
- arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)];
+ arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
+ arr9[sizeof(T9)], arr10[sizeof(T10)];
};
} // end namespace detail
@@ -195,10 +198,13 @@ union SizerImpl {
/// be added at the cost of more boiler plate.
template <typename T1,
typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char>
+ typename T5 = char, typename T6 = char, typename T7 = char,
+ typename T8 = char, typename T9 = char, typename T10 = char>
struct AlignedCharArrayUnion : llvm::AlignedCharArray<
- AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment,
- sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> {
+ AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, T10> >::Alignment,
+ sizeof(detail::SizerImpl<T1, T2, T3, T4, T5,
+ T6, T7, T8, T9, T10>)> {
};
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index 397f50f..0641322 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -17,14 +17,19 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdlib>
namespace llvm {
-template <typename T> struct ReferenceAdder { typedef T& result; };
-template <typename T> struct ReferenceAdder<T&> { typedef T result; };
+template <typename T> struct ReferenceAdder {
+ typedef T &result;
+};
+template <typename T> struct ReferenceAdder<T &> {
+ typedef T result;
+};
class MallocAllocator {
public:
@@ -35,15 +40,15 @@ public:
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() {
+ return static_cast<T *>(malloc(sizeof(T)));
+ }
- template <typename T>
- T *Allocate(size_t Num) {
- return static_cast<T*>(malloc(sizeof(T)*Num));
+ 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 Deallocate(const void *Ptr) { free(const_cast<void *>(Ptr)); }
void PrintStats() const {}
};
@@ -77,128 +82,224 @@ class MallocSlabAllocator : public SlabAllocator {
MallocAllocator Allocator;
public:
- MallocSlabAllocator() : Allocator() { }
+ MallocSlabAllocator() : Allocator() {}
virtual ~MallocSlabAllocator();
- virtual MemSlab *Allocate(size_t Size) LLVM_OVERRIDE;
- virtual void Deallocate(MemSlab *Slab) LLVM_OVERRIDE;
+ MemSlab *Allocate(size_t Size) override;
+ void Deallocate(MemSlab *Slab) override;
};
-/// 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 &) LLVM_DELETED_FUNCTION;
- void operator=(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION;
-
- /// SlabSize - Allocate data into slabs of this size unless we get an
- /// allocation above SizeThreshold.
- size_t SlabSize;
-
- /// SizeThreshold - For any allocation larger than this threshold, we should
- /// allocate a separate slab.
- size_t SizeThreshold;
-
- /// \brief the default allocator used if one is not provided
- MallocSlabAllocator DefaultSlabAllocator;
+/// \brief Non-templated base class for the \c BumpPtrAllocatorImpl template.
+class BumpPtrAllocatorBase {
+public:
+ void Deallocate(const void * /*Ptr*/) {}
+ void PrintStats() const;
- /// 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;
+ /// \brief Returns the total physical memory allocated by this allocator.
+ size_t getTotalMemory() const;
- /// CurSlab - The slab that we are currently allocating into.
- ///
+protected:
+ /// \brief 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.
+ /// \brief How many bytes we've allocated.
///
- char *End;
-
- /// BytesAllocated - This field tracks how many bytes we've allocated, so
- /// that we can compute how much space was wasted.
+ /// Used 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();
+ BumpPtrAllocatorBase() : CurSlab(0), BytesAllocated(0) {}
+};
- /// DeallocateSlabs - Deallocate all memory slabs after and including this
- /// one.
- void DeallocateSlabs(MemSlab *Slab);
+/// \brief Allocate memory in an ever growing pool, as if by bump-pointer.
+///
+/// This isn't strictly a bump-pointer allocator as it uses backing slabs of
+/// memory rather than relying on boundless contiguous heap. However, it has
+/// bump-pointer semantics in that is a monotonically growing pool of memory
+/// where every allocation is found by merely allocating the next N bytes in
+/// the slab, or the next N bytes in the next slab.
+///
+/// Note that this also has a threshold for forcing allocations above a certain
+/// size into their own slab.
+template <size_t SlabSize = 4096, size_t SizeThreshold = SlabSize>
+class BumpPtrAllocatorImpl : public BumpPtrAllocatorBase {
+ BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
+ void operator=(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
- template<typename T> friend class SpecificBumpPtrAllocator;
public:
- BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096);
- BumpPtrAllocator(size_t size, size_t threshold, SlabAllocator &allocator);
- ~BumpPtrAllocator();
-
- /// Reset - Deallocate all but the current slab and reset the current pointer
+ static_assert(SizeThreshold <= SlabSize,
+ "The SizeThreshold must be at most the SlabSize to ensure "
+ "that objects larger than a slab go into their own memory "
+ "allocation.");
+
+ BumpPtrAllocatorImpl()
+ : Allocator(DefaultSlabAllocator), NumSlabs(0) {}
+ BumpPtrAllocatorImpl(SlabAllocator &Allocator)
+ : Allocator(Allocator), NumSlabs(0) {}
+ ~BumpPtrAllocatorImpl() { DeallocateSlabs(CurSlab); }
+
+ /// \brief Deallocate all but the current slab and reset the current pointer
/// to the beginning of it, freeing all memory allocated so far.
- void Reset();
+ void Reset() {
+ if (!CurSlab)
+ return;
+ DeallocateSlabs(CurSlab->NextPtr);
+ CurSlab->NextPtr = 0;
+ CurPtr = (char *)(CurSlab + 1);
+ End = ((char *)CurSlab) + CurSlab->Size;
+ BytesAllocated = 0;
+ }
- /// Allocate - Allocate space at the specified alignment.
- ///
- void *Allocate(size_t Size, size_t Alignment);
+ /// \brief Allocate space at the specified alignment.
+ void *Allocate(size_t Size, size_t Alignment) {
+ if (!CurSlab) // Start a new slab if we haven't allocated one already.
+ StartNewSlab();
+
+ // Keep track of how many bytes we've allocated.
+ BytesAllocated += Size;
+
+ // 0-byte alignment means 1-byte alignment.
+ if (Alignment == 0)
+ Alignment = 1;
+
+ // Allocate the aligned space, going forwards from CurPtr.
+ char *Ptr = alignPtr(CurPtr, Alignment);
+
+ // Check if we can hold it.
+ if (Ptr + Size <= End) {
+ CurPtr = Ptr + Size;
+ // Update the allocation point of this memory block in MemorySanitizer.
+ // Without this, MemorySanitizer messages for values originated from here
+ // will point to the allocation of the entire slab.
+ __msan_allocated_memory(Ptr, Size);
+ return Ptr;
+ }
- /// Allocate space, but do not construct, one object.
- ///
- template <typename T>
- T *Allocate() {
- return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment));
+ // If Size is really big, allocate a separate slab for it.
+ size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1;
+ if (PaddedSize > SizeThreshold) {
+ ++NumSlabs;
+ MemSlab *NewSlab = Allocator.Allocate(PaddedSize);
+
+ // Put the new slab after the current slab, since we are not allocating
+ // into it.
+ NewSlab->NextPtr = CurSlab->NextPtr;
+ CurSlab->NextPtr = NewSlab;
+
+ Ptr = alignPtr((char *)(NewSlab + 1), Alignment);
+ assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size);
+ __msan_allocated_memory(Ptr, Size);
+ return Ptr;
+ }
+
+ // Otherwise, start a new slab and try again.
+ StartNewSlab();
+ Ptr = alignPtr(CurPtr, Alignment);
+ CurPtr = Ptr + Size;
+ assert(CurPtr <= End && "Unable to allocate memory!");
+ __msan_allocated_memory(Ptr, Size);
+ return Ptr;
}
- /// 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));
+ /// \brief Allocate space for one object without constructing it.
+ template <typename T> T *Allocate() {
+ return static_cast<T *>(Allocate(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) {
+ /// \brief Allocate space for an array of objects without constructing them.
+ template <typename T> T *Allocate(size_t Num) {
+ return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+ }
+
+ /// \brief Allocate space for an array of objects with the specified alignment
+ /// and without constructing them.
+ 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));
+ size_t EltSize = (sizeof(T) + Alignment - 1) & (-Alignment);
+ return static_cast<T *>(Allocate(Num * EltSize, Alignment));
}
- void Deallocate(const void * /*Ptr*/) {}
+ size_t GetNumSlabs() const { return NumSlabs; }
- unsigned GetNumSlabs() const;
+private:
+ /// \brief The default allocator used if one is not provided.
+ MallocSlabAllocator DefaultSlabAllocator;
- void PrintStats() const;
-
- /// Compute the total physical memory allocated by this allocator.
- size_t getTotalMemory() const;
+ /// \brief 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;
+
+ /// \brief The current pointer into the current slab.
+ ///
+ /// This points to the next free byte in the slab.
+ char *CurPtr;
+
+ /// \brief The end of the current slab.
+ char *End;
+
+ /// \brief How many slabs we've allocated.
+ ///
+ /// Used to scale the size of each slab and reduce the number of allocations
+ /// for extremely heavy memory use scenarios.
+ size_t NumSlabs;
+
+ /// \brief Allocate a new slab and move the bump pointers over into the new
+ /// slab, modifying CurPtr and End.
+ void StartNewSlab() {
+ ++NumSlabs;
+ // Scale the actual allocated slab size based on the number of slabs
+ // allocated. Every 128 slabs allocated, we double the allocated size to
+ // reduce allocation frequency, but saturate at multiplying the slab size by
+ // 2^30.
+ // FIXME: Currently, this count includes special slabs for objects above the
+ // size threshold. That will be fixed in a subsequent commit to make the
+ // growth even more predictable.
+ size_t AllocatedSlabSize =
+ SlabSize * ((size_t)1 << std::min<size_t>(30, NumSlabs / 128));
+
+ MemSlab *NewSlab = Allocator.Allocate(AllocatedSlabSize);
+ NewSlab->NextPtr = CurSlab;
+ CurSlab = NewSlab;
+ CurPtr = (char *)(CurSlab + 1);
+ End = ((char *)CurSlab) + CurSlab->Size;
+ }
+
+ /// \brief Deallocate all memory slabs after and including this one.
+ void DeallocateSlabs(MemSlab *Slab) {
+ while (Slab) {
+ MemSlab *NextSlab = Slab->NextPtr;
+#ifndef NDEBUG
+ // Poison the memory so stale pointers crash sooner. Note we must
+ // preserve the Size and NextPtr fields at the beginning.
+ sys::Memory::setRangeWritable(Slab + 1, Slab->Size - sizeof(MemSlab));
+ memset(Slab + 1, 0xCD, Slab->Size - sizeof(MemSlab));
+#endif
+ Allocator.Deallocate(Slab);
+ Slab = NextSlab;
+ --NumSlabs;
+ }
+ }
+
+ template <typename T> friend class SpecificBumpPtrAllocator;
};
-/// 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 {
+/// \brief The standard BumpPtrAllocator which just uses the default template
+/// paramaters.
+typedef BumpPtrAllocatorImpl<> BumpPtrAllocator;
+
+/// \brief A BumpPtrAllocator that allows only elements of a specific 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)
- : Allocator(size, threshold) {}
- SpecificBumpPtrAllocator(size_t size, size_t threshold,
- SlabAllocator &allocator)
- : Allocator(size, threshold, allocator) {}
-
- ~SpecificBumpPtrAllocator() {
- DestroyAll();
- }
+ SpecificBumpPtrAllocator() : Allocator() {}
+ SpecificBumpPtrAllocator(SlabAllocator &allocator) : Allocator(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
@@ -206,27 +307,28 @@ public:
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>());
+ char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr
+ : (char *)Slab + Slab->Size;
+ for (char *Ptr = (char *)(Slab + 1); Ptr < End; Ptr += sizeof(T)) {
+ Ptr = alignPtr(Ptr, alignOf<T>());
if (Ptr + sizeof(T) <= End)
- reinterpret_cast<T*>(Ptr)->~T();
+ 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);
- }
+ /// \brief Allocate space for an array of objects without constructing them.
+ T *Allocate(size_t num = 1) { return Allocator.Allocate<T>(num); }
};
} // end namespace llvm
-inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
+template <size_t SlabSize, size_t SizeThreshold>
+void *
+operator new(size_t Size,
+ llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &Allocator) {
struct S {
char c;
union {
@@ -236,10 +338,12 @@ inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
void *P;
} x;
};
- return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
- offsetof(S, x)));
+ return Allocator.Allocate(
+ Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
}
-inline void operator delete(void *, llvm::BumpPtrAllocator &) {}
+template <size_t SlabSize, size_t SizeThreshold>
+void operator delete(void *,
+ llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &) {}
#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
index c7e0cba..e974332 100644
--- a/include/llvm/Support/ArrayRecycler.h
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -16,12 +16,11 @@
#define LLVM_SUPPORT_ARRAYRECYCLER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/MathExtras.h"
namespace llvm {
-class BumpPtrAllocator;
-
/// Recycle small arrays allocated from a BumpPtrAllocator.
///
/// Arrays are allocated in a small number of fixed sizes. For each supported
@@ -35,6 +34,9 @@ class ArrayRecycler {
FreeList *Next;
};
+ static_assert(Align >= AlignOf<FreeList>::Alignment, "Object underaligned");
+ static_assert(sizeof(T) >= sizeof(FreeList), "Objects are too small");
+
// Keep a free list for each array size.
SmallVector<FreeList*, 8> Bucket;
@@ -53,8 +55,6 @@ class ArrayRecycler {
// Add an entry to the free list at Bucket[Idx].
void push(unsigned Idx, T *Ptr) {
assert(Ptr && "Cannot recycle NULL pointer");
- assert(sizeof(T) >= sizeof(FreeList) && "Objects are too small");
- assert(Align >= AlignOf<FreeList>::Alignment && "Object underaligned");
FreeList *Entry = reinterpret_cast<FreeList*>(Ptr);
if (Idx >= Bucket.size())
Bucket.resize(size_t(Idx) + 1);
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index 21879e7..dae520b 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/include/llvm/Support/BlockFrequency.h
@@ -25,7 +25,6 @@ class BranchProbability;
class BlockFrequency {
uint64_t Frequency;
- static const int64_t ENTRY_FREQ = 1 << 14;
/// \brief Scale the given BlockFrequency by N/D. Return the remainder from
/// the division by D. Upon overflow, the routine will saturate and
@@ -35,9 +34,6 @@ class BlockFrequency {
public:
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
- /// \brief Returns the frequency of the entry block of the function.
- static uint64_t getEntryFrequency() { return ENTRY_FREQ; }
-
/// \brief Returns the maximum possible frequency, the saturation value.
static uint64_t getMaxFrequency() { return -1ULL; }
@@ -59,6 +55,9 @@ public:
BlockFrequency &operator+=(const BlockFrequency &Freq);
const BlockFrequency operator+(const BlockFrequency &Freq) const;
+ /// \brief Shift block frequency to the right by count digits saturating to 1.
+ BlockFrequency &operator>>=(const unsigned count);
+
/// \brief Scale the given BlockFrequency by N/D. Return the remainder from
/// the division by D. Upon overflow, the routine will saturate.
uint32_t scale(const BranchProbability &Prob);
@@ -78,12 +77,8 @@ public:
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/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 9cc3989..dca7fc6 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -30,6 +30,9 @@
namespace llvm {
namespace COFF {
+ // The maximum number of sections that a COFF object can have (inclusive).
+ const int MaxNumberOfSections = 65299;
+
// The PE signature bytes that follows the DOS stub header.
static const char PEMagic[] = { 'P', 'E', '\0', '\0' };
@@ -59,7 +62,7 @@ namespace COFF {
IMAGE_FILE_MACHINE_AM33 = 0x13,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
IMAGE_FILE_MACHINE_ARM = 0x1C0,
- IMAGE_FILE_MACHINE_ARMV7 = 0x1C4,
+ IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
IMAGE_FILE_MACHINE_EBC = 0xEBC,
IMAGE_FILE_MACHINE_I386 = 0x14C,
IMAGE_FILE_MACHINE_IA64 = 0x200,
@@ -138,8 +141,8 @@ namespace COFF {
};
enum SymbolSectionNumber {
- IMAGE_SYM_DEBUG = -2,
- IMAGE_SYM_ABSOLUTE = -1,
+ IMAGE_SYM_DEBUG = 0xFFFE,
+ IMAGE_SYM_ABSOLUTE = 0xFFFF,
IMAGE_SYM_UNDEFINED = 0
};
@@ -209,6 +212,10 @@ namespace COFF {
SCT_COMPLEX_TYPE_SHIFT = 4
};
+ enum AuxSymbolType {
+ IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
+ };
+
struct section {
char Name[NameSize];
uint32_t VirtualSize;
@@ -222,7 +229,7 @@ namespace COFF {
uint32_t Characteristics;
};
- enum SectionCharacteristics LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum SectionCharacteristics : uint32_t {
SC_Invalid = 0xffffffff,
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
@@ -334,7 +341,7 @@ namespace COFF {
uint32_t TotalSize;
uint32_t PointerToLinenumber;
uint32_t PointerToNextFunction;
- uint8_t unused[2];
+ char unused[2];
};
struct AuxiliarybfAndefSymbol {
@@ -369,7 +376,14 @@ namespace COFF {
uint32_t CheckSum;
uint16_t Number;
uint8_t Selection;
- uint8_t unused[3];
+ char unused[3];
+ };
+
+ struct AuxiliaryCLRToken {
+ uint8_t AuxType;
+ uint8_t unused1;
+ uint32_t SymbolTableIndex;
+ char unused2[12];
};
union Auxiliary {
@@ -450,7 +464,12 @@ namespace COFF {
uint32_t AddressOfNewExeHeader;
};
- struct PEHeader {
+ struct PE32Header {
+ enum {
+ PE32 = 0x10b,
+ PE32_PLUS = 0x20b
+ };
+
uint16_t Magic;
uint8_t MajorLinkerVersion;
uint8_t MinorLinkerVersion;
@@ -460,7 +479,7 @@ namespace COFF {
uint32_t AddressOfEntryPoint; // RVA
uint32_t BaseOfCode; // RVA
uint32_t BaseOfData; // RVA
- uint64_t ImageBase;
+ uint32_t ImageBase;
uint32_t SectionAlignment;
uint32_t FileAlignment;
uint16_t MajorOperatingSystemVersion;
@@ -475,10 +494,10 @@ namespace COFF {
uint32_t CheckSum;
uint16_t Subsystem;
uint16_t DLLCharacteristics;
- uint64_t SizeOfStackReserve;
- uint64_t SizeOfStackCommit;
- uint64_t SizeOfHeapReserve;
- uint64_t SizeOfHeapCommit;
+ uint32_t SizeOfStackReserve;
+ uint32_t SizeOfStackCommit;
+ uint32_t SizeOfHeapReserve;
+ uint32_t SizeOfHeapCommit;
uint32_t LoaderFlags;
uint32_t NumberOfRvaAndSize;
};
@@ -526,6 +545,8 @@ namespace COFF {
};
enum DLLCharacteristics {
+ /// ASLR with 64 bit address space.
+ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
/// DLL can be relocated at load time.
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040,
/// Code integrity checks are enforced.
@@ -611,6 +632,17 @@ namespace COFF {
}
};
+ enum CodeViewLineTableIdentifiers {
+ DEBUG_SECTION_MAGIC = 0x4,
+ DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
+ DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
+ DEBUG_INDEX_SUBSECTION = 0xF4
+ };
+
+ inline bool isReservedSectionNumber(int N) {
+ return N == IMAGE_SYM_UNDEFINED || N > MaxNumberOfSections;
+ }
+
} // End namespace COFF.
} // End namespace llvm.
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index d70acbf..689f590 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -15,6 +15,7 @@
#ifndef LLVM_SUPPORT_CASTING_H
#define LLVM_SUPPORT_CASTING_H
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -58,11 +59,8 @@ struct isa_impl {
/// \brief Always allow upcasts, and perform no dynamic check for them.
template <typename To, typename From>
-struct isa_impl<To, From,
- typename enable_if<
- llvm::is_base_of<To, From>
- >::type
- > {
+struct isa_impl<
+ To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
static inline bool doit(const From &) { return true; }
};
@@ -131,7 +129,7 @@ struct isa_impl_wrap<To, FromTy, FromTy> {
// if (isa<Type>(myVal)) { ... }
//
template <class X, class Y>
-inline bool isa(const Y &Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) {
return isa_impl_wrap<X, const Y,
typename simplify_type<const Y>::SimpleType>::doit(Val);
}
@@ -208,7 +206,7 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
template <class X> struct is_simple_type {
static const bool value =
- is_same<X, typename simplify_type<X>::SimpleType>::value;
+ std::is_same<X, typename simplify_type<X>::SimpleType>::value;
};
// cast<X> - Return the argument parameter cast to the specified type. This
@@ -219,8 +217,8 @@ template <class X> struct is_simple_type {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename enable_if_c<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
+inline typename std::enable_if<!is_simple_type<Y>::value,
+ typename cast_retty<X, const Y>::ret_type>::type
cast(const Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
return cast_convert_val<
@@ -245,7 +243,8 @@ inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
// accepted.
//
template <class X, class Y>
-inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT 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);
@@ -261,19 +260,21 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
//
template <class X, class Y>
-inline typename enable_if_c<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
+ !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type
dyn_cast(const Y &Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
template <class X, class Y>
-inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type
+dyn_cast(Y &Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
template <class X, class Y>
-inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+dyn_cast(Y *Val) {
return isa<X>(Val) ? cast<X>(Val) : 0;
}
@@ -281,7 +282,8 @@ inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
// value is accepted.
//
template <class X, class Y>
-inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) {
+LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
+dyn_cast_or_null(Y *Val) {
return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
}
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 4efb6a6..e49a97e 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -21,10 +21,9 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/type_traits.h"
#include <cassert>
#include <climits>
#include <cstdarg>
@@ -149,8 +148,8 @@ private:
public:
OptionCategory(const char *const Name, const char *const Description = 0)
: Name(Name), Description(Description) { registerCategory(); }
- const char *getName() { return Name; }
- const char *getDescription() { return Description; }
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
};
// The general Option Category (used as default category).
@@ -249,6 +248,12 @@ public:
//
void addArgument();
+ /// Unregisters this option from the CommandLine system.
+ ///
+ /// This option must have been the last option registered.
+ /// For testing purposes only.
+ void removeArgument();
+
Option *getNextRegisteredOption() const { return NextRegistered; }
// Return the width of the option tag for printing...
@@ -374,7 +379,9 @@ struct OptionValueBase : public GenericOptionValue {
bool compare(const DataType &/*V*/) const { return false; }
- virtual bool compare(const GenericOptionValue& /*V*/) const { return false; }
+ bool compare(const GenericOptionValue& /*V*/) const override {
+ return false;
+ }
};
// Simple copy of the option value.
@@ -398,7 +405,7 @@ public:
return Valid && (Value != V);
}
- virtual bool compare(const GenericOptionValue &V) const {
+ bool compare(const GenericOptionValue &V) const override {
const OptionValueCopy<DataType> &VC =
static_cast< const OptionValueCopy<DataType>& >(V);
if (!VC.hasValue()) return false;
@@ -414,7 +421,7 @@ struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
// Top-level option class.
template<class DataType>
-struct OptionValue : OptionValueBase<DataType, is_class<DataType>::value> {
+struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
OptionValue() {}
OptionValue(const DataType& V) {
@@ -444,7 +451,7 @@ struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
return *this;
}
private:
- virtual void anchor();
+ void anchor() override;
};
template<>
@@ -461,7 +468,7 @@ struct OptionValue<std::string> : OptionValueCopy<std::string> {
return *this;
}
private:
- virtual void anchor();
+ void anchor() override;
};
//===----------------------------------------------------------------------===//
@@ -640,14 +647,14 @@ 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 {
+ unsigned getNumOptions() const override { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const override { return Values[N].Name; }
+ const char *getDescription(unsigned N) const override {
return Values[N].HelpStr;
}
// getOptionValue - Return the value of option name N.
- virtual const GenericOptionValue &getOptionValue(unsigned N) const {
+ const GenericOptionValue &getOptionValue(unsigned N) const override {
return Values[N].V;
}
@@ -756,13 +763,13 @@ public:
}
// getValueName - Do not print =<value> at all.
- virtual const char *getValueName() const { return 0; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
@@ -780,13 +787,13 @@ public:
}
// getValueName - Do not print =<value> at all.
- virtual const char *getValueName() const { return 0; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
@@ -801,13 +808,13 @@ public:
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"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
@@ -823,13 +830,13 @@ public:
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"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
@@ -845,13 +852,13 @@ public:
unsigned long long &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "uint"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
@@ -866,13 +873,13 @@ public:
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"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
@@ -887,13 +894,13 @@ public:
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"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
@@ -911,13 +918,13 @@ public:
}
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "string"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
@@ -935,13 +942,13 @@ public:
}
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "char"; }
+ const char *getValueName() const override { 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();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
@@ -1020,8 +1027,8 @@ template<> struct applicator<const char*> {
};
template<> struct applicator<NumOccurrencesFlag> {
- static void opt(NumOccurrencesFlag NO, Option &O) {
- O.setNumOccurrencesFlag(NO);
+ static void opt(NumOccurrencesFlag N, Option &O) {
+ O.setNumOccurrencesFlag(N);
}
};
template<> struct applicator<ValueExpected> {
@@ -1055,7 +1062,7 @@ class opt_storage {
DataType *Location; // Where to store the object...
OptionValue<DataType> Default;
- void check() const {
+ void check_location() const {
assert(Location != 0 && "cl::location(...) not specified for a command "
"line option with external storage, "
"or cl::init specified before cl::location()!!");
@@ -1073,14 +1080,14 @@ public:
template<class T>
void setValue(const T &V, bool initial = false) {
- check();
+ check_location();
*Location = V;
if (initial)
Default = V;
}
- DataType &getValue() { check(); return *Location; }
- const DataType &getValue() const { check(); return *Location; }
+ DataType &getValue() { check_location(); return *Location; }
+ const DataType &getValue() const { check_location(); return *Location; }
operator DataType() const { return this->getValue(); }
@@ -1148,11 +1155,11 @@ template <class DataType, bool ExternalStorage = false,
class ParserClass = parser<DataType> >
class opt : public Option,
public opt_storage<DataType, ExternalStorage,
- is_class<DataType>::value> {
+ std::is_class<DataType>::value> {
ParserClass Parser;
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
- StringRef Arg) {
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1162,20 +1169,20 @@ class opt : public Option,
return false;
}
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
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 {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
- virtual void printOptionValue(size_t GlobalWidth, bool Force) const {
+ void printOptionValue(size_t GlobalWidth, bool Force) const override {
if (Force || this->getDefault().compare(this->getValue())) {
cl::printOptionDiff<ParserClass>(
*this, Parser, this->getValue(), this->getDefault(), GlobalWidth);
@@ -1322,14 +1329,15 @@ class list : public Option, public list_storage<DataType, Storage> {
std::vector<unsigned> Positions;
ParserClass Parser;
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1341,13 +1349,14 @@ class list : public Option, public list_storage<DataType, Storage> {
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
// Unimplemented: list options don't currently store their default value.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
void done() {
addArgument();
@@ -1524,14 +1533,15 @@ class bits : public Option, public bits_storage<DataType, Storage> {
std::vector<unsigned> Positions;
ParserClass Parser;
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
@@ -1543,13 +1553,14 @@ class bits : public Option, public bits_storage<DataType, Storage> {
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
// Unimplemented: bits options don't currently store their default values.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
void done() {
addArgument();
@@ -1634,17 +1645,21 @@ public:
class alias : public Option {
Option *AliasFor;
- virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
- StringRef Arg) LLVM_OVERRIDE {
+ bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
+ StringRef Arg) override {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
}
// Handle printing stuff...
- virtual size_t getOptionWidth() const LLVM_OVERRIDE;
- virtual void printOptionInfo(size_t GlobalWidth) const LLVM_OVERRIDE;
+ size_t getOptionWidth() const override;
+ void printOptionInfo(size_t GlobalWidth) const override;
// Aliases do not need to print their values.
- virtual void printOptionValue(size_t /*GlobalWidth*/,
- bool /*Force*/) const LLVM_OVERRIDE {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
+
+ ValueExpected getValueExpectedFlagDefault() const override {
+ return AliasFor->getValueExpectedFlag();
+ }
void done() {
if (!hasArgStr())
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index 860f43e..1edcd45 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -21,6 +21,10 @@
# define __has_feature(x) 0
#endif
+#ifndef __has_extension
+# define __has_extension(x) 0
+#endif
+
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
@@ -40,15 +44,21 @@
# endif
#endif
-/// \brief Does the compiler support r-value references?
-/// This implies that <utility> provides the one-argument std::move; it
-/// does not imply the existence of any other C++ library features.
-#if (__has_feature(cxx_rvalue_references) \
- || defined(__GXX_EXPERIMENTAL_CXX0X__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1600))
-#define LLVM_HAS_RVALUE_REFERENCES 1
+/// \macro LLVM_MSC_PREREQ
+/// \brief Is the compiler MSVC of at least the specified version?
+/// The common \param version values to check for are:
+/// * 1700: Microsoft Visual Studio 2012 / 11.0
+/// * 1800: Microsoft Visual Studio 2013 / 12.0
+#ifdef _MSC_VER
+#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
+
+// We require at least MSVC 2012.
+#if !LLVM_MSC_PREREQ(1700)
+#error LLVM requires at least MSVC 2012.
+#endif
+
#else
-#define LLVM_HAS_RVALUE_REFERENCES 0
+#define LLVM_MSC_PREREQ(version) 0
#endif
/// \brief Does the compiler support r-value reference *this?
@@ -63,51 +73,16 @@
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif
-/// \macro LLVM_HAS_CXX11_TYPETRAITS
-/// \brief Does the compiler have the C++11 type traits.
-///
-/// #include <type_traits>
-///
-/// * enable_if
-/// * {true,false}_type
-/// * is_constructible
-/// * etc...
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_HAS_CXX11_TYPETRAITS 1
-#else
-#define LLVM_HAS_CXX11_TYPETRAITS 0
-#endif
-
-/// \macro LLVM_HAS_CXX11_STDLIB
-/// \brief Does the compiler have the C++11 standard library.
-///
-/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_HAS_CXX11_STDLIB 1
-#else
-#define LLVM_HAS_CXX11_STDLIB 0
-#endif
-
/// \macro LLVM_HAS_VARIADIC_TEMPLATES
/// \brief Does this compiler support variadic templates.
///
/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
-#if __has_feature(cxx_variadic_templates)
+#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800)
# define LLVM_HAS_VARIADIC_TEMPLATES 1
#else
# define LLVM_HAS_VARIADIC_TEMPLATES 0
#endif
-/// llvm_move - Expands to ::std::move if the compiler supports
-/// r-value references; otherwise, expands to the argument.
-#if LLVM_HAS_RVALUE_REFERENCES
-#define llvm_move(value) (::std::move(value))
-#else
-#define llvm_move(value) (value)
-#endif
-
/// Expands to '&' if r-value references are supported.
///
/// This can be used to provide l-value/r-value overrides of member functions.
@@ -129,32 +104,13 @@
/// public:
/// ...
/// };
-#if (__has_feature(cxx_deleted_functions) \
- || defined(__GXX_EXPERIMENTAL_CXX0X__))
- // No version of MSVC currently supports this.
+#if __has_feature(cxx_deleted_functions) || \
+ defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#define LLVM_DELETED_FUNCTION = delete
#else
#define LLVM_DELETED_FUNCTION
#endif
-/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
-/// Use to mark classes or virtual methods as final.
-#if __has_feature(cxx_override_control) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_FINAL final
-#else
-#define LLVM_FINAL
-#endif
-
-/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
-/// Use to mark virtual methods as overriding a base class method.
-#if __has_feature(cxx_override_control) \
- || (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define LLVM_OVERRIDE override
-#else
-#define LLVM_OVERRIDE
-#endif
-
#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define LLVM_CONSTEXPR constexpr
#else
@@ -335,19 +291,15 @@
# define LLVM_FUNCTION_NAME __func__
#endif
-#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H)
-# include <sanitizer/msan_interface.h>
-#else
-# define __msan_allocated_memory(p, size)
-# define __msan_unpoison(p, size)
-#endif
-
/// \macro LLVM_MEMORY_SANITIZER_BUILD
/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
#if __has_feature(memory_sanitizer)
# define LLVM_MEMORY_SANITIZER_BUILD 1
+# include <sanitizer/msan_interface.h>
#else
# define LLVM_MEMORY_SANITIZER_BUILD 0
+# define __msan_allocated_memory(p, size)
+# define __msan_unpoison(p, size)
#endif
/// \macro LLVM_ADDRESS_SANITIZER_BUILD
@@ -374,41 +326,30 @@
/// \macro LLVM_EXPLICIT
/// \brief Expands to explicit on compilers which support explicit conversion
/// operators. Otherwise expands to nothing.
-#if (__has_feature(cxx_explicit_conversions) \
- || defined(__GXX_EXPERIMENTAL_CXX0X__))
+#if __has_feature(cxx_explicit_conversions) || \
+ defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800)
#define LLVM_EXPLICIT explicit
#else
#define LLVM_EXPLICIT
#endif
-/// \macro LLVM_STATIC_ASSERT
-/// \brief Expands to C/C++'s static_assert on compilers which support it.
-#if __has_feature(cxx_static_assert)
-# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
-#elif __has_feature(c_static_assert)
-# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
-#else
-# define LLVM_STATIC_ASSERT(expr, msg)
-#endif
-
-/// \macro LLVM_ENUM_INT_TYPE
-/// \brief Expands to colon followed by the given integral type on compilers
-/// which support C++11 strong enums. This can be used to make enums unsigned
-/// with MSVC.
-#if __has_feature(cxx_strong_enums)
-# define LLVM_ENUM_INT_TYPE(intty) : intty
-#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Added in MSVC 2010.
-# define LLVM_ENUM_INT_TYPE(intty) : intty
-#else
-# define LLVM_ENUM_INT_TYPE(intty)
-#endif
-
/// \brief Does the compiler support generalized initializers (using braced
-/// lists and std::initializer_list).
-#if __has_feature(cxx_generalized_initializers)
+/// lists and std::initializer_list). While clang may claim it supports general
+/// initializers, if we're using MSVC's headers, we might not have a usable
+/// std::initializer list type from the STL. Disable this for now.
+#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER)
#define LLVM_HAS_INITIALIZER_LISTS 1
#else
#define LLVM_HAS_INITIALIZER_LISTS 0
#endif
+/// \brief Mark debug helper function definitions like dump() that should not be
+/// stripped from debug builds.
+// FIXME: Move this to a private config.h as it's not usable in public headers.
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
+#else
+#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
+#endif
+
#endif
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index bef9146..80eff5c 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -15,11 +15,11 @@
#define LLVM_SUPPORT_COMPRESSION_H
#include "llvm/Support/DataTypes.h"
+#include <memory>
namespace llvm {
class MemoryBuffer;
-template<typename T> class OwningPtr;
class StringRef;
namespace zlib {
@@ -33,21 +33,21 @@ enum CompressionLevel {
enum Status {
StatusOK,
- StatusUnsupported, // zlib is unavaliable
- StatusOutOfMemory, // there was not enough memory
- StatusBufferTooShort, // there was not enough room in the output buffer
- StatusInvalidArg, // invalid input parameter
- StatusInvalidData // data was corrupted or incomplete
+ StatusUnsupported, // zlib is unavailable
+ StatusOutOfMemory, // there was not enough memory
+ StatusBufferTooShort, // there was not enough room in the output buffer
+ StatusInvalidArg, // invalid input parameter
+ StatusInvalidData // data was corrupted or incomplete
};
bool isAvailable();
Status compress(StringRef InputBuffer,
- OwningPtr<MemoryBuffer> &CompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &CompressedBuffer,
CompressionLevel Level = DefaultCompression);
Status uncompress(StringRef InputBuffer,
- OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
size_t UncompressedSize);
uint32_t crc32(StringRef Buffer);
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 4c0a5e2..4500efe 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -46,6 +46,17 @@ class CrashRecoveryContext {
void *Impl;
CrashRecoveryContextCleanup *head;
+ /// An adaptor to convert an arbitrary functor into a void(void*), void* pair.
+ template<typename T> struct FunctorAdaptor {
+ T Fn;
+ static void invoke(void *Data) {
+ return static_cast<FunctorAdaptor<T>*>(Data)->Fn();
+ }
+ typedef void Callback(void*);
+ Callback *fn() { return &invoke; }
+ void *arg() { return this; }
+ };
+
public:
CrashRecoveryContext() : Impl(0), head(0) {}
~CrashRecoveryContext();
@@ -76,6 +87,11 @@ public:
/// RunSafely has returned false. Clients can use getBacktrace() to retrieve
/// the backtrace of the crash on failures.
bool RunSafely(void (*Fn)(void*), void *UserData);
+ template<typename Functor>
+ bool RunSafely(Functor Fn) {
+ FunctorAdaptor<Functor> Adaptor = { Fn };
+ return RunSafely(Adaptor.fn(), Adaptor.arg());
+ }
/// \brief Execute the provide callback function (with the given arguments) in
/// a protected context which is run in another thread (optionally with a
@@ -84,6 +100,11 @@ public:
/// See RunSafely() and llvm_execute_on_thread().
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize = 0);
+ template<typename Functor>
+ bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) {
+ FunctorAdaptor<Functor> Adaptor = { Fn };
+ return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(), RequestedStackSize);
+ }
/// \brief Explicitly trigger a crash recovery in the current process, and
/// return failure from RunSafely(). This function does not return.
diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h
deleted file mode 100644
index a09ccaa..0000000
--- a/include/llvm/Support/DataFlow.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- 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/ADT/GraphTraits.h"
-#include "llvm/IR/User.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/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index 23bbd1c..ca31644 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -24,7 +24,7 @@ namespace llvm {
//===----------------------------------------------------------------------===//
// Debug info constants.
-enum LLVM_ENUM_INT_TYPE(uint32_t) {
+enum : uint32_t {
LLVMDebugVersion = (12 << 16), // Current version of debug information.
LLVMDebugVersion11 = (11 << 16), // Constant for version 11.
LLVMDebugVersion10 = (10 << 16), // Constant for version 10.
@@ -41,13 +41,13 @@ namespace dwarf {
//===----------------------------------------------------------------------===//
// Dwarf constants as gleaned from the DWARF Debugging Information Format V.4
-// reference manual http://dwarf.freestandards.org.
+// reference manual http://www.dwarfstd.org/.
//
// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
// enumeration base type.
-enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
+enum LLVMConstants : uint32_t {
// llvm mock tags
DW_TAG_invalid = ~0U, // Tag for invalid results.
@@ -68,7 +68,7 @@ enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
const uint32_t DW_CIE_ID = UINT32_MAX;
const uint64_t DW64_CIE_ID = UINT64_MAX;
-enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
+enum Tag : uint16_t {
DW_TAG_array_type = 0x01,
DW_TAG_class_type = 0x02,
DW_TAG_entry_point = 0x03,
@@ -129,6 +129,12 @@ enum Tag LLVM_ENUM_INT_TYPE(uint16_t) {
DW_TAG_type_unit = 0x41,
DW_TAG_rvalue_reference_type = 0x42,
DW_TAG_template_alias = 0x43,
+
+ // New in DWARF 5:
+ DW_TAG_coarray_type = 0x44,
+ DW_TAG_generic_subrange = 0x45,
+ DW_TAG_dynamic_type = 0x46,
+
DW_TAG_MIPS_loop = 0x4081,
DW_TAG_format_label = 0x4101,
DW_TAG_function_template = 0x4102,
@@ -169,7 +175,7 @@ inline bool isType(Tag T) {
}
}
-enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
+enum Attribute : uint16_t {
// Attributes
DW_AT_sibling = 0x01,
DW_AT_location = 0x02,
@@ -264,6 +270,18 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
DW_AT_enum_class = 0x6d,
DW_AT_linkage_name = 0x6e,
+ // New in DWARF 5:
+ DW_AT_string_length_bit_size = 0x6f,
+ DW_AT_string_length_byte_size = 0x70,
+ DW_AT_rank = 0x71,
+ DW_AT_str_offsets_base = 0x72,
+ DW_AT_addr_base = 0x73,
+ DW_AT_ranges_base = 0x74,
+ DW_AT_dwo_id = 0x75,
+ DW_AT_dwo_name = 0x76,
+ DW_AT_reference = 0x77,
+ DW_AT_rvalue_reference = 0x78,
+
DW_AT_lo_user = 0x2000,
DW_AT_hi_user = 0x3fff,
@@ -323,7 +341,7 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
DW_AT_APPLE_property = 0x3fed
};
-enum Form LLVM_ENUM_INT_TYPE(uint16_t) {
+enum Form : uint16_t {
// Attribute form encodings
DW_FORM_addr = 0x01,
DW_FORM_block2 = 0x03,
@@ -605,7 +623,16 @@ enum SourceLanguage {
DW_LANG_ObjC_plus_plus = 0x0011,
DW_LANG_UPC = 0x0012,
DW_LANG_D = 0x0013,
+ // New in DWARF 5:
DW_LANG_Python = 0x0014,
+ DW_LANG_OpenCL = 0x0015,
+ DW_LANG_Go = 0x0016,
+ DW_LANG_Modula3 = 0x0017,
+ DW_LANG_Haskell = 0x0018,
+ DW_LANG_C_plus_plus_03 = 0x0019,
+ DW_LANG_C_plus_plus_11 = 0x001a,
+ DW_LANG_OCaml = 0x001b,
+
DW_LANG_lo_user = 0x8000,
DW_LANG_Mips_Assembler = 0x8001,
DW_LANG_hi_user = 0xffff
@@ -744,6 +771,15 @@ enum Constants {
DW_EH_PE_indirect = 0x80
};
+// Constants for debug_loc.dwo in the DWARF5 Split Debug Info Proposal
+enum LocationListEntry : unsigned char {
+ DW_LLE_end_of_list_entry,
+ DW_LLE_base_address_selection_entry,
+ DW_LLE_start_end_entry,
+ DW_LLE_start_length_entry,
+ DW_LLE_offset_pair_entry
+};
+
enum ApplePropertyAttributes {
// Apple Objective-C Property Attributes
DW_APPLE_PROPERTY_readonly = 0x01,
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 2868f35..7b10ebd 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -651,7 +651,7 @@ enum {
};
// ARM Specific e_flags
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
EF_ARM_SOFT_FLOAT = 0x00000200U,
EF_ARM_VFP_FLOAT = 0x00000400U,
EF_ARM_EABI_UNKNOWN = 0x00000000U,
@@ -801,10 +801,12 @@ enum {
};
// Mips Specific e_flags
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
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_ABI2 = 0x00000020,
+ EF_MIPS_32BITMODE = 0x00000100,
EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
//ARCH_ASE
@@ -837,7 +839,6 @@ enum {
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,
@@ -879,6 +880,9 @@ enum {
R_MIPS_TLS_TPREL_HI16 = 49,
R_MIPS_TLS_TPREL_LO16 = 50,
R_MIPS_GLOB_DAT = 51,
+ R_MIPS16_GOT16 = 102,
+ R_MIPS16_HI16 = 104,
+ R_MIPS16_LO16 = 105,
R_MIPS_COPY = 126,
R_MIPS_JUMP_SLOT = 127,
R_MICROMIPS_26_S1 = 133,
@@ -890,11 +894,14 @@ enum {
R_MICROMIPS_GOT_DISP = 145,
R_MICROMIPS_GOT_PAGE = 146,
R_MICROMIPS_GOT_OFST = 147,
+ R_MICROMIPS_TLS_GD = 162,
+ R_MICROMIPS_TLS_LDM = 163,
R_MICROMIPS_TLS_DTPREL_HI16 = 164,
R_MICROMIPS_TLS_DTPREL_LO16 = 165,
R_MICROMIPS_TLS_TPREL_HI16 = 169,
R_MICROMIPS_TLS_TPREL_LO16 = 170,
- R_MIPS_NUM = 218
+ R_MIPS_NUM = 218,
+ R_MIPS_PC32 = 248
};
// Special values for the st_other field in the symbol table entry for MIPS.
@@ -1087,6 +1094,94 @@ enum {
R_390_IRELATIVE = 61
};
+// ELF Relocation type for Sparc.
+enum {
+ R_SPARC_NONE = 0,
+ R_SPARC_8 = 1,
+ R_SPARC_16 = 2,
+ R_SPARC_32 = 3,
+ R_SPARC_DISP8 = 4,
+ R_SPARC_DISP16 = 5,
+ R_SPARC_DISP32 = 6,
+ R_SPARC_WDISP30 = 7,
+ R_SPARC_WDISP22 = 8,
+ R_SPARC_HI22 = 9,
+ R_SPARC_22 = 10,
+ R_SPARC_13 = 11,
+ R_SPARC_LO10 = 12,
+ R_SPARC_GOT10 = 13,
+ R_SPARC_GOT13 = 14,
+ R_SPARC_GOT22 = 15,
+ R_SPARC_PC10 = 16,
+ R_SPARC_PC22 = 17,
+ R_SPARC_WPLT30 = 18,
+ R_SPARC_COPY = 19,
+ R_SPARC_GLOB_DAT = 20,
+ R_SPARC_JMP_SLOT = 21,
+ R_SPARC_RELATIVE = 22,
+ R_SPARC_UA32 = 23,
+ R_SPARC_PLT32 = 24,
+ R_SPARC_HIPLT22 = 25,
+ R_SPARC_LOPLT10 = 26,
+ R_SPARC_PCPLT32 = 27,
+ R_SPARC_PCPLT22 = 28,
+ R_SPARC_PCPLT10 = 29,
+ R_SPARC_10 = 30,
+ R_SPARC_11 = 31,
+ R_SPARC_64 = 32,
+ R_SPARC_OLO10 = 33,
+ R_SPARC_HH22 = 34,
+ R_SPARC_HM10 = 35,
+ R_SPARC_LM22 = 36,
+ R_SPARC_PC_HH22 = 37,
+ R_SPARC_PC_HM10 = 38,
+ R_SPARC_PC_LM22 = 39,
+ R_SPARC_WDISP16 = 40,
+ R_SPARC_WDISP19 = 41,
+ R_SPARC_7 = 43,
+ R_SPARC_5 = 44,
+ R_SPARC_6 = 45,
+ R_SPARC_DISP64 = 46,
+ R_SPARC_PLT64 = 47,
+ R_SPARC_HIX22 = 48,
+ R_SPARC_LOX10 = 49,
+ R_SPARC_H44 = 50,
+ R_SPARC_M44 = 51,
+ R_SPARC_L44 = 52,
+ R_SPARC_REGISTER = 53,
+ R_SPARC_UA64 = 54,
+ R_SPARC_UA16 = 55,
+ R_SPARC_TLS_GD_HI22 = 56,
+ R_SPARC_TLS_GD_LO10 = 57,
+ R_SPARC_TLS_GD_ADD = 58,
+ R_SPARC_TLS_GD_CALL = 59,
+ R_SPARC_TLS_LDM_HI22 = 60,
+ R_SPARC_TLS_LDM_LO10 = 61,
+ R_SPARC_TLS_LDM_ADD = 62,
+ R_SPARC_TLS_LDM_CALL = 63,
+ R_SPARC_TLS_LDO_HIX22 = 64,
+ R_SPARC_TLS_LDO_LOX10 = 65,
+ R_SPARC_TLS_LDO_ADD = 66,
+ R_SPARC_TLS_IE_HI22 = 67,
+ R_SPARC_TLS_IE_LO10 = 68,
+ R_SPARC_TLS_IE_LD = 69,
+ R_SPARC_TLS_IE_LDX = 70,
+ R_SPARC_TLS_IE_ADD = 71,
+ R_SPARC_TLS_LE_HIX22 = 72,
+ R_SPARC_TLS_LE_LOX10 = 73,
+ R_SPARC_TLS_DTPMOD32 = 74,
+ R_SPARC_TLS_DTPMOD64 = 75,
+ R_SPARC_TLS_DTPOFF32 = 76,
+ R_SPARC_TLS_DTPOFF64 = 77,
+ R_SPARC_TLS_TPOFF32 = 78,
+ R_SPARC_TLS_TPOFF64 = 79,
+ R_SPARC_GOTDATA_HIX22 = 80,
+ R_SPARC_GOTDATA_LOX22 = 81,
+ R_SPARC_GOTDATA_OP_HIX22 = 82,
+ R_SPARC_GOTDATA_OP_LOX22 = 83,
+ R_SPARC_GOTDATA_OP = 84
+};
+
// Section header.
struct Elf32_Shdr {
Elf32_Word sh_name; // Section name (index into string table)
@@ -1130,7 +1225,7 @@ enum {
};
// Section types.
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
SHT_NULL = 0, // No associated section (inactive entry).
SHT_PROGBITS = 1, // Program-defined contents.
SHT_SYMTAB = 2, // Symbol table.
@@ -1178,7 +1273,7 @@ enum LLVM_ENUM_INT_TYPE(unsigned) {
};
// Section flags.
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
// Section data should be writable during execution.
SHF_WRITE = 0x1,
@@ -1270,7 +1365,7 @@ enum LLVM_ENUM_INT_TYPE(unsigned) {
};
// Section Group Flags
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
GRP_COMDAT = 0x1,
GRP_MASKOS = 0x0ff00000,
GRP_MASKPROC = 0xf0000000
@@ -1492,7 +1587,7 @@ enum {
};
// Segment flag bits.
-enum LLVM_ENUM_INT_TYPE(unsigned) {
+enum : unsigned {
PF_X = 1, // Execute
PF_W = 2, // Write
PF_R = 4, // Read
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 0d35849..2c5ab74 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -17,7 +17,6 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/SwapByteOrder.h"
-#include "llvm/Support/type_traits.h"
namespace llvm {
namespace support {
@@ -35,6 +34,7 @@ namespace detail {
} // end namespace detail
namespace endian {
+/// Swap the bytes of value to match the given endianness.
template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) {
if (endian != native && sys::IsBigEndianHost != (endian == big))
@@ -42,6 +42,7 @@ inline value_type byte_swap(value_type value) {
return value;
}
+/// Read a value of a particular endianness from memory.
template<typename value_type,
endianness endian,
std::size_t alignment>
@@ -55,6 +56,16 @@ inline value_type read(const void *memory) {
return byte_swap<value_type, endian>(ret);
}
+/// Read a value of a particular endianness from a buffer, and increment the
+/// buffer past that value.
+template<typename value_type, endianness endian, std::size_t alignment>
+inline value_type readNext(const unsigned char *&memory) {
+ value_type ret = read<value_type, endian, alignment>(memory);
+ memory += sizeof(value_type);
+ return ret;
+}
+
+/// Write a value to memory with a particular endianness.
template<typename value_type,
endianness endian,
std::size_t alignment>
diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h
new file mode 100644
index 0000000..89c66d3
--- /dev/null
+++ b/include/llvm/Support/EndianStream.h
@@ -0,0 +1,39 @@
+//===- EndianStream.h - Stream ops 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 defines utilities for operating on streams that have endian
+// specific data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LLVM_SUPPORT_ENDIAN_STREAM_H_
+#define _LLVM_SUPPORT_ENDIAN_STREAM_H_
+
+#include <llvm/Support/Endian.h>
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+namespace support {
+
+namespace endian {
+/// Adapter to write values to a stream in a particular byte order.
+template <endianness endian> struct Writer {
+ raw_ostream &OS;
+ Writer(raw_ostream &OS) : OS(OS) {}
+ template <typename value_type> void write(value_type Val) {
+ Val = byte_swap<value_type, endian>(Val);
+ OS.write((const char *)&Val, sizeof(value_type));
+ }
+};
+} // end namespace endian
+
+} // end namespace support
+} // end namespace llvm
+
+#endif // _LLVM_SUPPORT_ENDIAN_STREAM_H_
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index d5b11cb..becd957 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -19,15 +19,10 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Support/type_traits.h"
-
#include <cassert>
-#if LLVM_HAS_CXX11_TYPETRAITS
#include <type_traits>
-#endif
namespace llvm {
-#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES
template<class T, class V>
typename std::enable_if< std::is_constructible<T, V>::value
, typename std::remove_reference<V>::type>::type &&
@@ -41,12 +36,6 @@ typename std::enable_if< !std::is_constructible<T, V>::value
moveIfMoveConstructible(V &Val) {
return Val;
}
-#else
-template<class T, class V>
-V &moveIfMoveConstructible(V &Val) {
- return Val;
-}
-#endif
/// \brief Stores a reference that can be changed.
template <typename T>
@@ -71,11 +60,10 @@ public:
/// It is used like the following.
/// \code
/// ErrorOr<Buffer> getBuffer();
-/// void handleError(error_code ec);
///
/// auto buffer = getBuffer();
-/// if (!buffer)
-/// handleError(buffer);
+/// if (error_code ec = buffer.getError())
+/// return ec;
/// buffer->write("adena");
/// \endcode
///
@@ -93,35 +81,32 @@ public:
template<class T>
class ErrorOr {
template <class OtherT> friend class ErrorOr;
- static const bool isRef = is_reference<T>::value;
- typedef ReferenceStorage<typename remove_reference<T>::type> wrap;
+ static const bool isRef = std::is_reference<T>::value;
+ typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap;
public:
- typedef typename
- conditional< isRef
- , wrap
- , T
- >::type storage_type;
+ typedef typename std::conditional<isRef, wrap, T>::type storage_type;
private:
- typedef typename remove_reference<T>::type &reference;
- typedef typename remove_reference<T>::type *pointer;
+ typedef typename std::remove_reference<T>::type &reference;
+ typedef const typename std::remove_reference<T>::type &const_reference;
+ typedef typename std::remove_reference<T>::type *pointer;
public:
template <class E>
- ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value,
- void *>::type = 0)
+ ErrorOr(E ErrorCode, typename std::enable_if<is_error_code_enum<E>::value ||
+ is_error_condition_enum<E>::value,
+ void *>::type = 0)
: HasError(true) {
- new (getError()) error_code(make_error_code(ErrorCode));
+ new (getErrorStorage()) error_code(make_error_code(ErrorCode));
}
ErrorOr(llvm::error_code EC) : HasError(true) {
- new (getError()) error_code(EC);
+ new (getErrorStorage()) error_code(EC);
}
ErrorOr(T Val) : HasError(false) {
- new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
+ new (getStorage()) storage_type(moveIfMoveConstructible<storage_type>(Val));
}
ErrorOr(const ErrorOr &Other) {
@@ -144,7 +129,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
ErrorOr(ErrorOr &&Other) {
moveConstruct(std::move(Other));
}
@@ -164,31 +148,30 @@ public:
moveAssign(std::move(Other));
return *this;
}
-#endif
~ErrorOr() {
if (!HasError)
- get()->~storage_type();
+ getStorage()->~storage_type();
}
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
-
/// \brief Return false if there is an error.
- operator unspecified_bool_type() const {
- return HasError ? 0 : unspecified_bool_true;
+ LLVM_EXPLICIT operator bool() const {
+ return !HasError;
}
- operator llvm::error_code() const {
- return HasError ? *getError() : llvm::error_code::success();
+ reference get() { return *getStorage(); }
+ const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); }
+
+ error_code getError() const {
+ return HasError ? *getErrorStorage() : error_code::success();
}
pointer operator ->() {
- return toPointer(get());
+ return toPointer(getStorage());
}
reference operator *() {
- return *get();
+ return *getStorage();
}
private:
@@ -197,11 +180,11 @@ private:
if (!Other.HasError) {
// Get the other value.
HasError = false;
- new (get()) storage_type(*Other.get());
+ new (getStorage()) storage_type(*Other.getStorage());
} else {
// Get other's error.
HasError = true;
- new (getError()) error_code(Other);
+ new (getErrorStorage()) error_code(Other.getError());
}
}
@@ -224,17 +207,16 @@ private:
new (this) ErrorOr(Other);
}
-#if LLVM_HAS_RVALUE_REFERENCES
template <class OtherT>
void moveConstruct(ErrorOr<OtherT> &&Other) {
if (!Other.HasError) {
// Get the other value.
HasError = false;
- new (get()) storage_type(std::move(*Other.get()));
+ new (getStorage()) storage_type(std::move(*Other.getStorage()));
} else {
// Get other's error.
HasError = true;
- new (getError()) error_code(Other);
+ new (getErrorStorage()) error_code(Other.getError());
}
}
@@ -246,7 +228,6 @@ private:
this->~ErrorOr();
new (this) ErrorOr(std::move(Other));
}
-#endif
pointer toPointer(pointer Val) {
return Val;
@@ -256,23 +237,23 @@ private:
return &Val->get();
}
- storage_type *get() {
+ storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<storage_type*>(TStorage.buffer);
}
- const storage_type *get() const {
+ const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
- error_code *getError() {
+ error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
return reinterpret_cast<error_code*>(ErrorStorage.buffer);
}
- const error_code *getError() const {
- return const_cast<ErrorOr<T> *>(this)->getError();
+ const error_code *getErrorStorage() const {
+ return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
}
@@ -284,8 +265,8 @@ private:
};
template<class T, class E>
-typename enable_if_c<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::value, bool>::type
+typename std::enable_if<is_error_code_enum<E>::value ||
+ is_error_condition_enum<E>::value, bool>::type
operator ==(ErrorOr<T> &Err, E Code) {
return error_code(Err) == Code;
}
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index cbc9c46..1884a24 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -43,6 +43,9 @@ public:
static error_code create(StringRef FilePath, size_t Size,
OwningPtr<FileOutputBuffer> &Result,
unsigned Flags = 0);
+ static error_code create(StringRef FilePath, size_t Size,
+ std::unique_ptr<FileOutputBuffer> &Result,
+ unsigned Flags = 0);
/// Returns a pointer to the start of the buffer.
uint8_t *getBufferStart() {
@@ -83,7 +86,7 @@ private:
FileOutputBuffer(llvm::sys::fs::mapped_file_region *R,
StringRef Path, StringRef TempPath);
- OwningPtr<llvm::sys::fs::mapped_file_region> Region;
+ std::unique_ptr<llvm::sys::fs::mapped_file_region> Region;
SmallString<128> FinalPath;
SmallString<128> TempPath;
};
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index d301f84..b511a8e 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -28,7 +28,6 @@
#define LLVM_SUPPORT_FILESYSTEM_H
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
@@ -39,6 +38,7 @@
#include <iterator>
#include <stack>
#include <string>
+#include <tuple>
#include <vector>
#ifdef HAVE_SYS_STAT_H
@@ -49,10 +49,9 @@ namespace llvm {
namespace sys {
namespace fs {
-/// file_type - An "enum class" enumeration for the file system's view of the
-/// type.
+/// An "enum class" enumeration for the file system's view of the type.
struct file_type {
- enum _ {
+ enum Impl {
status_error,
file_not_found,
regular_file,
@@ -65,12 +64,11 @@ struct file_type {
type_unknown
};
- file_type(_ v) : v_(v) {}
- explicit file_type(int v) : v_(_(v)) {}
- operator int() const {return v_;}
+ file_type(Impl V) : V(V) {}
+ operator Impl() const { return V; }
private:
- int v_;
+ Impl V;
};
/// space_info - Self explanatory.
@@ -137,8 +135,7 @@ public:
}
bool operator!=(const UniqueID &Other) const { return !(*this == Other); }
bool operator<(const UniqueID &Other) const {
- return Device < Other.Device ||
- (Device == Other.Device && File < Other.File);
+ return std::tie(Device, File) < std::tie(Other.Device, Other.File);
}
uint64_t getDevice() const { return Device; }
uint64_t getFile() const { return File; }
@@ -272,51 +269,42 @@ private:
/// platform specific error_code.
error_code make_absolute(SmallVectorImpl<char> &path);
+/// @brief Normalize path separators in \a Path
+///
+/// If the path contains any '\' separators, they are transformed into '/'.
+/// This is particularly useful when cross-compiling Windows on Linux, but is
+/// safe to invoke on Windows, which accepts both characters as a path
+/// separator.
+error_code normalize_separators(SmallVectorImpl<char> &Path);
+
/// @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 Convenience function for clients that don't need to know if the
-/// directory existed or not.
-inline error_code create_directories(const Twine &Path) {
- bool Existed;
- return create_directories(Path, Existed);
-}
+/// @returns errc::success if is_directory(path), otherwise a platform
+/// specific error_code. If IgnoreExisting is false, also returns
+/// error if the directory already existed.
+error_code create_directories(const Twine &path, bool IgnoreExisting = true);
/// @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 Convenience function for clients that don't need to know if the
-/// directory existed or not.
-inline error_code create_directory(const Twine &Path) {
- bool Existed;
- return create_directory(Path, Existed);
-}
+/// @returns errc::success if is_directory(path), otherwise a platform
+/// specific error_code. If IgnoreExisting is false, also returns
+/// error if the directory already existed.
+error_code create_directory(const Twine &path, bool IgnoreExisting = true);
-/// @brief Create a hard link from \a from to \a to.
+/// @brief Create a link from \a from to \a to.
+///
+/// The link may be a soft or a hard link, depending on the platform. The caller
+/// may not assume which one. Currently on windows it creates a hard link since
+/// soft links require extra privileges. On unix, it creates a soft link since
+/// hard links don't work on SMB file systems.
///
/// @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);
+/// @returns errc::success if the link was created, otherwise a platform
+/// specific error_code.
+error_code create_link(const Twine &to, const Twine &from);
/// @brief Get the current path.
///
@@ -328,34 +316,10 @@ 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.
-/// @returns errc::success if path has been removed and existed has been
-/// successfully set, otherwise a platform specific error_code.
-error_code remove(const Twine &path, bool &existed);
-
-/// @brief Convenience function for clients that don't need to know if the file
-/// existed or not.
-inline error_code remove(const Twine &Path) {
- bool Existed;
- return remove(Path, 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.
-/// @returns errc::success if path has been removed and num_removed has been
-/// successfully set, otherwise a platform specific error_code.
-error_code remove_all(const Twine &path, uint32_t &num_removed);
-
-/// @brief Convenience function for clients that don't need to know how many
-/// files were removed.
-inline error_code remove_all(const Twine &Path) {
- uint32_t Removed;
- return remove_all(Path, Removed);
-}
+/// @returns errc::success if path has been removed or didn't exist, otherwise a
+/// platform specific error code. If IgnoreNonExisting is false, also
+/// returns error if the file didn't exist.
+error_code remove(const Twine &path, bool IgnoreNonExisting = true);
/// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
///
@@ -490,8 +454,7 @@ inline bool is_regular_file(const Twine &Path) {
/// directory, regular file, or symlink?
///
/// @param status A file_status previously returned from status.
-/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) &&
-/// !is_symlink(s)
+/// @returns exists(s) && !is_regular_file(s) && !is_directory(s)
bool is_other(file_status status);
/// @brief Is path something that exists but is not a directory,
@@ -504,21 +467,6 @@ bool is_other(file_status status);
/// 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.
-/// @returns 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.
-/// @returns 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.
@@ -545,6 +493,11 @@ inline error_code file_size(const Twine &Path, uint64_t &Result) {
return error_code::success();
}
+/// @brief Set the file modification and access time.
+///
+/// @returns errc::success if the file times were successfully set, otherwise a
+/// platform specific error_code or errc::not_supported on platforms
+/// where the functionality isn't available.
error_code setLastModificationAndAccessTime(int FD, TimeValue Time);
/// @brief Is status available?
@@ -621,9 +574,12 @@ enum OpenFlags {
/// 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
+ /// The file should be opened in text mode on platforms that make this
+ /// distinction.
+ F_Text = 4,
+
+ /// Open the file for read and write.
+ F_RW = 8
};
inline OpenFlags operator|(OpenFlags A, OpenFlags B) {
@@ -704,10 +660,8 @@ private:
public:
typedef char char_type;
-#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region(mapped_file_region&&);
mapped_file_region &operator =(mapped_file_region&&);
-#endif
/// Construct a mapped_file_region at \a path starting at \a offset of length
/// \a length and with access \a mode.
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 79c59e4..873b8df 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -51,8 +51,7 @@ namespace llvm {
~FileRemover() {
if (DeleteIt) {
// Ignore problems deleting the file.
- bool existed;
- sys::fs::remove(Filename.str(), existed);
+ sys::fs::remove(Filename.str());
}
}
@@ -62,8 +61,7 @@ namespace llvm {
void setFile(const Twine& filename, bool deleteIt = true) {
if (DeleteIt) {
// Ignore problems deleting the file.
- bool existed;
- sys::fs::remove(Filename.str(), existed);
+ sys::fs::remove(Filename.str());
}
Filename.clear();
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index aaa54e1..a62801f 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -84,7 +84,7 @@ public:
: format_object_base(fmt), Val(val) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val);
}
};
@@ -102,7 +102,7 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2);
}
};
@@ -121,7 +121,7 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3);
}
};
@@ -142,7 +142,7 @@ public:
: format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4);
}
};
@@ -165,7 +165,7 @@ public:
Val5(val5) {
}
- virtual int snprint(char *Buffer, unsigned BufferSize) const {
+ int snprint(char *Buffer, unsigned BufferSize) const override {
return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5);
}
};
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index df1f218..78c4809 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -57,11 +57,11 @@ private:
///
const char *Scanned;
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream,
/// not counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE {
+ uint64_t current_pos() const override {
// Our current position in the stream is all the contents which have been
// written to the underlying stream (*not* the current position of the
// underlying stream).
@@ -129,25 +129,23 @@ public:
/// getLine - Return the line number
unsigned getLine() { return Position.second; }
-
- raw_ostream &resetColor() {
+
+ raw_ostream &resetColor() override {
TheStream->resetColor();
return *this;
}
-
- raw_ostream &reverseColor() {
+
+ raw_ostream &reverseColor() override {
TheStream->reverseColor();
return *this;
}
-
- raw_ostream &changeColor(enum Colors Color,
- bool Bold,
- bool BG) {
+
+ raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
TheStream->changeColor(Color, Bold, BG);
return *this;
}
-
- bool is_displayed() const {
+
+ bool is_displayed() const override {
return TheStream->is_displayed();
}
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index 0aa716a..902f2db 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -1,4 +1,4 @@
-//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===//
+//===- GCOV.h - LLVM coverage tool ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This header provides the interface to read and write coverage files that
+// This header provides the interface to read and write coverage files that
// use 'gcov' format.
//
//===----------------------------------------------------------------------===//
@@ -16,6 +16,7 @@
#define LLVM_SUPPORT_GCOV_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -28,36 +29,69 @@ class GCOVBlock;
class FileInfo;
namespace GCOV {
- enum GCOVFormat {
- InvalidGCOV,
- GCNO_402,
- GCNO_404,
- GCDA_402,
- GCDA_404
+ enum GCOVVersion {
+ V402,
+ V404
};
} // end GCOV namespace
+/// GCOVOptions - A struct for passing gcov options between functions.
+struct GCOVOptions {
+ GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U)
+ : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
+ PreservePaths(P), UncondBranch(U) {}
+
+ bool AllBlocks;
+ bool BranchInfo;
+ bool BranchCount;
+ bool FuncCoverage;
+ bool PreservePaths;
+ bool UncondBranch;
+};
+
/// 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.
- GCOV::GCOVFormat readGCOVFormat() {
- StringRef Magic = Buffer->getBuffer().slice(0, 12);
- Cursor = 12;
- if (Magic == "oncg*404MVLL")
- return GCOV::GCNO_404;
- else if (Magic == "oncg*204MVLL")
- return GCOV::GCNO_402;
- else if (Magic == "adcg*404MVLL")
- return GCOV::GCDA_404;
- else if (Magic == "adcg*204MVLL")
- return GCOV::GCDA_402;
-
- Cursor = 0;
- return GCOV::InvalidGCOV;
+ /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
+ bool readGCNOFormat() {
+ StringRef File = Buffer->getBuffer().slice(0, 4);
+ if (File != "oncg") {
+ errs() << "Unexpected file type: " << File << ".\n";
+ return false;
+ }
+ Cursor = 4;
+ return true;
+ }
+
+ /// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
+ bool readGCDAFormat() {
+ StringRef File = Buffer->getBuffer().slice(0, 4);
+ if (File != "adcg") {
+ errs() << "Unexpected file type: " << File << ".\n";
+ return false;
+ }
+ Cursor = 4;
+ return true;
+ }
+
+ /// readGCOVVersion - Read GCOV version.
+ bool readGCOVVersion(GCOV::GCOVVersion &Version) {
+ StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4);
+ if (VersionStr == "*204") {
+ Cursor += 4;
+ Version = GCOV::V402;
+ return true;
+ }
+ if (VersionStr == "*404") {
+ Cursor += 4;
+ Version = GCOV::V404;
+ return true;
+ }
+ errs() << "Unexpected version: " << VersionStr << ".\n";
+ return false;
}
/// readFunctionTag - If cursor points to a function tag then increment the
@@ -170,8 +204,11 @@ public:
}
bool readString(StringRef &Str) {
- uint32_t Len;
- if (!readInt(Len)) return false;
+ uint32_t Len = 0;
+ // Keep reading until we find a non-zero length. This emulates gcov's
+ // behaviour, which appears to do the same.
+ while (Len == 0)
+ if (!readInt(Len)) return false;
Len *= 4;
if (Buffer->getBuffer().size() < Cursor+Len) {
errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
@@ -193,67 +230,188 @@ private:
/// (.gcno and .gcda).
class GCOVFile {
public:
- GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {}
+ GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
+ ProgramCount(0) {}
~GCOVFile();
- bool read(GCOVBuffer &Buffer);
- void dump();
+ bool readGCNO(GCOVBuffer &Buffer);
+ bool readGCDA(GCOVBuffer &Buffer);
+ uint32_t getChecksum() const { return Checksum; }
+ void dump() const;
void collectLineCounts(FileInfo &FI);
private:
+ bool GCNOInitialized;
+ GCOV::GCOVVersion Version;
+ uint32_t Checksum;
SmallVector<GCOVFunction *, 16> Functions;
uint32_t RunCount;
uint32_t ProgramCount;
};
+/// GCOVEdge - Collects edge information.
+struct GCOVEdge {
+ GCOVEdge(GCOVBlock *S, GCOVBlock *D): Src(S), Dst(D), Count(0) {}
+
+ GCOVBlock *Src;
+ GCOVBlock *Dst;
+ uint64_t Count;
+};
+
/// GCOVFunction - Collects function information.
class GCOVFunction {
public:
- GCOVFunction() : Ident(0), LineNumber(0) {}
+ typedef SmallVectorImpl<GCOVBlock *>::const_iterator BlockIterator;
+
+ GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
~GCOVFunction();
- bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
+ bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
+ bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
+ StringRef getName() const { return Name; }
StringRef getFilename() const { return Filename; }
- void dump();
+ size_t getNumBlocks() const { return Blocks.size(); }
+ uint64_t getEntryCount() const;
+ uint64_t getExitCount() const;
+
+ BlockIterator block_begin() const { return Blocks.begin(); }
+ BlockIterator block_end() const { return Blocks.end(); }
+
+ void dump() const;
void collectLineCounts(FileInfo &FI);
private:
+ GCOVFile &Parent;
uint32_t Ident;
+ uint32_t Checksum;
uint32_t LineNumber;
StringRef Name;
StringRef Filename;
SmallVector<GCOVBlock *, 16> Blocks;
+ SmallVector<GCOVEdge *, 16> Edges;
};
/// GCOVBlock - Collects block information.
class GCOVBlock {
+ struct EdgeWeight {
+ EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {}
+
+ GCOVBlock *Dst;
+ uint64_t Count;
+ };
+
+ struct SortDstEdgesFunctor {
+ bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) {
+ return E1->Dst->Number < E2->Dst->Number;
+ }
+ };
public:
- GCOVBlock(GCOVFunction &P, uint32_t N) :
- Parent(P), Number(N), Counter(0), Edges(), Lines() {}
+ typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator;
+
+ GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
+ DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
~GCOVBlock();
- void addEdge(uint32_t N) { Edges.push_back(N); }
+ const GCOVFunction &getParent() const { return Parent; }
void addLine(uint32_t N) { Lines.push_back(N); }
- void addCount(uint64_t N) { Counter += N; }
- size_t getNumEdges() { return Edges.size(); }
- void dump();
+ uint32_t getLastLine() const { return Lines.back(); }
+ void addCount(size_t DstEdgeNo, uint64_t N);
+ uint64_t getCount() const { return Counter; }
+
+ void addSrcEdge(GCOVEdge *Edge) {
+ assert(Edge->Dst == this); // up to caller to ensure edge is valid
+ SrcEdges.push_back(Edge);
+ }
+ void addDstEdge(GCOVEdge *Edge) {
+ assert(Edge->Src == this); // up to caller to ensure edge is valid
+ // Check if adding this edge causes list to become unsorted.
+ if (DstEdges.size() && DstEdges.back()->Dst->Number > Edge->Dst->Number)
+ DstEdgesAreSorted = false;
+ DstEdges.push_back(Edge);
+ }
+ size_t getNumSrcEdges() const { return SrcEdges.size(); }
+ size_t getNumDstEdges() const { return DstEdges.size(); }
+ void sortDstEdges();
+
+ EdgeIterator src_begin() const { return SrcEdges.begin(); }
+ EdgeIterator src_end() const { return SrcEdges.end(); }
+ EdgeIterator dst_begin() const { return DstEdges.begin(); }
+ EdgeIterator dst_end() const { return DstEdges.end(); }
+
+ void dump() const;
void collectLineCounts(FileInfo &FI);
private:
GCOVFunction &Parent;
uint32_t Number;
uint64_t Counter;
- SmallVector<uint32_t, 16> Edges;
+ bool DstEdgesAreSorted;
+ SmallVector<GCOVEdge *, 16> SrcEdges;
+ SmallVector<GCOVEdge *, 16> DstEdges;
SmallVector<uint32_t, 16> Lines;
};
-typedef DenseMap<uint32_t, uint64_t> LineCounts;
class FileInfo {
+ // It is unlikely--but possible--for multiple functions to be on the same line.
+ // Therefore this typedef allows LineData.Functions to store multiple functions
+ // per instance. This is rare, however, so optimize for the common case.
+ typedef SmallVector<const GCOVFunction *, 1> FunctionVector;
+ typedef DenseMap<uint32_t, FunctionVector> FunctionLines;
+ typedef SmallVector<const GCOVBlock *, 4> BlockVector;
+ typedef DenseMap<uint32_t, BlockVector> BlockLines;
+
+ struct LineData {
+ BlockLines Blocks;
+ FunctionLines Functions;
+ };
+
+ struct GCOVCoverage {
+ GCOVCoverage(StringRef Name) :
+ Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
+ BranchesTaken(0) {}
+
+ StringRef Name;
+
+ uint32_t LogicalLines;
+ uint32_t LinesExec;
+
+ uint32_t Branches;
+ uint32_t BranchesExec;
+ uint32_t BranchesTaken;
+ };
public:
- void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
- LineInfo[Filename][Line-1] += Count;
+ FileInfo(const GCOVOptions &Options) :
+ Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
+
+ void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
+ LineInfo[Filename].Blocks[Line-1].push_back(Block);
+ }
+ void addFunctionLine(StringRef Filename, uint32_t Line,
+ const GCOVFunction *Function) {
+ LineInfo[Filename].Functions[Line-1].push_back(Function);
}
void setRunCount(uint32_t Runs) { RunCount = Runs; }
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
- void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile);
+ void print(StringRef GCNOFile, StringRef GCDAFile);
private:
- StringMap<LineCounts> LineInfo;
+ void printFunctionSummary(raw_fd_ostream &OS,
+ const FunctionVector &Funcs) const;
+ void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
+ uint32_t LineIndex, uint32_t &BlockNo) const;
+ void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
+ GCOVCoverage &Coverage, uint32_t &EdgeNo);
+ void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
+ uint64_t Count) const;
+
+ void printCoverage(const GCOVCoverage &Coverage) const;
+ void printFuncCoverage() const;
+ void printFileCoverage() const;
+
+ const GCOVOptions &Options;
+ StringMap<LineData> LineInfo;
uint32_t RunCount;
uint32_t ProgramCount;
+
+ typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4>
+ FileCoverageList;
+ typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap;
+
+ FileCoverageList FileCoverages;
+ FuncCoverageMap FuncCoverages;
};
}
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Support/GenericDomTree.h
index 3aa0beb..6878844 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -1,4 +1,4 @@
-//===- llvm/Analysis/Dominators.h - Dominator Info Calculation --*- C++ -*-===//
+//===- GenericDomTree.h - Generic dominator trees for graphs ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,23 +6,23 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the DominatorTree class, which provides fast and efficient
-// dominance queries.
-//
+/// \file
+///
+/// This file defines a set of templates that efficiently compute a dominator
+/// tree over a generic graph. This is used typically in LLVM for fast
+/// dominance queries on the CFG, but is fully generic w.r.t. the underlying
+/// graph types.
+///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_DOMINATORS_H
-#define LLVM_ANALYSIS_DOMINATORS_H
+#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H
+#define LLVM_SUPPORT_GENERIC_DOM_TREE_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/Function.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -55,17 +55,16 @@ public:
//===----------------------------------------------------------------------===//
-// DomTreeNode - Dominator Tree Node
+// DomTreeNodeBase - 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;
+ mutable int DFSNumIn, DFSNumOut;
template<class N> friend class DominatorTreeBase;
friend struct PostDominatorTree;
@@ -148,14 +147,11 @@ private:
}
};
-EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
-EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
-
template<class NodeT>
inline raw_ostream &operator<<(raw_ostream &o,
const DomTreeNodeBase<NodeT> *Node) {
if (Node->getBlock())
- WriteAsOperand(o, Node->getBlock(), false);
+ Node->getBlock()->printAsOperand(o, false);
else
o << " <<exit node>>";
@@ -173,8 +169,6 @@ inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
PrintDomTree<NodeT>(*I, o, Lev+1);
}
-typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
-
//===----------------------------------------------------------------------===//
/// DominatorTree - Calculate the immediate dominator tree for a function.
///
@@ -202,8 +196,8 @@ protected:
DomTreeNodeMapType DomTreeNodes;
DomTreeNodeBase<NodeT> *RootNode;
- bool DFSInfoValid;
- unsigned int SlowQueries;
+ mutable bool DFSInfoValid;
+ mutable unsigned int SlowQueries;
// Information record used during immediate dominators computation.
struct InfoRec {
unsigned DFSNum;
@@ -216,7 +210,7 @@ protected:
DenseMap<NodeT*, NodeT*> IDoms;
- // Vertex - Map the DFS number to the BasicBlock*
+ // Vertex - Map the DFS number to the NodeT*
std::vector<NodeT*> Vertex;
// Info - Collection of information used during the computation of idoms.
@@ -303,7 +297,7 @@ public:
/// compare - Return false if the other dominator tree base matches this
/// dominator tree base. Otherwise return true.
- bool compare(DominatorTreeBase &Other) const {
+ bool compare(const DominatorTreeBase &Other) const {
const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
if (DomTreeNodes.size() != OtherDomTreeNodes.size())
@@ -346,12 +340,14 @@ public:
DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
- /// Get all nodes dominated by R, including R itself. Return true on success.
+ /// Get all nodes dominated by R, including R itself.
void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
+ Result.clear();
const DomTreeNodeBase<NodeT> *RN = getNode(R);
+ if (RN == NULL)
+ return; // If R is unreachable, it will not be present in the DOM tree.
SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
WL.push_back(RN);
- Result.clear();
while (!WL.empty()) {
const DomTreeNodeBase<NodeT> *N = WL.pop_back_val();
@@ -364,7 +360,7 @@ public:
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
- const DomTreeNodeBase<NodeT> *B) {
+ const DomTreeNodeBase<NodeT> *B) const {
if (A == 0 || B == 0)
return false;
if (A == B)
@@ -372,7 +368,7 @@ public:
return dominates(A, B);
}
- bool properlyDominates(const NodeT *A, const NodeT *B);
+ bool properlyDominates(const NodeT *A, const NodeT *B) const;
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
@@ -390,7 +386,7 @@ public:
/// constant time operation!
///
inline bool dominates(const DomTreeNodeBase<NodeT> *A,
- const DomTreeNodeBase<NodeT> *B) {
+ const DomTreeNodeBase<NodeT> *B) const {
// A node trivially dominates itself.
if (B == A)
return true;
@@ -425,7 +421,7 @@ public:
return dominatedBySlowTreeWalk(A, B);
}
- bool dominates(const NodeT *A, const NodeT *B);
+ bool dominates(const NodeT *A, const NodeT *B) const;
NodeT *getRoot() const {
assert(this->Roots.size() == 1 && "Should always have entry node!");
@@ -590,13 +586,13 @@ protected:
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
- void updateDFSNumbers() {
+ void updateDFSNumbers() const {
unsigned DFSNum = 0;
- SmallVector<std::pair<DomTreeNodeBase<NodeT>*,
- typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
+ SmallVector<std::pair<const DomTreeNodeBase<NodeT>*,
+ typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack;
- DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
+ const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
if (!ThisRoot)
return;
@@ -609,8 +605,8 @@ protected:
ThisRoot->DFSNumIn = DFSNum++;
while (!WorkStack.empty()) {
- DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
- typename DomTreeNodeBase<NodeT>::iterator ChildIt =
+ const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
+ typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
WorkStack.back().second;
// If we visited all of the children of this node, "recurse" back up the
@@ -620,7 +616,7 @@ protected:
WorkStack.pop_back();
} else {
// Otherwise, recursively visit this child.
- DomTreeNodeBase<NodeT> *Child = *ChildIt;
+ const DomTreeNodeBase<NodeT> *Child = *ChildIt;
++WorkStack.back().second;
WorkStack.push_back(std::make_pair(Child, Child->begin()));
@@ -643,7 +639,7 @@ protected:
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
+ // Add a new tree node for this NodeT, and link it as a child of
// IDomNode
DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
return this->DomTreeNodes[BB] = IDomNode->addChild(C);
@@ -693,7 +689,7 @@ public:
// 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) {
+bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
if (A == B)
return true;
@@ -705,7 +701,7 @@ bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
}
template<class NodeT>
bool
-DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
+DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const {
if (A == B)
return false;
@@ -716,225 +712,6 @@ DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
getNode(const_cast<NodeT *>(B)));
}
-EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
-
-class BasicBlockEdge {
- const BasicBlock *Start;
- const BasicBlock *End;
-public:
- BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
- Start(Start_), End(End_) { }
- const BasicBlock *getStart() const {
- return Start;
- }
- const BasicBlock *getEnd() const {
- return End;
- }
- bool isSingleEdge() const;
-};
-
-//===-------------------------------------
-/// 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();
- }
-
- /// Get all nodes dominated by R, including R itself. Return true on success.
- void getDescendants(BasicBlock *R,
- SmallVectorImpl<BasicBlock *> &Result) const {
- DT->getDescendants(R, Result);
- }
-
- /// 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 dominates(const BasicBlockEdge &BBE, const Use &U) const;
- bool dominates(const BasicBlockEdge &BBE, 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/include/llvm/Analysis/DominatorInternals.h b/include/llvm/Support/GenericDomTreeConstruction.h
index c0f95cb..f6bb8f4 100644
--- a/include/llvm/Analysis/DominatorInternals.h
+++ b/include/llvm/Support/GenericDomTreeConstruction.h
@@ -1,4 +1,4 @@
-//=== llvm/Analysis/DominatorInternals.h - Dominator Calculation -*- C++ -*-==//
+//===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -6,27 +6,27 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Generic dominator tree construction - This file provides routines to
+/// construct 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.
+///
+//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
-#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Analysis/Dominators.h"
+#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H
+#define LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_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.
-//
-//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/GenericDomTree.h"
namespace llvm {
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index 28c4cc7..8f4bf3c 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -55,7 +55,7 @@ namespace sys {
/// target which matches the host.
///
/// \return - The host CPU name, or empty if the CPU could not be determined.
- std::string getHostCPUName();
+ StringRef getHostCPUName();
/// getHostCPUFeatures - Get the LLVM names for the host CPU features.
/// The particular format of the names are target dependent, and suitable for
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index 3d73792..9ef5fe6 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -90,6 +90,12 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) {
return Value;
}
+/// Utility function to get the size of the ULEB128-encoded value.
+extern unsigned getULEB128Size(uint64_t Value);
+
+/// Utility function to get the size of the SLEB128-encoded value.
+extern unsigned getSLEB128Size(int64_t Value);
+
} // namespace llvm
#endif // LLVM_SYSTEM_LEB128_H
diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h
new file mode 100644
index 0000000..7077656
--- /dev/null
+++ b/include/llvm/Support/LineIterator.h
@@ -0,0 +1,84 @@
+//===- LineIterator.h - Iterator to read a text buffer's lines --*- 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_LINEITERATOR_H__
+#define LLVM_SUPPORT_LINEITERATOR_H__
+
+#include "llvm/ADT/StringRef.h"
+#include <iterator>
+
+namespace llvm {
+
+class MemoryBuffer;
+
+/// \brief A forward iterator which reads non-blank text lines from a buffer.
+///
+/// This class provides a forward iterator interface for reading one line at
+/// a time from a buffer. When default constructed the iterator will be the
+/// "end" iterator.
+///
+/// The iterator also is aware of what line number it is currently processing
+/// and can strip comment lines given the comment-starting character.
+///
+/// Note that this iterator requires the buffer to be nul terminated.
+class line_iterator
+ : public std::iterator<std::forward_iterator_tag, StringRef, ptrdiff_t> {
+ const MemoryBuffer *Buffer;
+ char CommentMarker;
+
+ unsigned LineNumber;
+ StringRef CurrentLine;
+
+public:
+ /// \brief Default construct an "end" iterator.
+ line_iterator() : Buffer(0) {}
+
+ /// \brief Construct a new iterator around some memory buffer.
+ explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0');
+
+ /// \brief Return true if we've reached EOF or are an "end" iterator.
+ bool is_at_eof() const { return !Buffer; }
+
+ /// \brief Return true if we're an "end" iterator or have reached EOF.
+ bool is_at_end() const { return is_at_eof(); }
+
+ /// \brief Return the current line number. May return any number at EOF.
+ int64_t line_number() const { return LineNumber; }
+
+ /// \brief Advance to the next (non-empty, non-comment) line.
+ line_iterator &operator++() {
+ advance();
+ return *this;
+ }
+ line_iterator operator++(int) {
+ line_iterator tmp(*this);
+ advance();
+ return tmp;
+ }
+
+ /// \brief Get the current line as a \c StringRef.
+ StringRef operator*() const { return CurrentLine; }
+ const StringRef *operator->() const { return &CurrentLine; }
+
+ friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) {
+ return LHS.Buffer == RHS.Buffer &&
+ LHS.CurrentLine.begin() == RHS.CurrentLine.begin();
+ }
+
+ friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) {
+ return !(LHS == RHS);
+ }
+
+private:
+ /// \brief Advance the iterator to the next line.
+ void advance();
+};
+}
+
+#endif // LLVM_SUPPORT_LINEITERATOR_H__
diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h
index b2b8c2d..4eb8507 100644
--- a/include/llvm/Support/MD5.h
+++ b/include/llvm/Support/MD5.h
@@ -28,13 +28,12 @@
#ifndef LLVM_SYSTEM_MD5_H
#define LLVM_SYSTEM_MD5_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
-template <typename T> class ArrayRef;
-
class MD5 {
// Any 32-bit or wider unsigned integer data type will do.
typedef uint32_t MD5_u32plus;
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 897a611..ef06a41 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -21,7 +21,7 @@
namespace llvm {
namespace MachO {
// Enums from <mach-o/loader.h>
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constants for the "magic" field in llvm::MachO::mach_header and
// llvm::MachO::mach_header_64
MH_MAGIC = 0xFEEDFACEu,
@@ -76,12 +76,12 @@ namespace llvm {
MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Flags for the "cmd" field in llvm::MachO::load_command
LC_REQ_DYLD = 0x80000000u
};
- enum LoadCommandType LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum LoadCommandType : uint32_t {
// Constants for the "cmd" field in llvm::MachO::load_command
LC_SEGMENT = 0x00000001u,
LC_SYMTAB = 0x00000002u,
@@ -128,10 +128,11 @@ namespace llvm {
LC_SOURCE_VERSION = 0x0000002Au,
LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu,
// 0x0000002Cu,
- LC_LINKER_OPTIONS = 0x0000002Du
+ LC_LINKER_OPTIONS = 0x0000002Du,
+ LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constant bits for the "flags" field in llvm::MachO::segment_command
SG_HIGHVM = 0x1u,
SG_FVMLIB = 0x2u,
@@ -147,7 +148,9 @@ namespace llvm {
SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS
};
- enum SectionType {
+ /// 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 SectionType : uint32_t {
// Constant masks for the "flags[7:0]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
S_REGULAR = 0x00u,
@@ -171,10 +174,12 @@ namespace llvm {
S_THREAD_LOCAL_ZEROFILL = 0x12u,
S_THREAD_LOCAL_VARIABLES = 0x13u,
S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
- S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u
+ S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u,
+
+ LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constant masks for the "flags[31:24]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
@@ -348,7 +353,7 @@ namespace llvm {
N_LENG = 0xFEu
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Constant values for the r_symbolnum field in an
// llvm::MachO::relocation_info structure when r_extern is 0.
R_ABS = 0,
@@ -403,6 +408,34 @@ namespace llvm {
ARM_RELOC_HALF = 8,
ARM_RELOC_HALF_SECTDIFF = 9,
+ // Constant values for the r_type field in an ARM64 architecture
+ // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
+ // structure.
+
+ // For pointers.
+ ARM64_RELOC_UNSIGNED = 0,
+ // Must be followed by an ARM64_RELOC_UNSIGNED
+ ARM64_RELOC_SUBTRACTOR = 1,
+ // A B/BL instruction with 26-bit displacement.
+ ARM64_RELOC_BRANCH26 = 2,
+ // PC-rel distance to page of target.
+ ARM64_RELOC_PAGE21 = 3,
+ // Offset within page, scaled by r_length.
+ ARM64_RELOC_PAGEOFF12 = 4,
+ // PC-rel distance to page of GOT slot.
+ ARM64_RELOC_GOT_LOAD_PAGE21 = 5,
+ // Offset within page of GOT slot, scaled by r_length.
+ ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6,
+ // For pointers to GOT slots.
+ ARM64_RELOC_POINTER_TO_GOT = 7,
+ // PC-rel distance to page of TLVP slot.
+ ARM64_RELOC_TLVP_LOAD_PAGE21 = 8,
+ // Offset within page of TLVP slot, scaled by r_length.
+ ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9,
+ // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12.
+ ARM64_RELOC_ADDEND = 10,
+
+
// Constant values for the r_type field in an x86_64 architecture
// llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info
// structure
@@ -739,9 +772,10 @@ namespace llvm {
};
struct version_min_command {
- uint32_t cmd;
- uint32_t cmdsize;
- uint32_t version;
+ uint32_t cmd; // LC_VERSION_MIN_MACOSX or
+ // LC_VERSION_MIN_IPHONEOS
+ uint32_t cmdsize; // sizeof(struct version_min_command)
+ uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz
uint32_t reserved;
};
@@ -893,7 +927,7 @@ namespace llvm {
}
// Enums from <mach/machine.h>
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Capability bits used in the definition of cpu_type.
CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits
CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI
@@ -908,12 +942,13 @@ namespace llvm {
/* CPU_TYPE_MIPS = 8, */
CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC
CPU_TYPE_ARM = 12,
+ CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64,
CPU_TYPE_SPARC = 14,
CPU_TYPE_POWERPC = 18,
CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
};
- enum LLVM_ENUM_INT_TYPE(uint32_t) {
+ enum : uint32_t {
// Capability bits used in the definition of cpusubtype.
CPU_SUB_TYPE_MASK = 0xff000000, // Mask for architecture bits
CPU_SUB_TYPE_LIB64 = 0x80000000, // 64 bit libraries
@@ -973,7 +1008,7 @@ namespace llvm {
CPU_SUBTYPE_ARM_V5TEJ = 7,
CPU_SUBTYPE_ARM_XSCALE = 8,
CPU_SUBTYPE_ARM_V7 = 9,
- CPU_SUBTYPE_ARM_V7F = 10,
+ // unused ARM_V7F = 10,
CPU_SUBTYPE_ARM_V7S = 11,
CPU_SUBTYPE_ARM_V7K = 12,
CPU_SUBTYPE_ARM_V6M = 14,
@@ -981,6 +1016,10 @@ namespace llvm {
CPU_SUBTYPE_ARM_V7EM = 16
};
+ enum CPUSubTypeARM64 {
+ CPU_SUBTYPE_ARM64_ALL = 0
+ };
+
enum CPUSubTypeSPARC {
CPU_SUBTYPE_SPARC_ALL = 0
};
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index ff41608..f1f7b4f 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -16,9 +16,9 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SwapByteOrder.h"
-#include "llvm/Support/type_traits.h"
-
+#include <cassert>
#include <cstring>
+#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
@@ -44,8 +44,8 @@ enum ZeroBehavior {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, std::size_t>::type
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
(void)ZB;
@@ -71,8 +71,8 @@ countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, std::size_t>::type
countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
#if __GNUC__ >= 4 || _MSC_VER
@@ -115,8 +115,8 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, std::size_t>::type
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
(void)ZB;
@@ -137,8 +137,8 @@ countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, std::size_t>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, std::size_t>::type
countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION;
#if __GNUC__ >= 4 || _MSC_VER
@@ -181,8 +181,8 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) {
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, T>::type
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
@@ -192,8 +192,8 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, T>::type
findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \brief Get the index of the last set bit starting from the least
@@ -204,8 +204,8 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
/// valid arguments.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed, T>::type
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
if (ZB == ZB_Max && Val == 0)
return std::numeric_limits<T>::max();
@@ -218,8 +218,8 @@ findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
// Disable signed.
template <typename T>
-typename enable_if_c<std::numeric_limits<T>::is_integer &&
- std::numeric_limits<T>::is_signed, T>::type
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed, T>::type
findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION;
/// \brief Macro compressed bit reversal table for 256 bits.
@@ -541,6 +541,18 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) {
return (A | B) & (1 + ~(A | B));
}
+/// \brief Aligns \c Ptr to \c 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.
+inline char *alignPtr(char *Ptr, size_t Alignment) {
+ assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
+ "Alignment is not a power of two!");
+
+ return (char *)(((uintptr_t)Ptr + Alignment - 1) &
+ ~(uintptr_t)(Alignment - 1));
+}
+
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
/// that is strictly greater than A. Returns zero on overflow.
inline uint64_t NextPowerOf2(uint64_t A) {
@@ -553,6 +565,13 @@ inline uint64_t NextPowerOf2(uint64_t A) {
return A + 1;
}
+/// Returns the power of two which is less than or equal to the given value.
+/// Essentially, it is a floor operation across the domain of powers of two.
+inline uint64_t PowerOf2Floor(uint64_t A) {
+ if (!A) return 0;
+ return 1ull << (63 - countLeadingZeros(A, ZB_Undefined));
+}
+
/// Returns the next integer (mod 2**64) that is greater than or equal to
/// \p Value and is a multiple of \p Align. \p Align must be non-zero.
///
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index a08c796..8251fcd 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -95,7 +95,7 @@ namespace sys {
/// memory was not allocated using the allocateMappedMemory method.
/// \p Block describes the memory block to be protected.
/// \p Flags specifies the new protection state to be assigned to the block.
- /// \p ErrMsg [out] returns a string describing any error that occured.
+ /// \p ErrMsg [out] returns a string describing any error that occurred.
///
/// If \p Flags is MF_WRITE, the actual behavior varies
/// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index ff22fb6..578c7e8 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -14,11 +14,12 @@
#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
#define LLVM_SUPPORT_MEMORYBUFFER_H
+#include "llvm-c/Support.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm-c/Core.h"
+#include <memory>
namespace llvm {
@@ -66,7 +67,11 @@ public:
/// 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(Twine Filename, OwningPtr<MemoryBuffer> &result,
+ static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &Result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true);
+ static error_code getFile(Twine Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
int64_t FileSize = -1,
bool RequiresNullTerminator = true);
@@ -76,6 +81,9 @@ public:
static error_code getOpenFileSlice(int FD, const char *Filename,
OwningPtr<MemoryBuffer> &Result,
uint64_t MapSize, int64_t Offset);
+ static error_code getOpenFileSlice(int FD, const char *Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
+ uint64_t MapSize, int64_t Offset);
/// Given an already-open file descriptor, read the file and return a
/// MemoryBuffer.
@@ -83,6 +91,10 @@ public:
OwningPtr<MemoryBuffer> &Result,
uint64_t FileSize,
bool RequiresNullTerminator = true);
+ static error_code getOpenFile(int FD, const char *Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
+ uint64_t FileSize,
+ bool RequiresNullTerminator = true);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that InputData must be null terminated if RequiresNullTerminator is true.
@@ -111,14 +123,18 @@ public:
/// 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);
+ static error_code getSTDIN(OwningPtr<MemoryBuffer> &Result);
+ static error_code getSTDIN(std::unique_ptr<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,
+ OwningPtr<MemoryBuffer> &Result,
+ int64_t FileSize = -1);
+ static error_code getFileOrSTDIN(StringRef Filename,
+ std::unique_ptr<MemoryBuffer> &Result,
int64_t FileSize = -1);
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index b2afe1b..ba18529 100644
--- a/include/llvm/Support/Path.h
+++ b/include/llvm/Support/Path.h
@@ -306,6 +306,12 @@ bool is_separator(char value);
/// @param result Holds the resulting path name.
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
+/// @brief Get the user's home directory.
+///
+/// @param result Holds the resulting path name.
+/// @result True if a home directory is set, false otherwise.
+bool home_directory(SmallVectorImpl<char> &result);
+
/// @brief Has root name?
///
/// root_name != ""
diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h
index 4f68fca..914141a 100644
--- a/include/llvm/Support/PrettyStackTrace.h
+++ b/include/llvm/Support/PrettyStackTrace.h
@@ -50,7 +50,7 @@ namespace llvm {
const char *Str;
public:
PrettyStackTraceString(const char *str) : Str(str) {}
- virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
+ void print(raw_ostream &OS) const override;
};
/// PrettyStackTraceProgram - This object prints a specified program arguments
@@ -63,7 +63,7 @@ namespace llvm {
: ArgC(argc), ArgV(argv) {
EnablePrettyStackTrace();
}
- virtual void print(raw_ostream &OS) const LLVM_OVERRIDE;
+ void print(raw_ostream &OS) const override;
};
} // end namespace llvm
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 2172036..7f6441e 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -29,9 +29,9 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/system_error.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/system_error.h"
namespace llvm {
class StringRef;
@@ -110,10 +110,10 @@ class self_process : public process {
virtual ~self_process();
public:
- virtual id_type get_id();
- virtual TimeValue get_user_time() const;
- virtual TimeValue get_system_time() const;
- virtual TimeValue get_wall_time() const;
+ id_type get_id() override;
+ TimeValue get_user_time() const override;
+ TimeValue get_system_time() const override;
+ TimeValue get_wall_time() const override;
/// \name Process configuration (sysconf on POSIX)
/// @{
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 00571a4..a1067a6 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -52,27 +52,31 @@ struct ProcessInfo {
ProcessInfo();
};
- /// 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.
+ /// This function attempts 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.
+ ///
+ /// It does not perform hashing as a shell would but instead stats each PATH
+ /// entry individually so should generally be avoided. Core LLVM library
+ /// functions and options should instead require fully specified paths.
+ ///
+ /// @returns A string containing the path of the program or an empty string if
+ /// the program could not be found.
std::string FindProgramByName(const std::string& name);
- // These functions change the specified standard stream (stdin, stdout, or
- // stderr) to binary mode. They return errc::success if the specified stream
+ // These functions change the specified standard stream (stdin or stdout) to
+ // binary mode. They return errc::success if the specified stream
// was changed. Otherwise a platform dependent error is returned.
error_code ChangeStdinToBinary();
error_code ChangeStdoutToBinary();
- error_code ChangeStderrToBinary();
/// This function executes the program using the arguments provided. The
/// invoked program will inherit the stdin, stdout, and stderr file
/// descriptors, the environment and other configuration settings of the
/// invoking program.
- /// This function waits the program to finish.
+ /// This function waits for the program to finish, so should be avoided in
+ /// library functions that aren't expected to block. Consider using
+ /// ExecuteNoWait() instead.
/// @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
diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h
index bcc561d..e97f36a 100644
--- a/include/llvm/Support/Recycler.h
+++ b/include/llvm/Support/Recycler.h
@@ -17,13 +17,12 @@
#include "llvm/ADT/ilist.h"
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
namespace llvm {
-class BumpPtrAllocator;
-
/// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for
/// printing statistics.
///
@@ -100,10 +99,10 @@ public:
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!");
+ static_assert(AlignOf<SubClass>::Alignment <= Align,
+ "Recycler allocation alignment is less than object align!");
+ static_assert(sizeof(SubClass) <= Size,
+ "Recycler allocation size is less than object size!");
return !FreeList.empty() ?
reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) :
static_cast<SubClass *>(Allocator.Allocate(Size, Align));
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 3d071be..2eea369 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -17,6 +17,7 @@
#ifndef LLVM_SUPPORT_REGEX_H
#define LLVM_SUPPORT_REGEX_H
+#include "llvm/Support/Compiler.h"
#include <string>
struct llvm_regex;
@@ -45,6 +46,17 @@ namespace llvm {
/// Compiles the given regular expression \p Regex.
Regex(StringRef Regex, unsigned Flags = NoFlags);
+ Regex(const Regex &) LLVM_DELETED_FUNCTION;
+ Regex &operator=(Regex regex) {
+ std::swap(preg, regex.preg);
+ std::swap(error, regex.error);
+ return *this;
+ }
+ Regex(Regex &&regex) {
+ preg = regex.preg;
+ error = regex.error;
+ regex.preg = NULL;
+ }
~Regex();
/// isValid - returns the error encountered during regex compilation, or
@@ -81,6 +93,9 @@ namespace llvm {
/// expression that matches Str and only Str.
static bool isLiteralERE(StringRef Str);
+ /// \brief Turn String into a regex by escaping its special characters.
+ static std::string escape(StringRef String);
+
private:
struct llvm_regex *preg;
int error;
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index e823d48..0259630 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -11,10 +11,11 @@
#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataStream.h"
#include "llvm/Support/MemoryObject.h"
+#include <cassert>
+#include <memory>
#include <vector>
namespace llvm {
@@ -38,7 +39,7 @@ class StreamableMemoryObject : public MemoryObject {
/// getBase - Returns the lowest valid address in the region.
///
/// @result - The lowest valid address.
- virtual uint64_t getBase() const LLVM_OVERRIDE = 0;
+ uint64_t getBase() const override = 0;
/// getExtent - Returns the size of the region in bytes. (The region is
/// contiguous, so the highest valid address of the region
@@ -46,7 +47,7 @@ class StreamableMemoryObject : public MemoryObject {
/// May block until all bytes in the stream have been read
///
/// @result - The size of the region.
- virtual uint64_t getExtent() const LLVM_OVERRIDE = 0;
+ uint64_t getExtent() const override = 0;
/// readByte - Tries to read a single byte from the region.
/// May block until (address - base) bytes have been read
@@ -54,7 +55,7 @@ class StreamableMemoryObject : public MemoryObject {
/// @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 LLVM_OVERRIDE = 0;
+ int readByte(uint64_t address, uint8_t *ptr) const override = 0;
/// readBytes - Tries to read a contiguous range of bytes from the
/// region, up to the end of the region.
@@ -70,9 +71,8 @@ class StreamableMemoryObject : public MemoryObject {
/// and large enough to hold size bytes.
/// @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) const LLVM_OVERRIDE = 0;
+ int readBytes(uint64_t address, uint64_t size,
+ uint8_t *buf) const override = 0;
/// getPointer - Ensures that the requested data is in memory, and returns
/// A pointer to it. More efficient than using readBytes if the
@@ -105,14 +105,12 @@ class StreamableMemoryObject : public MemoryObject {
class StreamingMemoryObject : public StreamableMemoryObject {
public:
StreamingMemoryObject(DataStreamer *streamer);
- virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
- virtual uint64_t getExtent() const LLVM_OVERRIDE;
- virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE;
- virtual int readBytes(uint64_t address,
- uint64_t size,
- uint8_t *buf) const LLVM_OVERRIDE;
- virtual const uint8_t *getPointer(uint64_t address,
- uint64_t size) const LLVM_OVERRIDE {
+ uint64_t getBase() const override { return 0; }
+ uint64_t getExtent() const override;
+ int readByte(uint64_t address, uint8_t *ptr) const override;
+ int readBytes(uint64_t address, uint64_t size,
+ uint8_t *buf) const override;
+ const uint8_t *getPointer(uint64_t address, uint64_t size) const override {
// This could be fixed by ensuring the bytes are fetched and making a copy,
// requiring that the bitcode size be known, or otherwise ensuring that
// the memory doesn't go away/get reallocated, but it's
@@ -120,8 +118,8 @@ public:
assert(0 && "getPointer in streaming memory objects not allowed");
return NULL;
}
- virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE;
- virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE;
+ bool isValidAddress(uint64_t address) const override;
+ bool isObjectEnd(uint64_t address) const override;
/// Drop s bytes from the front of the stream, pushing the positions of the
/// remaining bytes down by s. This is used to skip past the bitcode header,
@@ -137,7 +135,7 @@ public:
private:
const static uint32_t kChunkSize = 4096 * 4;
mutable std::vector<unsigned char> Bytes;
- OwningPtr<DataStreamer> Streamer;
+ std::unique_ptr<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
diff --git a/include/llvm/Support/StringRefMemoryObject.h b/include/llvm/Support/StringRefMemoryObject.h
index 994fa34..8a349ea 100644
--- a/include/llvm/Support/StringRefMemoryObject.h
+++ b/include/llvm/Support/StringRefMemoryObject.h
@@ -29,11 +29,11 @@ public:
StringRefMemoryObject(StringRef Bytes, uint64_t Base = 0)
: Bytes(Bytes), Base(Base) {}
- uint64_t getBase() const LLVM_OVERRIDE { return Base; }
- uint64_t getExtent() const LLVM_OVERRIDE { return Bytes.size(); }
+ uint64_t getBase() const override { return Base; }
+ uint64_t getExtent() const override { return Bytes.size(); }
- int readByte(uint64_t Addr, uint8_t *Byte) const LLVM_OVERRIDE;
- int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const LLVM_OVERRIDE;
+ int readByte(uint64_t Addr, uint8_t *Byte) const override;
+ int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const override;
};
}
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 9ecee3b..8e7478c 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -19,9 +19,9 @@
#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
#define LLVM_SUPPORT_TARGETREGISTRY_H
+#include "llvm-c/Disassembler.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm-c/Disassembler.h"
#include <cassert>
#include <string>
@@ -46,15 +46,12 @@ namespace llvm {
class MCRelocationInfo;
class MCTargetAsmParser;
class TargetMachine;
- class MCTargetStreamer;
class TargetOptions;
class raw_ostream;
class formatted_raw_ostream;
- MCStreamer *createAsmStreamer(MCContext &Ctx,
- MCTargetStreamer *TargetStreamer,
- formatted_raw_ostream &OS, bool isVerboseAsm,
- bool useLoc, bool useCFI,
+ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool isVerboseAsm, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
@@ -79,7 +76,7 @@ namespace llvm {
public:
friend struct TargetRegistry;
- typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
+ typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
StringRef TT);
@@ -128,12 +125,12 @@ namespace llvm {
MCAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
+ const MCSubtargetInfo &STI,
bool RelaxAll,
bool NoExecStack);
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
- bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
@@ -154,9 +151,8 @@ namespace llvm {
/// TargetRegistry.
Target *Next;
- /// TripleMatchQualityFn - The target function for rating the match quality
- /// of a triple.
- TripleMatchQualityFnTy TripleMatchQualityFn;
+ /// The target function for checking if an architecture is supported.
+ ArchMatchFnTy ArchMatchFn;
/// Name - The target name.
const char *Name;
@@ -421,11 +417,12 @@ namespace llvm {
MCAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
+ const MCSubtargetInfo &STI,
bool RelaxAll,
bool NoExecStack) const {
if (!MCObjectStreamerCtorFn)
return 0;
- return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter,
+ return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
RelaxAll, NoExecStack);
}
@@ -433,7 +430,6 @@ namespace llvm {
MCStreamer *createAsmStreamer(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
- bool useLoc,
bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
@@ -441,10 +437,10 @@ namespace llvm {
MCAsmBackend *TAB,
bool ShowInst) const {
if (AsmStreamerCtorFn)
- return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI,
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
- return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI,
+ return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
}
@@ -490,7 +486,6 @@ namespace llvm {
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 {
@@ -578,14 +573,13 @@ namespace llvm {
/// @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 ArchMatchFn - The arch match checking 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,
+ Target::ArchMatchFnTy ArchMatchFn,
bool HasJIT = false);
/// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
@@ -831,15 +825,11 @@ namespace llvm {
bool HasJIT = false>
struct RegisterTarget {
RegisterTarget(Target &T, const char *Name, const char *Desc) {
- TargetRegistry::RegisterTarget(T, Name, Desc,
- &getTripleMatchQuality,
- HasJIT);
+ TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
}
- static unsigned getTripleMatchQuality(const std::string &TT) {
- if (Triple(TT).getArch() == TargetArchType)
- return 20;
- return 0;
+ static bool getArchMatch(Triple::ArchType Arch) {
+ return Arch == TargetArchType;
}
};
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index 2785408..ee0e286 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -74,8 +74,7 @@ namespace sys {
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)
+ NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 10^7 Hz (10ns)
};
/// @}
@@ -236,15 +235,6 @@ namespace sys {
( 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_ - PosixZeroTimeSeconds;
- 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 {
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index a2191ad..88f8ccc 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -47,7 +47,7 @@ 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,
- sys::fs::OpenFlags Flags = sys::fs::F_None);
+ sys::fs::OpenFlags Flags);
tool_output_file(const char *Filename, int FD);
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
index 86faa38..734d323 100644
--- a/include/llvm/Support/UnicodeCharRanges.h
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -16,7 +16,6 @@
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/raw_ostream.h"
-
#include <algorithm>
namespace llvm {
@@ -40,7 +39,7 @@ inline bool operator<(UnicodeCharRange Range, uint32_t Value) {
/// array.
class UnicodeCharSet {
public:
- typedef llvm::ArrayRef<UnicodeCharRange> CharRanges;
+ typedef ArrayRef<UnicodeCharRange> CharRanges;
/// \brief Constructs a UnicodeCharSet instance from an array of
/// UnicodeCharRanges.
@@ -67,17 +66,17 @@ private:
for (CharRanges::const_iterator I = Ranges.begin(), E = Ranges.end();
I != E; ++I) {
if (I != Ranges.begin() && Prev >= I->Lower) {
- DEBUG(llvm::dbgs() << "Upper bound 0x");
- DEBUG(llvm::dbgs().write_hex(Prev));
- DEBUG(llvm::dbgs() << " should be less than succeeding lower bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Lower) << "\n");
+ DEBUG(dbgs() << "Upper bound 0x");
+ DEBUG(dbgs().write_hex(Prev));
+ DEBUG(dbgs() << " should be less than succeeding lower bound 0x");
+ DEBUG(dbgs().write_hex(I->Lower) << "\n");
return false;
}
if (I->Upper < I->Lower) {
- DEBUG(llvm::dbgs() << "Upper bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Lower));
- DEBUG(llvm::dbgs() << " should not be less than lower bound 0x");
- DEBUG(llvm::dbgs().write_hex(I->Upper) << "\n");
+ DEBUG(dbgs() << "Upper bound 0x");
+ DEBUG(dbgs().write_hex(I->Lower));
+ DEBUG(dbgs() << " should not be less than lower bound 0x");
+ DEBUG(dbgs().write_hex(I->Upper) << "\n");
return false;
}
Prev = I->Upper;
diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h
index 7ae40af..cebf75c 100644
--- a/include/llvm/Support/Valgrind.h
+++ b/include/llvm/Support/Valgrind.h
@@ -24,12 +24,10 @@
// 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);
+void AnnotateHappensAfter(const char *file, int line, const volatile void *cv);
+void AnnotateHappensBefore(const char *file, int line, const volatile void *cv);
+void AnnotateIgnoreWritesBegin(const char *file, int line);
+void AnnotateIgnoreWritesEnd(const char *file, int line);
}
#endif
diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h
index ecce713..7ca218e 100644
--- a/include/llvm/Support/Win64EH.h
+++ b/include/llvm/Support/Win64EH.h
@@ -108,17 +108,19 @@ struct UnwindInfo {
/// \brief Return pointer to language specific data part of UnwindInfo.
const void *getLanguageSpecificData() const {
- return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]);
+ return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
}
/// \brief Return image-relative offset of language-specific exception handler.
uint32_t getLanguageSpecificHandlerOffset() const {
- return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData());
+ return *reinterpret_cast<const support::ulittle32_t *>(
+ getLanguageSpecificData());
}
/// \brief Set image-relative offset of language-specific exception handler.
void setLanguageSpecificHandlerOffset(uint32_t offset) {
- *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset;
+ *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
+ offset;
}
/// \brief Return pointer to exception-specific data.
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 7020449..5194b52 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -38,14 +38,12 @@
#ifndef LLVM_SUPPORT_YAMLPARSER_H
#define LLVM_SUPPORT_YAMLPARSER_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 <map>
#include <limits>
+#include <map>
#include <utility>
namespace llvm {
@@ -97,8 +95,8 @@ public:
void printError(Node *N, const Twine &Msg);
private:
- OwningPtr<Scanner> scanner;
- OwningPtr<Document> CurrentDoc;
+ std::unique_ptr<Scanner> scanner;
+ std::unique_ptr<Document> CurrentDoc;
friend class Document;
};
@@ -116,7 +114,7 @@ public:
NK_Alias
};
- Node(unsigned int Type, OwningPtr<Document> &, StringRef Anchor,
+ Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor,
StringRef Tag);
/// @brief Get the value of the anchor attached to this node. If it does not
@@ -157,7 +155,7 @@ public:
}
protected:
- OwningPtr<Document> &Doc;
+ std::unique_ptr<Document> &Doc;
SMRange SourceRange;
void operator delete(void *) throw() {}
@@ -176,9 +174,9 @@ private:
/// Example:
/// !!null null
class NullNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- NullNode(OwningPtr<Document> &D)
+ NullNode(std::unique_ptr<Document> &D)
: Node(NK_Null, D, StringRef(), StringRef()) {}
static inline bool classof(const Node *N) {
@@ -192,9 +190,9 @@ public:
/// Example:
/// Adena
class ScalarNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
StringRef Val)
: Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
SMLoc Start = SMLoc::getFromPointer(Val.begin());
@@ -234,13 +232,10 @@ private:
/// Example:
/// Section: .text
class KeyValueNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- KeyValueNode(OwningPtr<Document> &D)
- : Node(NK_KeyValue, D, StringRef(), StringRef())
- , Key(0)
- , Value(0)
- {}
+ KeyValueNode(std::unique_ptr<Document> &D)
+ : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(0), Value(0) {}
/// @brief Parse and return the key.
///
@@ -256,7 +251,7 @@ public:
/// @returns The value, or nullptr if failed() == true.
Node *getValue();
- virtual void skip() LLVM_OVERRIDE {
+ void skip() override {
getKey()->skip();
getValue()->skip();
}
@@ -346,7 +341,7 @@ void skip(CollectionType &C) {
/// Name: _main
/// Scope: Global
class MappingNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
enum MappingType {
MT_Block,
@@ -354,7 +349,7 @@ public:
MT_Inline ///< An inline mapping node is used for "[key: value]".
};
- MappingNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
MappingType MT)
: Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
IsAtEnd(false), CurrentEntry(0) {}
@@ -370,7 +365,7 @@ public:
iterator end() { return iterator(); }
- virtual void skip() LLVM_OVERRIDE {
+ void skip() override {
yaml::skip(*this);
}
@@ -396,7 +391,7 @@ private:
/// - Hello
/// - World
class SequenceNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
enum SequenceType {
ST_Block,
@@ -411,7 +406,7 @@ public:
ST_Indentless
};
- SequenceNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
+ SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
SequenceType ST)
: Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
IsAtEnd(false),
@@ -431,7 +426,7 @@ public:
iterator end() { return iterator(); }
- virtual void skip() LLVM_OVERRIDE {
+ void skip() override {
yaml::skip(*this);
}
@@ -452,10 +447,10 @@ private:
/// Example:
/// *AnchorName
class AliasNode : public Node {
- virtual void anchor();
+ void anchor() override;
public:
- AliasNode(OwningPtr<Document> &D, StringRef Val)
- : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
+ AliasNode(std::unique_ptr<Document> &D, StringRef Val)
+ : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
StringRef getName() const { return Name; }
Node *getTarget();
@@ -532,7 +527,7 @@ private:
class document_iterator {
public:
document_iterator() : Doc(0) {}
- document_iterator(OwningPtr<Document> &D) : Doc(&D) {}
+ document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
bool operator ==(const document_iterator &Other) {
if (isAtEnd() || Other.isAtEnd())
@@ -559,16 +554,14 @@ public:
return *Doc->get();
}
- OwningPtr<Document> &operator ->() {
- return *Doc;
- }
+ std::unique_ptr<Document> &operator->() { return *Doc; }
private:
bool isAtEnd() const {
return !Doc || !*Doc;
}
- OwningPtr<Document> *Doc;
+ std::unique_ptr<Document> *Doc;
};
}
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index c19eb23..ea217c3 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -1,4 +1,4 @@
-//===- llvm/Supporrt/YAMLTraits.h -------------------------------*- C++ -*-===//
+//===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -13,19 +13,17 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Support/type_traits.h"
-
namespace llvm {
namespace yaml {
@@ -45,6 +43,8 @@ template<class T>
struct MappingTraits {
// Must provide:
// static void mapping(IO &io, T &fields);
+ // Optionally may provide:
+ // static StringRef validate(IO &io, T &fields);
};
@@ -227,6 +227,23 @@ public:
static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
};
+// Test if MappingTraits<T>::validate() is defined on type T.
+template <class T>
+struct has_MappingValidateTraits
+{
+ typedef StringRef (*Signature_validate)(class IO&, T&);
+
+ template <typename U>
+ static char test(SameType<Signature_validate, &U::validate>*);
+
+ template <typename U>
+ static double test(...);
+
+public:
+ static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
+};
+
+
// Test if SequenceTraits<T> is defined on type T.
template <class T>
@@ -248,7 +265,7 @@ public:
// has_FlowTraits<int> will cause an error with some compilers because
// it subclasses int. Using this wrapper only instantiates the
// real has_FlowTraits only if the template type is a class.
-template <typename T, bool Enabled = llvm::is_class<T>::value>
+template <typename T, bool Enabled = std::is_class<T>::value>
class has_FlowTraits
{
public:
@@ -278,7 +295,7 @@ public:
// Test if SequenceTraits<T> is defined on type T
template<typename T>
-struct has_SequenceTraits : public llvm::integral_constant<bool,
+struct has_SequenceTraits : public std::integral_constant<bool,
has_SequenceMethodTraits<T>::value > { };
@@ -302,7 +319,7 @@ public:
template<typename T>
-struct missingTraits : public llvm::integral_constant<bool,
+struct missingTraits : public std::integral_constant<bool,
!has_ScalarEnumerationTraits<T>::value
&& !has_ScalarBitSetTraits<T>::value
&& !has_ScalarTraits<T>::value
@@ -310,7 +327,15 @@ struct missingTraits : public llvm::integral_constant<bool,
&& !has_SequenceTraits<T>::value
&& !has_DocumentListTraits<T>::value > {};
+template<typename T>
+struct validatedMappingTraits : public std::integral_constant<bool,
+ has_MappingTraits<T>::value
+ && has_MappingValidateTraits<T>::value> {};
+template<typename T>
+struct unvalidatedMappingTraits : public std::integral_constant<bool,
+ has_MappingTraits<T>::value
+ && !has_MappingValidateTraits<T>::value> {};
// Base class for Input and Output.
class IO {
public:
@@ -318,7 +343,7 @@ public:
IO(void *Ctxt=NULL);
virtual ~IO();
- virtual bool outputting() const = 0;
+ virtual bool outputting() = 0;
virtual unsigned beginSequence() = 0;
virtual bool preflightElement(unsigned, void *&) = 0;
@@ -388,7 +413,7 @@ public:
}
template <typename T>
- typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+ typename std::enable_if<has_SequenceTraits<T>::value,void>::type
mapOptional(const char* Key, T& Val) {
// omit key/value instead of outputting empty sequence
if ( this->canElideEmptySequence() && !(Val.begin() != Val.end()) )
@@ -397,7 +422,12 @@ public:
}
template <typename T>
- typename llvm::enable_if_c<!has_SequenceTraits<T>::value,void>::type
+ void mapOptional(const char* Key, Optional<T> &Val) {
+ processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false);
+ }
+
+ template <typename T>
+ typename std::enable_if<!has_SequenceTraits<T>::value,void>::type
mapOptional(const char* Key, T& Val) {
this->processKey(Key, Val, false);
}
@@ -409,6 +439,26 @@ public:
private:
template <typename T>
+ void processKeyWithDefault(const char *Key, Optional<T> &Val,
+ const Optional<T> &DefaultValue, bool Required) {
+ assert(DefaultValue.hasValue() == false &&
+ "Optional<T> shouldn't have a value!");
+ void *SaveInfo;
+ bool UseDefault;
+ const bool sameAsDefault = outputting() && !Val.hasValue();
+ if (!outputting() && !Val.hasValue())
+ Val = T();
+ if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
+ SaveInfo)) {
+ yamlize(*this, Val.getValue(), Required);
+ this->postflightKey(SaveInfo);
+ } else {
+ if (UseDefault)
+ Val = DefaultValue;
+ }
+ }
+
+ template <typename T>
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
bool Required) {
void *SaveInfo;
@@ -442,7 +492,7 @@ private:
template<typename T>
-typename llvm::enable_if_c<has_ScalarEnumerationTraits<T>::value,void>::type
+typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type
yamlize(IO &io, T &Val, bool) {
io.beginEnumScalar();
ScalarEnumerationTraits<T>::enumeration(io, Val);
@@ -450,7 +500,7 @@ yamlize(IO &io, T &Val, bool) {
}
template<typename T>
-typename llvm::enable_if_c<has_ScalarBitSetTraits<T>::value,void>::type
+typename std::enable_if<has_ScalarBitSetTraits<T>::value,void>::type
yamlize(IO &io, T &Val, bool) {
bool DoClear;
if ( io.beginBitSetScalar(DoClear) ) {
@@ -463,7 +513,7 @@ yamlize(IO &io, T &Val, bool) {
template<typename T>
-typename llvm::enable_if_c<has_ScalarTraits<T>::value,void>::type
+typename std::enable_if<has_ScalarTraits<T>::value,void>::type
yamlize(IO &io, T &Val, bool) {
if ( io.outputting() ) {
std::string Storage;
@@ -484,21 +534,41 @@ yamlize(IO &io, T &Val, bool) {
template<typename T>
-typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type
+typename std::enable_if<validatedMappingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
io.beginMapping();
+ if (io.outputting()) {
+ StringRef Err = MappingTraits<T>::validate(io, Val);
+ if (!Err.empty()) {
+ llvm::errs() << Err << "\n";
+ assert(Err.empty() && "invalid struct trying to be written as yaml");
+ }
+ }
MappingTraits<T>::mapping(io, Val);
+ if (!io.outputting()) {
+ StringRef Err = MappingTraits<T>::validate(io, Val);
+ if (!Err.empty())
+ io.setError(Err);
+ }
io.endMapping();
}
template<typename T>
-typename llvm::enable_if_c<missingTraits<T>::value, void>::type
+typename std::enable_if<unvalidatedMappingTraits<T>::value, void>::type
+yamlize(IO &io, T &Val, bool) {
+ io.beginMapping();
+ MappingTraits<T>::mapping(io, Val);
+ io.endMapping();
+}
+
+template<typename T>
+typename std::enable_if<missingTraits<T>::value, void>::type
yamlize(IO &io, T &Val, bool) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
}
template<typename T>
-typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type
+typename std::enable_if<has_SequenceTraits<T>::value,void>::type
yamlize(IO &io, T &Seq, bool) {
if ( has_FlowTraits< SequenceTraits<T> >::value ) {
unsigned incnt = io.beginFlowSequence();
@@ -538,6 +608,12 @@ struct ScalarTraits<StringRef> {
static void output(const StringRef &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, StringRef &);
};
+
+template<>
+struct ScalarTraits<std::string> {
+ static void output(const std::string &, void*, llvm::raw_ostream &);
+ static StringRef input(StringRef, void*, std::string &);
+};
template<>
struct ScalarTraits<uint8_t> {
@@ -697,32 +773,30 @@ public:
// Check if there was an syntax or semantic error during parsing.
llvm::error_code error();
- static bool classof(const IO *io) { return !io->outputting(); }
-
private:
- virtual bool outputting() const;
- virtual bool mapTag(StringRef, bool);
- virtual void beginMapping();
- virtual void endMapping();
- virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
- virtual void postflightKey(void *);
- virtual unsigned beginSequence();
- virtual void endSequence();
- virtual bool preflightElement(unsigned index, void *&);
- virtual void postflightElement(void *);
- virtual unsigned beginFlowSequence();
- virtual bool preflightFlowElement(unsigned , void *&);
- virtual void postflightFlowElement(void *);
- virtual void endFlowSequence();
- virtual void beginEnumScalar();
- virtual bool matchEnumScalar(const char*, bool);
- virtual void endEnumScalar();
- virtual bool beginBitSetScalar(bool &);
- virtual bool bitSetMatch(const char *, bool );
- virtual void endBitSetScalar();
- virtual void scalarString(StringRef &);
- virtual void setError(const Twine &message);
- virtual bool canElideEmptySequence();
+ bool outputting() override;
+ bool mapTag(StringRef, bool) override;
+ void beginMapping() override;
+ void endMapping() override;
+ bool preflightKey(const char *, bool, bool, bool &, void *&) override;
+ void postflightKey(void *) override;
+ unsigned beginSequence() override;
+ void endSequence() override;
+ bool preflightElement(unsigned index, void *&) override;
+ void postflightElement(void *) override;
+ unsigned beginFlowSequence() override;
+ bool preflightFlowElement(unsigned , void *&) override;
+ void postflightFlowElement(void *) override;
+ void endFlowSequence() override;
+ void beginEnumScalar() override;
+ bool matchEnumScalar(const char*, bool) override;
+ void endEnumScalar() override;
+ bool beginBitSetScalar(bool &) override;
+ bool bitSetMatch(const char *, bool ) override;
+ void endBitSetScalar() override;
+ void scalarString(StringRef &) override;
+ void setError(const Twine &message) override;
+ bool canElideEmptySequence() override;
class HNode {
virtual void anchor();
@@ -735,7 +809,7 @@ private:
};
class EmptyHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
EmptyHNode(Node *n) : HNode(n) { }
static inline bool classof(const HNode *n) {
@@ -745,7 +819,7 @@ private:
};
class ScalarHNode : public HNode {
- virtual void anchor();
+ void anchor() override;
public:
ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
@@ -802,15 +876,15 @@ public:
void nextDocument();
private:
- llvm::SourceMgr SrcMgr; // must be before Strm
- OwningPtr<llvm::yaml::Stream> Strm;
- OwningPtr<HNode> TopNode;
- llvm::error_code EC;
- llvm::BumpPtrAllocator StringAllocator;
- llvm::yaml::document_iterator DocIterator;
- std::vector<bool> BitValuesUsed;
- HNode *CurrentNode;
- bool ScalarMatchFound;
+ llvm::SourceMgr SrcMgr; // must be before Strm
+ std::unique_ptr<llvm::yaml::Stream> Strm;
+ std::unique_ptr<HNode> TopNode;
+ llvm::error_code EC;
+ llvm::BumpPtrAllocator StringAllocator;
+ llvm::yaml::document_iterator DocIterator;
+ std::vector<bool> BitValuesUsed;
+ HNode *CurrentNode;
+ bool ScalarMatchFound;
};
@@ -825,31 +899,29 @@ public:
Output(llvm::raw_ostream &, void *Ctxt=NULL);
virtual ~Output();
- static bool classof(const IO *io) { return io->outputting(); }
-
- virtual bool outputting() const;
- virtual bool mapTag(StringRef, bool);
- virtual void beginMapping();
- virtual void endMapping();
- virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
- virtual void postflightKey(void *);
- virtual unsigned beginSequence();
- virtual void endSequence();
- virtual bool preflightElement(unsigned, void *&);
- virtual void postflightElement(void *);
- virtual unsigned beginFlowSequence();
- virtual bool preflightFlowElement(unsigned, void *&);
- virtual void postflightFlowElement(void *);
- virtual void endFlowSequence();
- virtual void beginEnumScalar();
- virtual bool matchEnumScalar(const char*, bool);
- virtual void endEnumScalar();
- virtual bool beginBitSetScalar(bool &);
- virtual bool bitSetMatch(const char *, bool );
- virtual void endBitSetScalar();
- virtual void scalarString(StringRef &);
- virtual void setError(const Twine &message);
- virtual bool canElideEmptySequence();
+ bool outputting() override;
+ bool mapTag(StringRef, bool) override;
+ void beginMapping() override;
+ void endMapping() override;
+ bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
+ void postflightKey(void *) override;
+ unsigned beginSequence() override;
+ void endSequence() override;
+ bool preflightElement(unsigned, void *&) override;
+ void postflightElement(void *) override;
+ unsigned beginFlowSequence() override;
+ bool preflightFlowElement(unsigned, void *&) override;
+ void postflightFlowElement(void *) override;
+ void endFlowSequence() override;
+ void beginEnumScalar() override;
+ bool matchEnumScalar(const char*, bool) override;
+ void endEnumScalar() override;
+ bool beginBitSetScalar(bool &) override;
+ bool bitSetMatch(const char *, bool ) override;
+ void endBitSetScalar() override;
+ void scalarString(StringRef &) override;
+ void setError(const Twine &message) override;
+ bool canElideEmptySequence() override;
public:
// These are only used by operator<<. They could be private
// if that templated operator could be made a friend.
@@ -942,7 +1014,7 @@ struct ScalarTraits<Hex64> {
// Define non-member operator>> so that Input can stream in a document list.
template <typename T>
inline
-typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Input &>::type
+typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docList) {
int i = 0;
while ( yin.setCurrentDocument() ) {
@@ -958,7 +1030,7 @@ operator>>(Input &yin, T &docList) {
// Define non-member operator>> so that Input can stream in a map as a document.
template <typename T>
inline
-typename llvm::enable_if_c<has_MappingTraits<T>::value,Input &>::type
+typename std::enable_if<has_MappingTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docMap) {
yin.setCurrentDocument();
yamlize(yin, docMap, true);
@@ -969,7 +1041,7 @@ operator>>(Input &yin, T &docMap) {
// a document.
template <typename T>
inline
-typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type
+typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docSeq) {
if (yin.setCurrentDocument())
yamlize(yin, docSeq, true);
@@ -979,7 +1051,7 @@ operator>>(Input &yin, T &docSeq) {
// Provide better error message about types missing a trait specialization
template <typename T>
inline
-typename llvm::enable_if_c<missingTraits<T>::value,Input &>::type
+typename std::enable_if<missingTraits<T>::value, Input &>::type
operator>>(Input &yin, T &docSeq) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
return yin;
@@ -989,7 +1061,7 @@ operator>>(Input &yin, T &docSeq) {
// Define non-member operator<< so that Output can stream out document list.
template <typename T>
inline
-typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Output &>::type
+typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
operator<<(Output &yout, T &docList) {
yout.beginDocuments();
const size_t count = DocumentListTraits<T>::size(yout, docList);
@@ -1006,7 +1078,7 @@ operator<<(Output &yout, T &docList) {
// Define non-member operator<< so that Output can stream out a map.
template <typename T>
inline
-typename llvm::enable_if_c<has_MappingTraits<T>::value,Output &>::type
+typename std::enable_if<has_MappingTraits<T>::value, Output &>::type
operator<<(Output &yout, T &map) {
yout.beginDocuments();
if ( yout.preflightDocument(0) ) {
@@ -1020,7 +1092,7 @@ operator<<(Output &yout, T &map) {
// Define non-member operator<< so that Output can stream out a sequence.
template <typename T>
inline
-typename llvm::enable_if_c<has_SequenceTraits<T>::value,Output &>::type
+typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
operator<<(Output &yout, T &seq) {
yout.beginDocuments();
if ( yout.preflightDocument(0) ) {
@@ -1034,7 +1106,7 @@ operator<<(Output &yout, T &seq) {
// Provide better error message about types missing a trait specialization
template <typename T>
inline
-typename llvm::enable_if_c<missingTraits<T>::value,Output &>::type
+typename std::enable_if<missingTraits<T>::value, Output &>::type
operator<<(Output &yout, T &seq) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
return yout;
@@ -1075,6 +1147,7 @@ operator<<(Output &yout, T &seq) {
return seq.size(); \
} \
static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
+ (void)flow; /* Remove this workaround after PR17897 is fixed */ \
if ( index >= seq.size() ) \
seq.resize(index+1); \
return seq[index]; \
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index 9000306..3114199 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -81,12 +81,12 @@ namespace llvm
Filled = false;
}
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream,
/// not counting the bytes currently in the buffer.
///
- virtual uint64_t current_pos() const LLVM_OVERRIDE {
+ uint64_t current_pos() const override {
// This has the same effect as calling TheStream.current_pos(),
// but that interface is private.
return TheStream->tell() - TheStream->GetNumBytesInBuffer();
diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h
index 4385721..04cf3b6 100644
--- a/include/llvm/Support/raw_os_ostream.h
+++ b/include/llvm/Support/raw_os_ostream.h
@@ -26,11 +26,11 @@ 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) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE;
+ uint64_t current_pos() const override;
public:
raw_os_ostream(std::ostream &O) : OS(O) {}
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index ec7e06b..0240035 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -322,14 +322,14 @@ class raw_fd_ostream : public raw_ostream {
uint64_t pos;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE { return pos; }
+ uint64_t current_pos() const override { return pos; }
/// preferred_buffer_size - Determine an efficient buffer size.
- virtual size_t preferred_buffer_size() const LLVM_OVERRIDE;
+ size_t preferred_buffer_size() const override;
/// error_detected - Set the flag indicating that an output error has
/// been encountered.
@@ -347,7 +347,7 @@ public:
/// file descriptor when it is done (this is necessary to detect
/// output errors).
raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
- sys::fs::OpenFlags Flags = sys::fs::F_None);
+ sys::fs::OpenFlags Flags);
/// 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.
@@ -373,15 +373,15 @@ public:
UseAtomicWrites = Value;
}
- virtual raw_ostream &changeColor(enum Colors colors, bool bold=false,
- bool bg=false) LLVM_OVERRIDE;
- virtual raw_ostream &resetColor() LLVM_OVERRIDE;
+ raw_ostream &changeColor(enum Colors colors, bool bold=false,
+ bool bg=false) override;
+ raw_ostream &resetColor() override;
- virtual raw_ostream &reverseColor() LLVM_OVERRIDE;
+ raw_ostream &reverseColor() override;
- virtual bool is_displayed() const LLVM_OVERRIDE;
+ bool is_displayed() const override;
- virtual bool has_colors() const LLVM_OVERRIDE;
+ bool has_colors() const override;
/// has_error - Return the value of the flag in this raw_fd_ostream indicating
/// whether an output error has been encountered.
@@ -427,11 +427,11 @@ class raw_string_ostream : public raw_ostream {
std::string &OS;
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE { return OS.size(); }
+ uint64_t current_pos() const override { return OS.size(); }
public:
explicit raw_string_ostream(std::string &O) : OS(O) {}
~raw_string_ostream();
@@ -451,11 +451,11 @@ 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) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE;
+ uint64_t current_pos() const override;
public:
/// Construct a new raw_svector_ostream.
///
@@ -477,11 +477,11 @@ public:
/// raw_null_ostream - A raw_ostream that discards all output.
class raw_null_ostream : public raw_ostream {
/// write_impl - See raw_ostream::write_impl.
- virtual void write_impl(const char *Ptr, size_t size) LLVM_OVERRIDE;
+ void write_impl(const char *Ptr, size_t size) override;
/// current_pos - Return the current position within the stream, not
/// counting the bytes currently in the buffer.
- virtual uint64_t current_pos() const LLVM_OVERRIDE;
+ uint64_t current_pos() const override;
public:
explicit raw_null_ostream() {}
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index 43dace6..4ca4b06 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -48,10 +48,10 @@ const error_category& generic_category();
const error_category& system_category();
template <class T> struct is_error_code_enum
- : public false_type {};
+ : public std::false_type {};
template <class T> struct is_error_condition_enum
- : public false_type {};
+ : public std::false_type {};
class error_code
{
@@ -203,7 +203,7 @@ enum class errc
wrong_protocol_type // EPROTOTYPE
};
-template <> struct is_error_condition_enum<errc> : true_type { }
+template <> struct is_error_condition_enum<errc> : std::true_type { }
error_code make_error_code(errc e);
error_condition make_error_condition(errc e);
@@ -225,7 +225,6 @@ template <> struct hash<std::error_code>;
*/
#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/type_traits.h"
#include <cerrno>
#include <string>
@@ -474,11 +473,11 @@ namespace llvm {
// is_error_code_enum
-template <class Tp> struct is_error_code_enum : public false_type {};
+template <class Tp> struct is_error_code_enum : public std::false_type {};
// is_error_condition_enum
-template <class Tp> struct is_error_condition_enum : public false_type {};
+template <class Tp> struct is_error_condition_enum : public std::false_type {};
// Some error codes are not present on all platforms, so we provide equivalents
// for them:
@@ -613,9 +612,9 @@ enum _ {
operator int() const {return v_;}
};
-template <> struct is_error_condition_enum<errc> : true_type { };
+template <> struct is_error_condition_enum<errc> : std::true_type { };
-template <> struct is_error_condition_enum<errc::_> : true_type { };
+template <> struct is_error_condition_enum<errc::_> : std::true_type { };
class error_condition;
class error_code;
@@ -629,8 +628,8 @@ class error_category
public:
virtual ~error_category();
-private:
error_category();
+private:
error_category(const error_category&) LLVM_DELETED_FUNCTION;
error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION;
@@ -653,7 +652,7 @@ public:
class _do_message : public error_category
{
public:
- virtual std::string message(int ev) const LLVM_OVERRIDE;
+ std::string message(int ev) const override;
};
const error_category& generic_category();
@@ -675,7 +674,7 @@ public:
: _val_(_val), _cat_(&_cat) {}
template <class E>
- error_condition(E _e, typename enable_if_c<
+ error_condition(E _e, typename std::enable_if<
is_error_condition_enum<E>::value
>::type* = 0)
{*this = make_error_condition(_e);}
@@ -686,13 +685,12 @@ public:
}
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;}
+ typename std::enable_if<is_error_condition_enum<E>::value,
+ error_condition &>::type
+ operator=(E _e) {
+ *this = make_error_condition(_e);
+ return *this;
+ }
void clear() {
_val_ = 0;
@@ -737,7 +735,7 @@ public:
: _val_(_val), _cat_(&_cat) {}
template <class E>
- error_code(E _e, typename enable_if_c<
+ error_code(E _e, typename std::enable_if<
is_error_code_enum<E>::value
>::type* = 0) {
*this = make_error_code(_e);
@@ -749,13 +747,11 @@ public:
}
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;}
+ typename std::enable_if<is_error_code_enum<E>::value, error_code &>::type
+ operator=(E _e) {
+ *this = make_error_code(_e);
+ return *this;
+ }
void clear() {
_val_ = 0;
@@ -892,9 +888,9 @@ enum _ {
};
-template <> struct is_error_code_enum<windows_error> : true_type { };
+template <> struct is_error_code_enum<windows_error> : std::true_type { };
-template <> struct is_error_code_enum<windows_error::_> : true_type { };
+template <> struct is_error_code_enum<windows_error::_> : std::true_type { };
inline error_code make_error_code(windows_error e) {
return error_code(static_cast<int>(e), system_category());
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index 906e97c..70953a9 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -7,18 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
-// 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.
+// This file provides useful additions to the standard type_traits library.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
#define LLVM_SUPPORT_TYPE_TRAITS_H
-#include "llvm/Support/DataTypes.h"
-#include <cstddef>
+#include <type_traits>
#include <utility>
#ifndef __has_feature
@@ -26,40 +22,8 @@
#define __has_feature(x) 0
#endif
-// 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:
- static const bool 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>
@@ -71,7 +35,7 @@ struct isPodLike {
#else
// 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;
+ static const bool value = !std::is_class<T>::value;
#endif
};
@@ -80,161 +44,45 @@ 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 wheather the given type is a reference.
-template <typename T> struct is_reference : false_type {};
-template <typename T> struct is_reference<T&> : 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.
+/// Note that this accepts potentially more integral types than 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;
+ typedef typename std::remove_reference<T>::type UnderlyingT;
public:
- static const bool
- value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value &&
- !is_same<UnderlyingT, float>::value &&
- !is_same<UnderlyingT, double>::value &&
- sizeof(char) != sizeof(check_int_convertible(nonce_instance)));
-};
-
-// 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));
+ static const bool value =
+ !std::is_class<UnderlyingT>::value && // Filter conversion operators.
+ !std::is_pointer<UnderlyingT>::value &&
+ !std::is_floating_point<UnderlyingT>::value &&
+ std::is_convertible<UnderlyingT, unsigned long long>::value;
};
-// 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; };
-
-// If T is a pointer, just return it. If it is not, return T&.
+/// \brief If T is a pointer, just return it. If it is not, return T&.
template<typename T, typename Enable = void>
struct add_lvalue_reference_if_not_pointer { typedef T &type; };
-template<typename T>
-struct add_lvalue_reference_if_not_pointer<T,
- typename enable_if<is_pointer<T> >::type> {
+template <typename T>
+struct add_lvalue_reference_if_not_pointer<
+ T, typename std::enable_if<std::is_pointer<T>::value>::type> {
typedef T type;
};
-// If T is a pointer to X, return a pointer to const X. If it is not, return
-// const T.
+/// \brief If T is a pointer to X, return a pointer to const X. If it is not,
+/// return const T.
template<typename T, typename Enable = void>
struct add_const_past_pointer { typedef const T type; };
-template<typename T>
-struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> {
- typedef const typename remove_pointer<T>::type *type;
+template <typename T>
+struct add_const_past_pointer<
+ T, typename std::enable_if<std::is_pointer<T>::value>::type> {
+ typedef const typename std::remove_pointer<T>::type *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; };
-
}
#ifdef LLVM_DEFINED_HAS_FEATURE
diff --git a/include/llvm/TableGen/Error.h b/include/llvm/TableGen/Error.h
index 2d0a2b4..17ac418 100644
--- a/include/llvm/TableGen/Error.h
+++ b/include/llvm/TableGen/Error.h
@@ -27,9 +27,9 @@ void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
void PrintError(const char *Loc, const Twine &Msg);
void PrintError(const Twine &Msg);
-LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const std::string &Msg);
+LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Twine &Msg);
LLVM_ATTRIBUTE_NORETURN void PrintFatalError(ArrayRef<SMLoc> ErrorLoc,
- const std::string &Msg);
+ const Twine &Msg);
extern SourceMgr SrcMgr;
extern unsigned ErrorsPrinted;
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 50352bd..2bed006 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -150,28 +150,28 @@ 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);}
-
- virtual std::string getAsString() const { return "bit"; }
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+ Init *convertValue( BitInit *BI) override { return (Init*)BI; }
+ Init *convertValue( BitsInit *BI) override;
+ Init *convertValue( IntInit *II) override;
+ Init *convertValue(StringInit *SI) override { return 0; }
+ Init *convertValue( ListInit *LI) override { return 0; }
+ Init *convertValue(VarBitInit *VB) override { return (Init*)VB; }
+ Init *convertValue( DefInit *DI) override { return 0; }
+ Init *convertValue( DagInit *DI) override { return 0; }
+ Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+ Init *convertValue( TypedInit *TI) override;
+ Init *convertValue( VarInit *VI) override { return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override { return "bit"; }
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const RecTy*) const;
+ bool baseClassOf(const RecTy*) const override;
};
@@ -189,28 +189,28 @@ public:
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);}
-
- virtual std::string getAsString() const;
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override;
+ Init *convertValue( BitInit *UI) override;
+ Init *convertValue( BitsInit *BI) override;
+ Init *convertValue( IntInit *II) override;
+ Init *convertValue(StringInit *SI) override { return 0; }
+ Init *convertValue( ListInit *LI) override { return 0; }
+ Init *convertValue(VarBitInit *VB) override { return 0; }
+ Init *convertValue( DefInit *DI) override { return 0; }
+ Init *convertValue( DagInit *DI) override { return 0; }
+ Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+ Init *convertValue( TypedInit *TI) override;
+ Init *convertValue( VarInit *VI) override{ return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override{ return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override;
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override{
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const RecTy*) const;
+ bool baseClassOf(const RecTy*) const override;
};
@@ -226,29 +226,29 @@ 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);}
-
- virtual std::string getAsString() const { return "int"; }
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+ Init *convertValue( BitInit *BI) override;
+ Init *convertValue( BitsInit *BI) override;
+ Init *convertValue( IntInit *II) override { return (Init*)II; }
+ Init *convertValue(StringInit *SI) override { return 0; }
+ Init *convertValue( ListInit *LI) override { return 0; }
+ Init *convertValue(VarBitInit *VB) override { return 0; }
+ Init *convertValue( DefInit *DI) override { return 0; }
+ Init *convertValue( DagInit *DI) override { return 0; }
+ Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+ Init *convertValue( TypedInit *TI) override;
+ Init *convertValue( VarInit *VI) override { return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override { return "int"; }
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const RecTy*) const;
+ bool baseClassOf(const RecTy*) const override;
};
/// StringRecTy - 'string' - Represent an string value
@@ -263,26 +263,26 @@ 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);}
-
- virtual std::string getAsString() const { return "string"; }
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+ Init *convertValue( BitInit *BI) override { return 0; }
+ Init *convertValue( BitsInit *BI) override { return 0; }
+ Init *convertValue( IntInit *II) override { return 0; }
+ Init *convertValue(StringInit *SI) override { return (Init*)SI; }
+ Init *convertValue( ListInit *LI) override { return 0; }
+ Init *convertValue( UnOpInit *BO) override;
+ Init *convertValue( BinOpInit *BO) override;
+ Init *convertValue( TernOpInit *BO) override {return RecTy::convertValue(BO);}
+
+ Init *convertValue(VarBitInit *VB) override { return 0; }
+ Init *convertValue( DefInit *DI) override { return 0; }
+ Init *convertValue( DagInit *DI) override { return 0; }
+ Init *convertValue( TypedInit *TI) override;
+ Init *convertValue( VarInit *VI) override { return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override { return "string"; }
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override {
return RHS->baseClassOf(this);
}
};
@@ -302,29 +302,29 @@ 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);}
-
- virtual std::string getAsString() const;
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+ Init *convertValue( BitInit *BI) override { return 0; }
+ Init *convertValue( BitsInit *BI) override { return 0; }
+ Init *convertValue( IntInit *II) override { return 0; }
+ Init *convertValue(StringInit *SI) override { return 0; }
+ Init *convertValue( ListInit *LI) override;
+ Init *convertValue(VarBitInit *VB) override { return 0; }
+ Init *convertValue( DefInit *DI) override { return 0; }
+ Init *convertValue( DagInit *DI) override { return 0; }
+ Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( TernOpInit *UI) override{ return RecTy::convertValue(UI);}
+ Init *convertValue( TypedInit *TI) override;
+ Init *convertValue( VarInit *VI) override { return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override;
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override{
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const RecTy*) const;
+ bool baseClassOf(const RecTy*) const override;
};
/// DagRecTy - 'dag' - Represent a dag fragment
@@ -339,25 +339,25 @@ 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);}
-
- virtual std::string getAsString() const { return "dag"; }
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+ Init *convertValue( BitInit *BI) override { return 0; }
+ Init *convertValue( BitsInit *BI) override { return 0; }
+ Init *convertValue( IntInit *II) override { return 0; }
+ Init *convertValue(StringInit *SI) override { return 0; }
+ Init *convertValue( ListInit *LI) override { return 0; }
+ Init *convertValue(VarBitInit *VB) override { return 0; }
+ Init *convertValue( DefInit *DI) override { return 0; }
+ Init *convertValue( UnOpInit *BO) override;
+ Init *convertValue( BinOpInit *BO) override;
+ Init *convertValue( TernOpInit *BO) override {return RecTy::convertValue(BO);}
+ Init *convertValue( DagInit *CI) override { return (Init*)CI; }
+ Init *convertValue( TypedInit *TI) override;
+ Init *convertValue( VarInit *VI) override { return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override { return "dag"; }
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override{
return RHS->baseClassOf(this);
}
};
@@ -379,28 +379,28 @@ public:
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);}
-
- virtual std::string getAsString() const;
-
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
+ Init *convertValue( UnsetInit *UI) override { return (Init*)UI; }
+ Init *convertValue( BitInit *BI) override { return 0; }
+ Init *convertValue( BitsInit *BI) override { return 0; }
+ Init *convertValue( IntInit *II) override { return 0; }
+ Init *convertValue(StringInit *SI) override { return 0; }
+ Init *convertValue( ListInit *LI) override { return 0; }
+ Init *convertValue(VarBitInit *VB) override { return 0; }
+ Init *convertValue( UnOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( BinOpInit *UI) override { return RecTy::convertValue(UI);}
+ Init *convertValue( TernOpInit *UI) override {return RecTy::convertValue(UI);}
+ Init *convertValue( DefInit *DI) override;
+ Init *convertValue( DagInit *DI) override { return 0; }
+ Init *convertValue( TypedInit *VI) override;
+ Init *convertValue( VarInit *VI) override { return RecTy::convertValue(VI);}
+ Init *convertValue( FieldInit *FI) override { return RecTy::convertValue(FI);}
+
+ std::string getAsString() const override;
+
+ bool typeIsConvertibleTo(const RecTy *RHS) const override {
return RHS->baseClassOf(this);
}
- virtual bool baseClassOf(const RecTy*) const;
+ bool baseClassOf(const RecTy*) const override;
};
/// resolveTypes - Find a common type that T1 and T2 convert to.
@@ -569,16 +569,16 @@ public:
}
RecTy *getType() const { return Ty; }
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
- virtual Init *
- convertInitListSlice(const std::vector<unsigned> &Elements) const;
+ Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
+ Init *
+ convertInitListSlice(const std::vector<unsigned> &Elements) const override;
/// 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;
+ RecTy *getFieldType(const std::string &FieldName) const override;
/// resolveListElementReference - This method is used to implement
/// VarListElementInit::resolveReferences. If the list element is resolvable
@@ -594,7 +594,7 @@ class UnsetInit : public Init {
UnsetInit() : Init(IK_UnsetInit) {}
UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION;
UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION;
- virtual void anchor();
+ void anchor() override;
public:
static bool classof(const Init *I) {
@@ -602,16 +602,16 @@ public:
}
static UnsetInit *get();
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<UnsetInit *>(this));
}
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
return const_cast<UnsetInit*>(this);
}
- virtual bool isComplete() const { return false; }
- virtual std::string getAsString() const { return "?"; }
+ bool isComplete() const override { return false; }
+ std::string getAsString() const override { return "?"; }
};
@@ -623,7 +623,7 @@ class BitInit : public Init {
explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION;
BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION;
- virtual void anchor();
+ void anchor() override;
public:
static bool classof(const Init *I) {
@@ -633,16 +633,16 @@ public:
bool getValue() const { return Value; }
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<BitInit *>(this));
}
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
assert(Bit < 1 && "Bit index out of range!");
return const_cast<BitInit*>(this);
}
- virtual std::string getAsString() const { return Value ? "1" : "0"; }
+ std::string getAsString() const override { return Value ? "1" : "0"; }
};
/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
@@ -667,13 +667,13 @@ public:
unsigned getNumBits() const { return Bits.size(); }
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<BitsInit *>(this));
}
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
+ Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
- virtual bool isComplete() const {
+ bool isComplete() const override {
for (unsigned i = 0; i != getNumBits(); ++i)
if (!getBit(i)->isComplete()) return false;
return true;
@@ -683,11 +683,11 @@ public:
if (getBit(i)->isComplete()) return false;
return true;
}
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
assert(Bit < Bits.size() && "Bit index out of range!");
return Bits[Bit];
}
@@ -713,23 +713,23 @@ public:
int64_t getValue() const { return Value; }
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<IntInit *>(this));
}
- virtual Init *
- convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
+ Init *
+ convertInitializerBitRange(const std::vector<unsigned> &Bits) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
/// 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 {
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override {
llvm_unreachable("Illegal element reference off int");
}
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
return BitInit::get((Value & (1ULL << Bit)) != 0);
}
};
@@ -745,7 +745,7 @@ class StringInit : public TypedInit {
StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION;
StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION;
- virtual void anchor();
+ void anchor() override;
public:
static bool classof(const Init *I) {
@@ -755,22 +755,22 @@ public:
const std::string &getValue() const { return Value; }
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<StringInit *>(this));
}
- virtual std::string getAsString() const { return "\"" + Value + "\""; }
- virtual std::string getAsUnquotedString() const { return Value; }
+ std::string getAsString() const override { return "\"" + Value + "\""; }
+ std::string getAsUnquotedString() const override { return Value; }
/// 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 {
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override {
llvm_unreachable("Illegal element reference off string");
}
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
llvm_unreachable("Illegal bit reference off string");
}
};
@@ -806,10 +806,10 @@ public:
Record *getElementAsRecord(unsigned i) const;
- virtual Init *
- convertInitListSlice(const std::vector<unsigned> &Elements) const;
+ Init *
+ convertInitListSlice(const std::vector<unsigned> &Elements) const override;
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<ListInit *>(this));
}
@@ -818,9 +818,9 @@ public:
/// 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;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
ArrayRef<Init*> getValues() const { return Values; }
@@ -833,10 +833,10 @@ public:
/// 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;
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override;
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
llvm_unreachable("Illegal bit reference off list");
}
};
@@ -866,14 +866,14 @@ public:
// possible to fold.
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<OpInit *>(this));
}
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const;
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override;
- virtual Init *getBit(unsigned Bit) const;
+ Init *getBit(unsigned Bit) const override;
};
@@ -899,14 +899,14 @@ 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 {
+ OpInit *clone(std::vector<Init *> &Operands) const override {
assert(Operands.size() == 1 &&
"Wrong number of operands for unary operation");
return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
}
- virtual int getNumOperands() const { return 1; }
- virtual Init *getOperand(int i) const {
+ int getNumOperands() const override { return 1; }
+ Init *getOperand(int i) const override {
assert(i == 0 && "Invalid operand id for unary operator");
return getOperand();
}
@@ -916,11 +916,11 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const override;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
};
/// BinOpInit - !op (X, Y) - Combine two inits.
@@ -946,14 +946,14 @@ public:
RecTy *Type);
// Clone - Clone this operator, replacing arguments with the new list
- virtual OpInit *clone(std::vector<Init *> &Operands) const {
+ OpInit *clone(std::vector<Init *> &Operands) const override {
assert(Operands.size() == 2 &&
"Wrong number of operands for binary operation");
return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
}
- virtual int getNumOperands() const { return 2; }
- virtual Init *getOperand(int i) const {
+ int getNumOperands() const override { return 2; }
+ Init *getOperand(int i) const override {
assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
if (i == 0) {
return getLHS();
@@ -968,11 +968,11 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const override;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
};
/// TernOpInit - !op (X, Y, Z) - Combine two inits.
@@ -1000,15 +1000,15 @@ public:
RecTy *Type);
// Clone - Clone this operator, replacing arguments with the new list
- virtual OpInit *clone(std::vector<Init *> &Operands) const {
+ OpInit *clone(std::vector<Init *> &Operands) const override {
assert(Operands.size() == 3 &&
"Wrong number of operands for ternary operation");
return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
getType());
}
- virtual int getNumOperands() const { return 3; }
- virtual Init *getOperand(int i) const {
+ int getNumOperands() const override { return 3; }
+ Init *getOperand(int i) const override {
assert((i == 0 || i == 1 || i == 2) &&
"Invalid operand id for ternary operator");
if (i == 0) {
@@ -1027,13 +1027,13 @@ public:
// Fold - If possible, fold this to a simpler init. Return this if not
// possible to fold.
- virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const override;
- virtual bool isComplete() const { return false; }
+ bool isComplete() const override { return false; }
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
};
@@ -1057,7 +1057,7 @@ public:
static VarInit *get(const std::string &VN, RecTy *T);
static VarInit *get(Init *VN, RecTy *T);
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<VarInit *>(this));
}
@@ -1067,23 +1067,23 @@ public:
return getNameInit()->getAsUnquotedString();
}
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const;
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override;
- virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const RecordVal *RV,
- const std::string &FieldName) const;
+ RecTy *getFieldType(const std::string &FieldName) const override;
+ Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const override;
/// 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;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual Init *getBit(unsigned Bit) const;
+ Init *getBit(unsigned Bit) const override;
- virtual std::string getAsString() const { return getName(); }
+ std::string getAsString() const override { return getName(); }
};
@@ -1110,17 +1110,17 @@ public:
}
static VarBitInit *get(TypedInit *T, unsigned B);
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<VarBitInit *>(this));
}
- virtual Init *getBitVar() const { return TI; }
- virtual unsigned getBitNum() const { return Bit; }
+ Init *getBitVar() const override { return TI; }
+ unsigned getBitNum() const override { return Bit; }
- virtual std::string getAsString() const;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ std::string getAsString() const override;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual Init *getBit(unsigned B) const {
+ Init *getBit(unsigned B) const override {
assert(B < 1 && "Bit index out of range!");
return const_cast<VarBitInit*>(this);
}
@@ -1149,7 +1149,7 @@ public:
}
static VarListElementInit *get(TypedInit *T, unsigned E);
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<VarListElementInit *>(this));
}
@@ -1159,14 +1159,13 @@ public:
/// 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;
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override;
- virtual std::string getAsString() const;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ std::string getAsString() const override;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual Init *getBit(unsigned Bit) const;
+ Init *getBit(unsigned Bit) const override;
};
/// DefInit - AL - Represent a reference to a 'def' in the description
@@ -1186,7 +1185,7 @@ public:
}
static DefInit *get(Record*);
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<DefInit *>(this));
}
@@ -1194,21 +1193,21 @@ public:
//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;
+ RecTy *getFieldType(const std::string &FieldName) const override;
+ Init *getFieldInit(Record &R, const RecordVal *RV,
+ const std::string &FieldName) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
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 {
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override {
llvm_unreachable("Illegal element reference off def");
}
};
@@ -1235,19 +1234,18 @@ public:
static FieldInit *get(Init *R, const std::string &FN);
static FieldInit *get(Init *R, const Init *FN);
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<FieldInit *>(this));
}
- virtual Init *getBit(unsigned Bit) const;
+ Init *getBit(unsigned Bit) const override;
- virtual Init *resolveListElementReference(Record &R,
- const RecordVal *RV,
- unsigned Elt) const;
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override;
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual std::string getAsString() const {
+ std::string getAsString() const override {
return Rec->getAsString() + "." + FieldName;
}
};
@@ -1285,7 +1283,7 @@ public:
void Profile(FoldingSetNodeID &ID) const;
- virtual Init *convertInitializerTo(RecTy *Ty) const {
+ Init *convertInitializerTo(RecTy *Ty) const override {
return Ty->convertValue(const_cast<DagInit *>(this));
}
@@ -1303,9 +1301,9 @@ public:
return ArgNames[Num];
}
- virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
+ Init *resolveReferences(Record &R, const RecordVal *RV) const override;
- virtual std::string getAsString() const;
+ std::string getAsString() const override;
typedef std::vector<Init*>::const_iterator const_arg_iterator;
typedef std::vector<std::string>::const_iterator const_name_iterator;
@@ -1322,12 +1320,12 @@ public:
inline size_t name_size () const { return ArgNames.size(); }
inline bool name_empty() const { return ArgNames.empty(); }
- virtual Init *getBit(unsigned Bit) const {
+ Init *getBit(unsigned Bit) const override {
llvm_unreachable("Illegal bit reference off dag");
}
- virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
- unsigned Elt) const {
+ Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) const override {
llvm_unreachable("Illegal element reference off dag");
}
};
@@ -1614,7 +1612,7 @@ public:
/// getValueAsBitOrUnset - This method looks up the specified field and
/// returns its value as a bit. If the field is unset, sets Unset to true and
- /// retunrs false.
+ /// returns false.
///
bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const;
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 3f6eae6..facb89a 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -685,6 +685,27 @@ class InstrInfo {
//
// This option is a temporary migration help. It will go away.
bit guessInstructionProperties = 1;
+
+ // TableGen's instruction encoder generator has support for matching operands
+ // to bit-field variables both by name and by position. While matching by
+ // name is preferred, this is currently not possible for complex operands,
+ // and some targets still reply on the positional encoding rules. When
+ // generating a decoder for such targets, the positional encoding rules must
+ // be used by the decoder generator as well.
+ //
+ // This option is temporary; it will go away once the TableGen decoder
+ // generator has better support for complex operands and targets have
+ // migrated away from using positionally encoded operands.
+ bit decodePositionallyEncodedOperands = 0;
+
+ // When set, this indicates that there will be no overlap between those
+ // operands that are matched by ordering (positional operands) and those
+ // matched by name.
+ //
+ // This option is temporary; it will go away once the TableGen decoder
+ // generator has better support for complex operands and targets have
+ // migrated away from using positionally encoded operands.
+ bit noNamedPositionallyEncodedOperands = 0;
}
// Standard Pseudo Instructions.
@@ -702,7 +723,7 @@ def INLINEASM : Instruction {
let AsmString = "";
let neverHasSideEffects = 1; // Note side effect is encoded in an operand.
}
-def PROLOG_LABEL : Instruction {
+def CFI_INSTRUCTION : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
@@ -802,16 +823,18 @@ def LIFETIME_END : Instruction {
}
def STACKMAP : Instruction {
let OutOperandList = (outs);
- let InOperandList = (ins i32imm:$id, i32imm:$nbytes, variable_ops);
+ let InOperandList = (ins i64imm:$id, i32imm:$nbytes, variable_ops);
let isCall = 1;
let mayLoad = 1;
+ let usesCustomInserter = 1;
}
def PATCHPOINT : Instruction {
let OutOperandList = (outs unknown:$dst);
- let InOperandList = (ins i32imm:$id, i32imm:$nbytes, unknown:$callee,
+ let InOperandList = (ins i64imm:$id, i32imm:$nbytes, unknown:$callee,
i32imm:$nargs, i32imm:$cc, variable_ops);
let isCall = 1;
let mayLoad = 1;
+ let usesCustomInserter = 1;
}
}
@@ -947,7 +970,7 @@ 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";
+ string AsmWriterClassName = "InstPrinter";
// Variant - AsmWriters can be of multiple different variants. Variants are
// used to support targets that need to emit assembly code in ways that are
@@ -957,21 +980,8 @@ class AsmWriter {
// == 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;
diff --git a/include/llvm/Target/TargetCallingConv.h b/include/llvm/Target/TargetCallingConv.h
index 9cc52a5..a660403 100644
--- a/include/llvm/Target/TargetCallingConv.h
+++ b/include/llvm/Target/TargetCallingConv.h
@@ -14,6 +14,7 @@
#ifndef LLVM_TARGET_TARGETCALLINGCONV_H
#define LLVM_TARGET_TARGETCALLINGCONV_H
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
#include <string>
@@ -42,6 +43,8 @@ namespace ISD {
static const uint64_t ByValAlignOffs = 7;
static const uint64_t Split = 1ULL<<11;
static const uint64_t SplitOffs = 11;
+ static const uint64_t InAlloca = 1ULL<<12; ///< Passed with inalloca
+ static const uint64_t InAllocaOffs = 12;
static const uint64_t OrigAlign = 0x1FULL<<27;
static const uint64_t OrigAlignOffs = 27;
static const uint64_t ByValSize = 0xffffffffULL<<32; ///< Struct size
@@ -68,6 +71,9 @@ namespace ISD {
bool isByVal() const { return Flags & ByVal; }
void setByVal() { Flags |= One << ByValOffs; }
+ bool isInAlloca() const { return Flags & InAlloca; }
+ void setInAlloca() { Flags |= One << InAllocaOffs; }
+
bool isNest() const { return Flags & Nest; }
void setNest() { Flags |= One << NestOffs; }
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
index c1bef28..9d1dc38 100644
--- a/include/llvm/Target/TargetCallingConv.td
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -89,11 +89,15 @@ class CCAssignToStack<int size, int align> : CCAction {
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;
+/// CCAssignToStackWithShadow - Same as CCAssignToStack, but with a list of
+/// registers to be shadowed. Note that, unlike CCAssignToRegWithShadow, this
+/// shadows ALL of the registers in shadowList.
+class CCAssignToStackWithShadow<int size,
+ int align,
+ list<Register> shadowList> : CCAction {
+ int Size = size;
+ int Align = align;
+ list<Register> ShadowRegList = shadowList;
}
/// CCPassByVal - This action always matches: it assigns the value to a stack
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index 46eaef2..d4f9f23 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -67,8 +67,8 @@ namespace llvm {
memcpy_chk,
/// double __sincospi_stret(double x);
sincospi_stret,
- /// float __sincospi_stretf(float x);
- sincospi_stretf,
+ /// float __sincospif_stret(float x);
+ sincospif_stret,
/// double __sinpi(double x);
sinpi,
/// float __sinpif(float x);
@@ -251,6 +251,18 @@ namespace llvm {
floorf,
/// long double floorl(long double x);
floorl,
+ /// double fmax(double x, double y);
+ fmax,
+ /// float fmaxf(float x, float y);
+ fmaxf,
+ /// long double fmaxl(long double x, long double y);
+ fmaxl,
+ /// double fmin(double x, double y);
+ fmin,
+ /// float fminf(float x, float y);
+ fminf,
+ /// long double fminl(long double x, long double y);
+ fminl,
/// double fmod(double x, double y);
fmod,
/// float fmodf(float x, float y);
@@ -340,6 +352,12 @@ namespace llvm {
labs,
/// int lchown(const char *path, uid_t owner, gid_t group);
lchown,
+ /// double ldexp(double x, int n);
+ ldexp,
+ /// float ldexpf(float x, int n);
+ ldexpf,
+ /// long double ldexpl(long double x, int n);
+ ldexpl,
/// long long int llabs(long long int j);
llabs,
/// double log(double x);
@@ -703,6 +721,8 @@ public:
case LibFunc::sqrt: case LibFunc::sqrtf: case LibFunc::sqrtl:
case LibFunc::sqrt_finite: case LibFunc::sqrtf_finite:
case LibFunc::sqrtl_finite:
+ case LibFunc::fmax: case LibFunc::fmaxf: case LibFunc::fmaxl:
+ case LibFunc::fmin: case LibFunc::fminf: case LibFunc::fminl:
case LibFunc::floor: case LibFunc::floorf: case LibFunc::floorl:
case LibFunc::nearbyint: case LibFunc::nearbyintf: case LibFunc::nearbyintl:
case LibFunc::ceil: case LibFunc::ceilf: case LibFunc::ceill:
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 5ab04f7..2f6445f 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -28,9 +28,9 @@
#include "llvm/CodeGen/RuntimeLibcalls.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/InlineAsm.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Target/TargetCallingConv.h"
#include "llvm/Target/TargetMachine.h"
#include <climits>
@@ -48,8 +48,10 @@ namespace llvm {
class MachineFunction;
class MachineInstr;
class MachineJumpTableInfo;
+ class Mangler;
class MCContext;
class MCExpr;
+ class MCSymbol;
template<typename T> class SmallVectorImpl;
class DataLayout;
class TargetRegisterClass;
@@ -143,7 +145,7 @@ protected:
public:
const TargetMachine &getTargetMachine() const { return TM; }
- const DataLayout *getDataLayout() const { return TD; }
+ const DataLayout *getDataLayout() const { return DL; }
const TargetLoweringObjectFile &getObjFileLowering() const { return TLOF; }
bool isBigEndian() const { return !IsLittleEndian; }
@@ -173,10 +175,30 @@ public:
return true;
}
+ /// Return true if multiple condition registers are available.
+ bool hasMultipleConditionRegisters() const {
+ return HasMultipleConditionRegisters;
+ }
+
/// Return true if a vector of the given type should be split
/// (TypeSplitVector) instead of promoted (TypePromoteInteger) during type
/// legalization.
- virtual bool shouldSplitVectorElementType(EVT /*VT*/) const { return false; }
+ virtual bool shouldSplitVectorType(EVT /*VT*/) const { return false; }
+
+ // There are two general methods for expanding a BUILD_VECTOR node:
+ // 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
+ // them together.
+ // 2. Build the vector on the stack and then load it.
+ // If this function returns true, then method (1) will be used, subject to
+ // the constraint that all of the necessary shuffles are legal (as determined
+ // by isShuffleMaskLegal). If this function returns false, then method (2) is
+ // always used. The vector type, and the number of defined values, are
+ // provided.
+ virtual bool
+ shouldExpandBuildVectorWithShuffles(EVT /* VT */,
+ unsigned DefinedValues) const {
+ return DefinedValues < 3;
+ }
/// Return true if integer divide is usually cheaper than a sequence of
/// several shifts, adds, and multiplies for this target.
@@ -215,6 +237,21 @@ public:
return true;
}
+ /// \brief Return if the target supports combining a
+ /// chain like:
+ /// \code
+ /// %andResult = and %val1, #imm-with-one-bit-set;
+ /// %icmpResult = icmp %andResult, 0
+ /// br i1 %icmpResult, label %dest1, label %dest2
+ /// \endcode
+ /// into a single machine instruction of a form like:
+ /// \code
+ /// brOnBitSet %register, #bitNumber, dest
+ /// \endcode
+ bool isMaskAndBranchFoldingLegal() const {
+ return MaskAndBranchFoldingIsLegal;
+ }
+
/// 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
@@ -604,8 +641,9 @@ public:
return getValueType(Ty, AllowUnknown).getSimpleVT();
}
- /// Return the desired alignment for ByVal aggregate function arguments in the
- /// caller parameter area. This is the actual alignment, not its logarithm.
+ /// Return the desired alignment for ByVal or InAlloca aggregate function
+ /// arguments in the caller parameter area. This is the actual alignment, not
+ /// its logarithm.
virtual unsigned getByValTypeAlignment(Type *Ty) const;
/// Return the type of registers that this ValueType will eventually require.
@@ -707,14 +745,16 @@ public:
/// \brief Determine if the target supports unaligned memory accesses.
///
- /// This function returns true if the target allows unaligned memory accesses.
- /// of the specified type. If true, it also returns whether the unaligned
- /// memory access is "fast" in the second argument by reference. This is used,
- /// for example, in situations where an array copy/move/set is converted to a
- /// sequence of store operations. It's use helps to ensure that such
- /// replacements don't generate code that causes an alignment error (trap) on
- /// the target machine.
- virtual bool allowsUnalignedMemoryAccesses(EVT, bool * /*Fast*/ = 0) const {
+ /// This function returns true if the target allows unaligned memory accesses
+ /// of the specified type in the given address space. If true, it also returns
+ /// whether the unaligned memory access is "fast" in the third argument by
+ /// reference. This is used, for example, in situations where an array
+ /// copy/move/set is converted to a sequence of store operations. Its use
+ /// helps to ensure that such replacements don't generate code that causes an
+ /// alignment error (trap) on the target machine.
+ virtual bool allowsUnalignedMemoryAccesses(EVT,
+ unsigned AddrSpace = 0,
+ bool * /*Fast*/ = 0) const {
return false;
}
@@ -880,13 +920,13 @@ protected:
}
/// Indicate whether this target prefers to use _setjmp to implement
- /// llvm.setjmp or the non _ version. Defaults to false.
+ /// llvm.setjmp or the version without _. Defaults to false.
void setUseUnderscoreSetJmp(bool Val) {
UseUnderscoreSetJmp = Val;
}
/// Indicate whether this target prefers to use _longjmp to implement
- /// llvm.longjmp or the non _ version. Defaults to false.
+ /// llvm.longjmp or the version without _. Defaults to false.
void setUseUnderscoreLongJmp(bool Val) {
UseUnderscoreLongJmp = Val;
}
@@ -926,6 +966,15 @@ protected:
SelectIsExpensive = isExpensive;
}
+ /// Tells the code generator that the target has multiple (allocatable)
+ /// condition registers that can be used to store the results of comparisons
+ /// for use by selects and conditional branches. With multiple condition
+ /// registers, the code generator will not aggressively sink comparisons into
+ /// the blocks of their users.
+ void setHasMultipleConditionRegisters(bool hasManyRegs = true) {
+ HasMultipleConditionRegisters = hasManyRegs;
+ }
+
/// 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) {
@@ -1166,6 +1215,14 @@ public:
return true;
}
+ /// Return true if it's significantly cheaper to shift a vector by a uniform
+ /// scalar than by an amount which will vary across each lane. On x86, for
+ /// example, there is a "psllw" instruction for the former case, but no simple
+ /// instruction for a general "a << b" operation on vectors.
+ virtual bool isVectorShiftByScalarCheap(Type *Ty) const {
+ return false;
+ }
+
/// 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.
@@ -1273,6 +1330,15 @@ public:
return false;
}
+ /// \brief Return true if it is beneficial to convert a load of a constant to
+ /// just the constant itself.
+ /// On some targets it might be more efficient to use a combination of
+ /// arithmetic instructions to materialize the constant instead of loading it
+ /// from a constant pool.
+ virtual bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
+ Type *Ty) const {
+ return false;
+ }
//===--------------------------------------------------------------------===//
// Runtime Library hooks
//
@@ -1311,7 +1377,7 @@ public:
private:
const TargetMachine &TM;
- const DataLayout *TD;
+ const DataLayout *DL;
const TargetLoweringObjectFile &TLOF;
/// True if this is a little endian target.
@@ -1321,6 +1387,13 @@ private:
/// the select operations if possible.
bool SelectIsExpensive;
+ /// Tells the code generator that the target has multiple (allocatable)
+ /// condition registers that can be used to store the results of comparisons
+ /// for use by selects and conditional branches. With multiple condition
+ /// registers, the code generator will not aggressively sink comparisons into
+ /// the blocks of their users.
+ bool HasMultipleConditionRegisters;
+
/// 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
@@ -1681,10 +1754,18 @@ protected:
/// the branch is usually predicted right.
bool PredictableSelectIsExpensive;
+ /// MaskAndBranchFoldingIsLegal - Indicates if the target supports folding
+ /// a mask of a single bit, a compare, and a branch into a single instruction.
+ bool MaskAndBranchFoldingIsLegal;
+
protected:
/// Return true if the value types that can be represented by the specified
/// register class are all legal.
bool isLegalRC(const TargetRegisterClass *RC) const;
+
+ /// Replace/modify any TargetFrameIndex operands with a targte-dependent
+ /// sequence of memory operands that is recognized by PrologEpilogInserter.
+ MachineBasicBlock *emitPatchPoint(MachineInstr *MI, MachineBasicBlock *MBB) const;
};
/// This class defines information used to lower LLVM code to legal SelectionDAG
@@ -1853,6 +1934,14 @@ public:
void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
};
+ /// Return if the N is a constant or constant vector equal to the true value
+ /// from getBooleanContents().
+ bool isConstTrueVal(const SDNode *N) const;
+
+ /// Return if the N is a constant or constant vector equal to the false value
+ /// from getBooleanContents().
+ bool isConstFalseVal(const SDNode *N) const;
+
/// 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,
@@ -1931,12 +2020,13 @@ public:
bool isSRet : 1;
bool isNest : 1;
bool isByVal : 1;
+ bool isInAlloca : 1;
bool isReturned : 1;
uint16_t Alignment;
ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
- isSRet(false), isNest(false), isByVal(false), isReturned(false),
- Alignment(0) { }
+ isSRet(false), isNest(false), isByVal(false), isInAlloca(false),
+ isReturned(false), Alignment(0) { }
void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
};
@@ -2060,6 +2150,12 @@ public:
return false;
}
+ /// Return the builtin name for the __builtin___clear_cache intrinsic
+ /// Default is to invoke the clear cache library call
+ virtual const char * getClearCacheBuiltinName() const {
+ return "__clear_cache";
+ }
+
/// 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
@@ -2078,6 +2174,18 @@ public:
return NULL;
}
+ /// This callback is used to prepare for a volatile or atomic load.
+ /// It takes a chain node as input and returns the chain for the load itself.
+ ///
+ /// Having a callback like this is necessary for targets like SystemZ,
+ /// which allows a CPU to reuse the result of a previous load indefinitely,
+ /// even if a cache-coherent store is performed by another CPU. The default
+ /// implementation does nothing.
+ virtual SDValue prepareVolatileOrAtomicLoad(SDValue Chain, SDLoc DL,
+ SelectionDAG &DAG) const {
+ return Chain;
+ }
+
/// 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
@@ -2127,6 +2235,10 @@ public:
return 0;
}
+
+ bool verifyReturnAddressArgumentIsConstant(SDValue Op,
+ SelectionDAG &DAG) const;
+
//===--------------------------------------------------------------------===//
// Inline Asm Support hooks
//
@@ -2190,15 +2302,6 @@ public:
/// 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),
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 284b6bb..cdb7ea6 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -29,11 +29,13 @@ namespace llvm {
class MCSymbol;
class MCSymbolRefExpr;
class MCStreamer;
+ class ConstantExpr;
class GlobalValue;
class TargetMachine;
-
+
class TargetLoweringObjectFile : public MCObjectFileInfo {
MCContext *Ctx;
+ const DataLayout *DL;
TargetLoweringObjectFile(
const TargetLoweringObjectFile&) LLVM_DELETED_FUNCTION;
@@ -42,91 +44,88 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
public:
MCContext &getContext() const { return *Ctx; }
- TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(0) {}
-
+ TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(0), DL(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.
+
+ /// 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 {
+ /// Extract the dependent library name from a linker option string. Returns
+ /// StringRef() if the option does not specify a library.
+ virtual StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const {
+ return StringRef();
}
- /// 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.
+ /// Emit the module flags that the platform cares about.
+ virtual void emitModuleFlags(MCStreamer &Streamer,
+ ArrayRef<Module::ModuleFlagEntry> Flags,
+ Mangler &Mang, const TargetMachine &TM) const {}
+
+ /// 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.
+
+ /// 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.
+
+ /// 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,
+ 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.
+
+ /// 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,
+ 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.
+ /// 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 *
- getSpecialCasedSectionGlobals(const GlobalValue *GV, Mangler *Mang,
- SectionKind Kind) const {
+ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
+ Mangler &Mang, const TargetMachine &TM) const = 0;
+
+ /// Allow the target to completely override section assignment of a global.
+ virtual const MCSection *getSpecialCasedSectionGlobals(const GlobalValue *GV,
+ SectionKind Kind,
+ Mangler &Mang) const {
return 0;
}
-
- /// getTTypeGlobalReference - Return an MCExpr to use for a reference
- /// to the specified global variable from exception handling information.
- ///
- virtual const MCExpr *
- getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
-
- /// Return the MCSymbol for the specified global value. This symbol is the
- /// main label that is the address of the global
- MCSymbol *getSymbol(Mangler &M, const GlobalValue *GV) const;
- // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
- virtual MCSymbol *
- getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI) const;
+ /// Return an MCExpr to use for a reference to the specified global variable
+ /// from exception handling information.
+ virtual const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding,
+ Mangler &Mang, const TargetMachine &TM,
+ MachineModuleInfo *MMI, MCStreamer &Streamer) const;
+
+ /// Return the MCSymbol for a private symbol with global value name as its
+ /// base, with the specified suffix.
+ MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
+ StringRef Suffix, Mangler &Mang,
+ const TargetMachine &TM) const;
+
+ // The symbol that gets passed to .cfi_personality.
+ virtual MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
+ Mangler &Mang,
+ const TargetMachine &TM,
+ MachineModuleInfo *MMI) const;
- ///
const MCExpr *
getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
MCStreamer &Streamer) const;
@@ -146,10 +145,22 @@ public:
/// emitting the address in debug info.
virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
+ virtual const MCExpr *
+ getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler &Mang,
+ const TargetMachine &TM) const {
+ return 0;
+ }
+
+ /// \brief True if the section is atomized using the symbols in it.
+ /// This is false if the section is not atomized at all (most ELF sections) or
+ /// if it is atomized based on its contents (MachO' __TEXT,__cstring for
+ /// example).
+ virtual bool isSectionAtomizableBySymbols(const MCSection &Section) const;
+
protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
- Mangler *Mang, const TargetMachine &TM) const;
+ Mangler &Mang, const TargetMachine &TM) const;
};
} // end namespace llvm
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 11b0f5f..ce3f866 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -26,9 +26,11 @@ namespace llvm {
class InstrItineraryData;
class JITCodeEmitter;
class GlobalValue;
+class Mangler;
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
+class MCSymbol;
class Target;
class DataLayout;
class TargetLibraryInfo;
@@ -85,9 +87,9 @@ protected: // Can only create subclasses.
unsigned MCRelaxAll : 1;
unsigned MCNoExecStack : 1;
unsigned MCSaveTempLabels : 1;
- unsigned MCUseLoc : 1;
unsigned MCUseCFI : 1;
unsigned MCUseDwarfDirectory : 1;
+ unsigned RequireStructuredCFG : 1;
public:
virtual ~TargetMachine();
@@ -108,7 +110,7 @@ public:
void resetTargetOptions(const MachineFunction *MF) const;
// Interfaces to the major aspects of target machine information:
- //
+ //
// -- Instruction opcode and operand information
// -- Pipelines and scheduling information
// -- Stack frame information
@@ -156,6 +158,9 @@ public:
return 0;
}
+ bool requiresStructuredCFG() const { return RequireStructuredCFG; }
+ void setRequiresStructuredCFG(bool Value) { RequireStructuredCFG = Value; }
+
/// hasMCRelaxAll - Check whether all machine code instructions should be
/// relaxed.
bool hasMCRelaxAll() const { return MCRelaxAll; }
@@ -178,12 +183,6 @@ public:
/// 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; }
@@ -292,6 +291,10 @@ public:
bool /*DisableVerify*/ = true) {
return true;
}
+
+ void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV,
+ Mangler &Mang, bool MayAlwaysUsePrivate = false) const;
+ MCSymbol *getSymbol(const GlobalValue *GV, Mangler &Mang) const;
};
/// LLVMTargetMachine - This class describes a target machine that is
@@ -309,7 +312,7 @@ public:
/// \brief Register analysis passes for this target with a pass manager.
///
/// This registers target independent analysis passes.
- virtual void addAnalysisPasses(PassManagerBase &PM);
+ void addAnalysisPasses(PassManagerBase &PM) override;
/// createPassConfig - Create a pass configuration object to be used by
/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
@@ -318,12 +321,10 @@ public:
/// 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,
- AnalysisID StartAfter = 0,
- AnalysisID StopAfter = 0);
+ bool addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out,
+ CodeGenFileType FileType, bool DisableVerify = true,
+ AnalysisID StartAfter = 0,
+ AnalysisID StopAfter = 0) override;
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted. This uses a JITCodeEmitter object to handle
@@ -331,19 +332,16 @@ public:
/// of functions. This method returns true if machine code emission is
/// not supported.
///
- virtual bool addPassesToEmitMachineCode(PassManagerBase &PM,
- JITCodeEmitter &MCE,
- bool DisableVerify = true);
+ bool addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &MCE,
+ bool DisableVerify = true) override;
/// 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);
+ bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
+ raw_ostream &OS, bool DisableVerify = true) override;
/// addCodeEmitter - This pass should be overridden by the target to add a
/// code emitter, if supported. If this is not supported, 'true' should be
diff --git a/include/llvm/Target/TargetOpcodes.h b/include/llvm/Target/TargetOpcodes.h
index bd74cb9..abb3eca 100644
--- a/include/llvm/Target/TargetOpcodes.h
+++ b/include/llvm/Target/TargetOpcodes.h
@@ -22,90 +22,90 @@ namespace llvm {
/// 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
- /// represents a consecutive sequence of sub-registers. It's used as a
- /// 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 = 14,
-
- /// Lifetime markers.
- LIFETIME_START = 15,
- LIFETIME_END = 16,
-
- /// A Stackmap instruction captures the location of live variables at its
- /// position in the instruction stream. It is followed by a shadow of bytes
- /// that must lie within the function and not contain another stackmap.
- STACKMAP = 17,
-
- /// Patchable call instruction - this instruction represents a call to a
- /// constant address, followed by a series of NOPs. It is intended to
- /// support optimizations for dynamic languages (such as javascript) that
- /// rewrite calls to runtimes with more efficient code sequences.
- /// This also implies a stack map.
- PATCHPOINT = 18
- };
+enum {
+ PHI = 0,
+ INLINEASM = 1,
+ CFI_INSTRUCTION = 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
+ /// represents a consecutive sequence of sub-registers. It's used as a
+ /// 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 = 14,
+
+ /// Lifetime markers.
+ LIFETIME_START = 15,
+ LIFETIME_END = 16,
+
+ /// A Stackmap instruction captures the location of live variables at its
+ /// position in the instruction stream. It is followed by a shadow of bytes
+ /// that must lie within the function and not contain another stackmap.
+ STACKMAP = 17,
+
+ /// Patchable call instruction - this instruction represents a call to a
+ /// constant address, followed by a series of NOPs. It is intended to
+ /// support optimizations for dynamic languages (such as javascript) that
+ /// rewrite calls to runtimes with more efficient code sequences.
+ /// This also implies a stack map.
+ PATCHPOINT = 18
+};
} // end namespace TargetOpcode
} // end namespace llvm
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index e77be0e..1f87343 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -42,70 +42,17 @@ namespace llvm {
public:
TargetOptions()
: PrintMachineCode(false), NoFramePointerElim(false),
- LessPreciseFPMADOption(false),
- UnsafeFPMath(false), NoInfsFPMath(false),
- NoNaNsFPMath(false), HonorSignDependentRoundingFPMathOption(false),
- UseSoftFloat(false), NoZerosInBSS(false),
- JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
- GuaranteedTailCallOpt(false), DisableTailCalls(false),
- StackAlignmentOverride(0),
+ LessPreciseFPMADOption(false), UnsafeFPMath(false),
+ NoInfsFPMath(false), NoNaNsFPMath(false),
+ HonorSignDependentRoundingFPMathOption(false), UseSoftFloat(false),
+ NoZerosInBSS(false), JITEmitDebugInfo(false),
+ JITEmitDebugInfoToDisk(false), GuaranteedTailCallOpt(false),
+ DisableTailCalls(false), StackAlignmentOverride(0),
EnableFastISel(false), PositionIndependentExecutable(false),
- EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""),
- FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard)
- {}
-
- TargetOptions(const TargetOptions& rhs)
- : PrintMachineCode(rhs.PrintMachineCode),
- NoFramePointerElim(rhs.NoFramePointerElim),
- LessPreciseFPMADOption(rhs.LessPreciseFPMADOption),
- UnsafeFPMath(rhs.UnsafeFPMath),
- NoInfsFPMath(rhs.NoInfsFPMath),
- NoNaNsFPMath(rhs.NoNaNsFPMath),
- HonorSignDependentRoundingFPMathOption(rhs.HonorSignDependentRoundingFPMathOption),
- UseSoftFloat(rhs.UseSoftFloat),
- NoZerosInBSS(rhs.NoZerosInBSS),
- JITEmitDebugInfo(rhs.JITEmitDebugInfo),
- JITEmitDebugInfoToDisk(rhs.JITEmitDebugInfoToDisk),
- GuaranteedTailCallOpt(rhs.GuaranteedTailCallOpt),
- DisableTailCalls(rhs.DisableTailCalls),
- StackAlignmentOverride(rhs.StackAlignmentOverride),
- EnableFastISel(rhs.EnableFastISel),
- PositionIndependentExecutable(rhs.PositionIndependentExecutable),
- EnableSegmentedStacks(rhs.EnableSegmentedStacks),
- UseInitArray(rhs.UseInitArray),
- TrapFuncName(rhs.TrapFuncName),
- FloatABIType(rhs.FloatABIType),
- AllowFPOpFusion(rhs.AllowFPOpFusion)
- {}
-
- TargetOptions& operator =(const TargetOptions& rhs)
- {
- if (&rhs == this)
- return *this;
-
- PrintMachineCode = rhs.PrintMachineCode;
- NoFramePointerElim = rhs.NoFramePointerElim;
- LessPreciseFPMADOption = rhs.LessPreciseFPMADOption;
- UnsafeFPMath = rhs.UnsafeFPMath;
- NoInfsFPMath = rhs.NoInfsFPMath;
- NoNaNsFPMath = rhs.NoNaNsFPMath;
- HonorSignDependentRoundingFPMathOption = rhs.HonorSignDependentRoundingFPMathOption;
- UseSoftFloat = rhs.UseSoftFloat;
- NoZerosInBSS = rhs.NoZerosInBSS;
- JITEmitDebugInfo = rhs.JITEmitDebugInfo;
- JITEmitDebugInfoToDisk = rhs.JITEmitDebugInfoToDisk;
- GuaranteedTailCallOpt = rhs.GuaranteedTailCallOpt;
- DisableTailCalls = rhs.DisableTailCalls;
- StackAlignmentOverride = rhs.StackAlignmentOverride;
- EnableFastISel = rhs.EnableFastISel;
- PositionIndependentExecutable = rhs.PositionIndependentExecutable;
- EnableSegmentedStacks = rhs.EnableSegmentedStacks;
- UseInitArray = rhs.UseInitArray;
- TrapFuncName = rhs.TrapFuncName;
- FloatABIType = rhs.FloatABIType;
- AllowFPOpFusion = rhs.AllowFPOpFusion;
- return *this;
- }
+ EnableSegmentedStacks(false), UseInitArray(false),
+ DisableIntegratedAS(false), CompressDebugSections(false),
+ TrapFuncName(""), FloatABIType(FloatABI::Default),
+ AllowFPOpFusion(FPOpFusion::Standard) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@@ -211,6 +158,12 @@ namespace llvm {
/// constructors.
unsigned UseInitArray : 1;
+ /// Disable the integrated assembler.
+ unsigned DisableIntegratedAS : 1;
+
+ /// Compress DWARF debug sections.
+ unsigned CompressDebugSections : 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.
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 958bea6..b0c21c1 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -672,6 +672,28 @@ public:
// Do nothing.
}
+ /// Allow the target to reverse allocation order of local live ranges. This
+ /// will generally allocate shorter local live ranges first. For targets with
+ /// many registers, this could reduce regalloc compile time by a large
+ /// factor. It is disabled by default for three reasons:
+ /// (1) Top-down allocation is simpler and easier to debug for targets that
+ /// don't benefit from reversing the order.
+ /// (2) Bottom-up allocation could result in poor evicition decisions on some
+ /// targets affecting the performance of compiled code.
+ /// (3) Bottom-up allocation is no longer guaranteed to optimally color.
+ virtual bool reverseLocalAssignment() const { return false; }
+
+ /// Allow the target to override register assignment heuristics based on the
+ /// live range size. If this returns false, then local live ranges are always
+ /// assigned in order regardless of their size. This is a temporary hook for
+ /// debugging downstream codegen failures exposed by regalloc.
+ virtual bool mayOverrideLocalAssignment() const { return true; }
+
+ /// Allow the target to override the cost of using a callee-saved register for
+ /// the first time. Default value of 0 means we will use a callee-saved
+ /// register if it is available.
+ virtual unsigned getCSRFirstUseCost() const { return 0; }
+
/// requiresRegisterScavenging - returns true if the target requires (and can
/// make use of) the register scavenger.
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
@@ -748,8 +770,8 @@ public:
/// 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 {
+ virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
+ int64_t Offset) const {
llvm_unreachable("resolveFrameIndex does not exist on this target");
}
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 9d4858a..b4d0c44 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -114,14 +114,46 @@ class ProcResourceKind;
// resources implies using one of the super resoruces.
//
// ProcResourceUnits normally model a few buffered resources within an
-// out-of-order engine that the compiler attempts to conserve.
-// Buffered resources may be held for multiple clock cycles, but the
-// scheduler does not pin them to a particular clock cycle relative to
-// instruction dispatch. Setting BufferSize=0 changes this to an
-// in-order resource. In this case, the scheduler counts down from the
-// cycle that the instruction issues in-order, forcing an interlock
-// with subsequent instructions that require the same resource until
-// the number of ResourceCyles specified in WriteRes expire.
+// out-of-order engine. Buffered resources may be held for multiple
+// clock cycles, but the scheduler does not pin them to a particular
+// clock cycle relative to instruction dispatch. Setting BufferSize=0
+// changes this to an in-order issue/dispatch resource. In this case,
+// the scheduler counts down from the cycle that the instruction
+// issues in-order, forcing a stall whenever a subsequent instruction
+// requires the same resource until the number of ResourceCyles
+// specified in WriteRes expire. Setting BufferSize=1 changes this to
+// an in-order latency resource. In this case, the scheduler models
+// producer/consumer stalls between instructions that use the
+// resource.
+//
+// Examples (all assume an out-of-order engine):
+//
+// Use BufferSize = -1 for "issue ports" fed by a unified reservation
+// station. Here the size of the reservation station is modeled by
+// MicroOpBufferSize, which should be the minimum size of either the
+// register rename pool, unified reservation station, or reorder
+// buffer.
+//
+// Use BufferSize = 0 for resources that force "dispatch/issue
+// groups". (Different processors define dispath/issue
+// differently. Here we refer to stage between decoding into micro-ops
+// and moving them into a reservation station.) Normally NumMicroOps
+// is sufficient to limit dispatch/issue groups. However, some
+// processors can form groups of with only certain combinitions of
+// instruction types. e.g. POWER7.
+//
+// Use BufferSize = 1 for in-order execution units. This is used for
+// an in-order pipeline within an out-of-order core where scheduling
+// dependent operations back-to-back is guaranteed to cause a
+// bubble. e.g. Cortex-a9 floating-point.
+//
+// Use BufferSize > 1 for out-of-order executions units with a
+// separate reservation station. This simply models the size of the
+// reservation station.
+//
+// To model both dispatch/issue groups and in-order execution units,
+// create two types of units, one with BufferSize=0 and one with
+// BufferSize=1.
//
// SchedModel ties these units to a processor for any stand-alone defs
// of this class. Instances of subclass ProcResource will be automatically
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index d94bdc6..16cfff1 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -362,7 +362,6 @@ 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]>;
@@ -466,7 +465,7 @@ def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT",
SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>;
def concat_vectors : SDNode<"ISD::CONCAT_VECTORS",
- SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1, 2>]>,[]>;
+ SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>;
// This operator does not do subvector type checking. The ARM
// backend, at least, needs it.
@@ -492,6 +491,12 @@ def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
// Do not use cvt directly. Use cvt forms below
def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>;
+def SDT_assertext : SDTypeProfile<1, 1,
+ [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
+def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>;
+def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>;
+
+
//===----------------------------------------------------------------------===//
// Selection DAG Condition Codes
@@ -554,6 +559,12 @@ class PatFrag<dag ops, dag frag, code pred = [{}],
SDNodeXForm OperandTransform = xform;
}
+// OutPatFrag is a pattern fragment that is used as part of an output pattern
+// (not an input pattern). These do not have predicates or transforms, but are
+// used to avoid repeated subexpressions in output patterns.
+class OutPatFrag<dag ops, dag frag>
+ : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>;
+
// 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>
diff --git a/include/llvm/Target/TargetSelectionDAGInfo.h b/include/llvm/Target/TargetSelectionDAGInfo.h
index 3474ee4..98a5149 100644
--- a/include/llvm/Target/TargetSelectionDAGInfo.h
+++ b/include/llvm/Target/TargetSelectionDAGInfo.h
@@ -31,10 +31,10 @@ class TargetSelectionDAGInfo {
TargetSelectionDAGInfo(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
void operator=(const TargetSelectionDAGInfo &) LLVM_DELETED_FUNCTION;
- const DataLayout *TD;
+ const DataLayout *DL;
protected:
- const DataLayout *getDataLayout() const { return TD; }
+ const DataLayout *getDataLayout() const { return DL; }
public:
explicit TargetSelectionDAGInfo(const TargetMachine &TM);
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
index 7f51c51..334fb1c 100644
--- a/include/llvm/Transforms/IPO.h
+++ b/include/llvm/Transforms/IPO.h
@@ -34,7 +34,7 @@ ModulePass *createStripSymbolsPass(bool OnlyDebugInfo = false);
//===----------------------------------------------------------------------===//
//
-// These functions strips symbols from functions and modules.
+// These functions strips symbols from functions and modules.
// Only debugging information is not stripped.
//
ModulePass *createStripNonDebugSymbolsPass();
@@ -78,20 +78,24 @@ ModulePass *createGlobalDCEPass();
/// 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
+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 Threshold can be passed directly, or asked to be computed from the
+/// given optimization and size optimization arguments.
+///
/// The -inline-threshold command line option takes precedence over the
/// threshold given here.
Pass *createFunctionInliningPass();
Pass *createFunctionInliningPass(int Threshold);
+Pass *createFunctionInliningPass(unsigned OptLevel, unsigned SizeOptLevel);
//===----------------------------------------------------------------------===//
-/// createAlwaysInlinerPass - Return a new pass object that inlines only
+/// createAlwaysInlinerPass - Return a new pass object that inlines only
/// functions that are marked as "always_inline".
Pass *createAlwaysInlinerPass();
Pass *createAlwaysInlinerPass(bool InsertLifetime);
@@ -187,7 +191,7 @@ ModulePass *createMergeFunctionsPass();
/// createPartialInliningPass - This pass inlines parts of functions.
///
ModulePass *createPartialInliningPass();
-
+
//===----------------------------------------------------------------------===//
// createMetaRenamerPass - Rename everything with metasyntatic names.
//
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
index 43a0ac8..6a644ad 100644
--- a/include/llvm/Transforms/IPO/InlinerPass.h
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -36,16 +36,16 @@ struct Inliner : public CallGraphSCCPass {
/// 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;
+ void getAnalysisUsage(AnalysisUsage &Info) const override;
// Main run interface method, this implements the interface required by the
// Pass class.
- virtual bool runOnSCC(CallGraphSCC &SCC);
+ bool runOnSCC(CallGraphSCC &SCC) override;
using llvm::Pass::doFinalization;
// doFinalization - Remove now-dead linkonce functions at the end of
// processing to avoid breaking the SCC traversal.
- virtual bool doFinalization(CallGraph &CG);
+ bool doFinalization(CallGraph &CG) override;
/// This method returns the value specified by the -inline-threshold value,
/// specified on the command line. This is typically not directly needed.
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 2788774..42b6b27 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -111,7 +111,6 @@ public:
bool BBVectorize;
bool SLPVectorize;
bool LoopVectorize;
- bool LateVectorize;
bool RerollLoops;
private:
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 2de15aa..b527546 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -66,14 +66,12 @@ ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
// Insert AddressSanitizer (address sanity checking) instrumentation
FunctionPass *createAddressSanitizerFunctionPass(
bool CheckInitOrder = true, bool CheckUseAfterReturn = false,
- bool CheckLifetime = false, StringRef BlacklistFile = StringRef(),
- bool ZeroBaseShadow = false);
+ bool CheckLifetime = false, StringRef BlacklistFile = StringRef());
ModulePass *createAddressSanitizerModulePass(
- bool CheckInitOrder = true, StringRef BlacklistFile = StringRef(),
- bool ZeroBaseShadow = false);
+ bool CheckInitOrder = true, StringRef BlacklistFile = StringRef());
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
-FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false,
+FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0,
StringRef BlacklistFile = StringRef());
// Insert ThreadSanitizer (race detection) instrumentation
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 1521c4c..7267222 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -142,6 +142,8 @@ Pass *createLoopInstSimplifyPass();
//
Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1,
int AllowPartial = -1, int Runtime = -1);
+// Create an unrolling pass for full unrolling only.
+Pass *createSimpleLoopUnrollPass();
//===----------------------------------------------------------------------===//
//
@@ -262,16 +264,10 @@ 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.
+// LowerInvoke - This pass removes invoke instructions, converting them to call
+// instructions.
//
-FunctionPass *createLowerInvokePass(const TargetMachine *TM = 0,
- bool useExpensiveEHSupport = false);
+FunctionPass *createLowerInvokePass();
extern char &LowerInvokePassID;
//===----------------------------------------------------------------------===//
@@ -312,9 +308,9 @@ Pass *createLoopDeletionPass();
//===----------------------------------------------------------------------===//
//
-// CodeGenPrepare - This pass prepares a function for instruction selection.
+// ConstantHoisting - This pass prepares a function for expensive constants.
//
-FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = 0);
+FunctionPass *createConstantHoistingPass();
//===----------------------------------------------------------------------===//
//
@@ -370,6 +366,17 @@ FunctionPass *createPartiallyInlineLibCallsPass();
FunctionPass *createSampleProfileLoaderPass();
FunctionPass *createSampleProfileLoaderPass(StringRef Name);
+//===----------------------------------------------------------------------===//
+//
+// ScalarizerPass - Converts vector operations into scalar operations
+//
+FunctionPass *createScalarizerPass();
+
+//===----------------------------------------------------------------------===//
+//
+// AddDiscriminators - Add DWARF path discriminators to the IR.
+FunctionPass *createAddDiscriminatorsPass();
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/ASanStackFrameLayout.h b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
new file mode 100644
index 0000000..4e4f02c
--- /dev/null
+++ b/include/llvm/Transforms/Utils/ASanStackFrameLayout.h
@@ -0,0 +1,64 @@
+//===- ASanStackFrameLayout.h - ComputeASanStackFrameLayout -----*- 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 ComputeASanStackFrameLayout and auxiliary data structs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
+#define LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class AllocaInst;
+
+// These magic constants should be the same as in
+// in asan_internal.h from ASan runtime in compiler-rt.
+static const int kAsanStackLeftRedzoneMagic = 0xf1;
+static const int kAsanStackMidRedzoneMagic = 0xf2;
+static const int kAsanStackRightRedzoneMagic = 0xf3;
+
+// Input/output data struct for ComputeASanStackFrameLayout.
+struct ASanStackVariableDescription {
+ const char *Name; // Name of the variable that will be displayed by asan
+ // if a stack-related bug is reported.
+ uint64_t Size; // Size of the variable in bytes.
+ size_t Alignment; // Alignment of the variable (power of 2).
+ AllocaInst *AI; // The actual AllocaInst.
+ size_t Offset; // Offset from the beginning of the frame;
+ // set by ComputeASanStackFrameLayout.
+};
+
+// Output data struct for ComputeASanStackFrameLayout.
+struct ASanStackFrameLayout {
+ // Frame description, see DescribeAddressIfStack in ASan runtime.
+ SmallString<64> DescriptionString;
+ // The contents of the shadow memory for the stack frame that we need
+ // to set at function entry.
+ SmallVector<uint8_t, 64> ShadowBytes;
+ size_t FrameAlignment; // Alignment for the entire frame.
+ size_t FrameSize; // Size of the frame in bytes.
+};
+
+void ComputeASanStackFrameLayout(
+ // The array of stack variables. The elements may get reordered and changed.
+ SmallVectorImpl<ASanStackVariableDescription> &Vars,
+ // AddressSanitizer's shadow granularity. Usually 8, may also be 16, 32, 64.
+ size_t Granularity,
+ // The minimal size of the left-most redzone (header).
+ // At least 4 pointer sizes, power of 2, and >= Granularity.
+ // The resulting FrameSize should be multiple of MinHeaderSize.
+ size_t MinHeaderSize,
+ // The result is put here.
+ ASanStackFrameLayout *Layout);
+
+} // llvm namespace
+
+#endif // LLVM_TRANSFORMS_UTILS_ASANSTACKFRAMELAYOUT_H
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 65cafe2..4d5e305 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -18,7 +18,7 @@
// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
#include "llvm/IR/BasicBlock.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/IR/CFG.h"
namespace llvm {
@@ -183,27 +183,47 @@ ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
BasicBlock *Pred);
/// SplitBlockAndInsertIfThen - Split the containing block at the
-/// specified instruction - everything before and including Cmp stays
-/// in the old basic block, and everything after Cmp is moved to a
+/// specified instruction - everything before and including SplitBefore stays
+/// in the old basic block, and everything after SplitBefore is moved to a
/// new block. The two blocks are connected by a conditional branch
/// (with value of Cmp being the condition).
/// Before:
/// Head
-/// Cmp
+/// SplitBefore
/// Tail
/// After:
/// Head
-/// Cmp
-/// if (Cmp)
+/// if (Cond)
/// ThenBlock
+/// SplitBefore
/// Tail
///
/// If Unreachable is true, then ThenBlock ends with
/// UnreachableInst, otherwise it branches to Tail.
/// Returns the NewBasicBlock's terminator.
+TerminatorInst *SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore,
+ bool Unreachable,
+ MDNode *BranchWeights = 0);
-TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
- bool Unreachable, MDNode *BranchWeights = 0);
+
+/// SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen,
+/// but also creates the ElseBlock.
+/// Before:
+/// Head
+/// SplitBefore
+/// Tail
+/// After:
+/// Head
+/// if (Cond)
+/// ThenBlock
+/// else
+/// ElseBlock
+/// SplitBefore
+/// Tail
+void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
+ TerminatorInst **ThenTerm,
+ TerminatorInst **ElseTerm,
+ MDNode *BranchWeights = 0);
///
/// GetIfCondition - Check whether BB is the merge point of a if-region.
@@ -211,9 +231,8 @@ TerminatorInst *SplitBlockAndInsertIfThen(Instruction *Cmp,
/// BB will be taken. Also, return by references the block that will be
/// entered from if the condition is true, and the block that will be
/// entered if the condition is false.
-
Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
- BasicBlock *&IfFalse);
+ BasicBlock *&IfFalse);
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index 181ed07..0f39ada 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -83,6 +83,14 @@ namespace llvm {
Value *EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
const AttributeSet &Attrs);
+ /// EmitUnaryFloatFnCall - Emit a call to the binary function named 'Name'
+ /// (e.g. 'fmin'). This function is known to take type matching 'Op1' and
+ /// 'Op2' and return one value with the same type. If 'Op1/Op2' are long
+ /// double, 'l' is added as the suffix of name, if 'Op1/Op2' are float, we
+ /// add a 'f' suffix.
+ Value *EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
+ IRBuilder<> &B, const AttributeSet &Attrs);
+
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index 3ec1329..96c6508 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -20,8 +20,8 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/ValueMap.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/IR/ValueMap.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
namespace llvm {
@@ -109,7 +109,7 @@ BasicBlock *CloneBasicBlock(const BasicBlock *BB,
/// information about the cloned code if non-null.
///
/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue
-/// mappings.
+/// mappings, and debug info metadata will not be cloned.
///
Function *CloneFunction(const Function *F,
ValueToValueMapTy &VMap,
@@ -151,7 +151,7 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = 0,
- const DataLayout *TD = 0,
+ const DataLayout *DL = 0,
Instruction *TheCall = 0);
@@ -159,13 +159,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
/// InlineFunction call, and records the auxiliary results produced by it.
class InlineFunctionInfo {
public:
- explicit InlineFunctionInfo(CallGraph *cg = 0, const DataLayout *td = 0)
- : CG(cg), TD(td) {}
+ explicit InlineFunctionInfo(CallGraph *cg = 0, const DataLayout *DL = 0)
+ : CG(cg), DL(DL) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
- const DataLayout *TD;
+ const DataLayout *DL;
/// StaticAllocas - InlineFunction fills this in with all static allocas that
/// get copied into the caller.
diff --git a/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
index 488d7a5..22469e0 100644
--- a/include/llvm/Transforms/Utils/CmpInstAnalysis.h
+++ b/include/llvm/Transforms/Utils/CmpInstAnalysis.h
@@ -1,4 +1,4 @@
-//===-- CmpInstAnalysis.h - Utils to help fold compare insts ------===//
+//===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h
index 27d3c58..55e8b66 100644
--- a/include/llvm/Transforms/Utils/IntegerDivision.h
+++ b/include/llvm/Transforms/Utils/IntegerDivision.h
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains an implementation of 32bit integer division for targets
-// that don't have native support. It's largely derived from compiler-rt's
-// implementation of __udivsi3, but hand-tuned for targets that prefer less
-// control flow.
+// This file contains an implementation of 32bit and 64bit scalar integer
+// division for targets that don't have native support. It's largely derived
+// from compiler-rt's implementations of __udivsi3 and __udivmoddi4,
+// but hand-tuned for targets that prefer less control flow.
//
//===----------------------------------------------------------------------===//
@@ -26,9 +26,8 @@ namespace llvm {
/// Generate code to calculate the remainder of two integers, replacing Rem
/// with the generated code. This currently generates code using the udiv
/// expansion, but future work includes generating more specialized code,
- /// e.g. when more information about the operands are known. Currently only
- /// implements 32bit scalar division (due to udiv's limitation), but future
- /// work is removing this limitation.
+ /// e.g. when more information about the operands are known. Implements both
+ /// 32bit and 64bit scalar division.
///
/// @brief Replace Rem with generated code.
bool expandRemainder(BinaryOperator *Rem);
@@ -36,27 +35,39 @@ namespace llvm {
/// Generate code to divide two integers, replacing Div with the generated
/// code. This currently generates code similarly to compiler-rt's
/// implementations, but future work includes generating more specialized code
- /// when more information about the operands are known. Currently only
- /// implements 32bit scalar division, but future work is removing this
- /// limitation.
+ /// when more information about the operands are known. Implements both
+ /// 32bit and 64bit scalar division.
///
/// @brief Replace Div with generated code.
bool expandDivision(BinaryOperator* Div);
/// Generate code to calculate the remainder of two integers, replacing Rem
- /// with the generated code. Uses the above 32bit routine, therefore adequate
- /// for targets with little or no support for less than 32 bit arithmetic.
+ /// with the generated code. Uses ExpandReminder with a 32bit Rem which
+ /// makes it useful for targets with little or no support for less than
+ /// 32 bit arithmetic.
///
/// @brief Replace Rem with generated code.
bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
+ /// Generate code to calculate the remainder of two integers, replacing Rem
+ /// with the generated code. Uses ExpandReminder with a 64bit Rem.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandRemainderUpTo64Bits(BinaryOperator *Rem);
+
/// Generate code to divide two integers, replacing Div with the generated
- /// code. Uses the above 32bit routine, therefore adequate for targets with
- /// little or no support for less than 32 bit arithmetic.
+ /// code. Uses ExpandDivision with a 32bit Div which makes it useful for
+ /// targets with little or no support for less than 32 bit arithmetic.
///
/// @brief Replace Rem with generated code.
bool expandDivisionUpTo32Bits(BinaryOperator *Div);
+ /// Generate code to divide two integers, replacing Div with the generated
+ /// code. Uses ExpandDivision with a 64bit Div.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandDivisionUpTo64Bits(BinaryOperator *Div);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 5586c15..c68fd06 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -16,9 +16,9 @@
#define LLVM_TRANSFORMS_UTILS_LOCAL_H
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Operator.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
namespace llvm {
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index 4745eba..64e18ca1 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -15,12 +15,49 @@
#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
namespace llvm {
-
+class AliasAnalysis;
+class BasicBlock;
+class DominatorTree;
class Loop;
+class LoopInfo;
class Pass;
+class ScalarEvolution;
BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
+/// \brief Simplify each loop in a loop nest recursively.
+///
+/// This takes a potentially un-simplified loop L (and its children) and turns
+/// it into a simplified loop nest with preheaders and single backedges. It
+/// will optionally update \c AliasAnalysis and \c ScalarEvolution analyses if
+/// passed into it.
+bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
+ AliasAnalysis *AA = 0, ScalarEvolution *SE = 0);
+
+/// \brief Put loop into LCSSA form.
+///
+/// Looks at all instructions in the loop which have uses outside of the
+/// current loop. For each, an LCSSA PHI node is inserted and the uses outside
+/// the loop are rewritten to use this node.
+///
+/// LoopInfo and DominatorTree are required and preserved.
+///
+/// If ScalarEvolution is passed in, it will be preserved.
+///
+/// Returns true if any modifications are made to the loop.
+bool formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE = 0);
+
+/// \brief Put a loop nest into LCSSA form.
+///
+/// This recursively forms LCSSA for a loop nest.
+///
+/// LoopInfo and DominatorTree are required and preserved.
+///
+/// If ScalarEvolution is passed in, it will be preserved.
+///
+/// Returns true if any modifications are made to the loop.
+bool formLCSSARecursively(Loop &L, DominatorTree &DT, ScalarEvolution *SE = 0);
+
}
#endif
diff --git a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
index a9adbd7..0f3da16 100644
--- a/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
+++ b/include/llvm/Transforms/Utils/SSAUpdaterImpl.h
@@ -17,9 +17,9 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h
index 7e97e21..dedeca3 100644
--- a/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -16,12 +16,13 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ValueHandle.h"
namespace llvm {
class CastInst;
+class DominatorTree;
class IVUsers;
class Loop;
class LPPassManager;
@@ -31,9 +32,25 @@ class ScalarEvolution;
/// Interface for visiting interesting IV users that are recognized but not
/// simplified by this utility.
class IVVisitor {
+protected:
+ const DominatorTree *DT;
+ bool ShouldSplitOverflowIntrinsics;
+
virtual void anchor();
public:
+ IVVisitor(): DT(NULL), ShouldSplitOverflowIntrinsics(false) {}
virtual ~IVVisitor() {}
+
+ const DominatorTree *getDomTree() const { return DT; }
+
+ bool shouldSplitOverflowInstrinsics() const {
+ return ShouldSplitOverflowIntrinsics;
+ }
+ void setSplitOverflowIntrinsics() {
+ ShouldSplitOverflowIntrinsics = true;
+ assert(DT && "Splitting overflow intrinsics requires a DomTree.");
+ }
+
virtual void visitCast(CastInst *Cast) = 0;
};
diff --git a/include/llvm/Transforms/Utils/SpecialCaseList.h b/include/llvm/Transforms/Utils/SpecialCaseList.h
index 34c28fc..508a6df 100644
--- a/include/llvm/Transforms/Utils/SpecialCaseList.h
+++ b/include/llvm/Transforms/Utils/SpecialCaseList.h
@@ -43,7 +43,9 @@
// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
//
//===----------------------------------------------------------------------===//
-//
+
+#ifndef LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
+#define LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
#include "llvm/ADT/StringMap.h"
@@ -108,3 +110,5 @@ class SpecialCaseList {
};
} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_SPECIALCASELIST_H
diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
index 933c85c..79a70cf 100644
--- a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
+++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -32,7 +32,7 @@ public:
}
// We can preserve non-critical-edgeness when we unify function exit nodes
- virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
// getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistent)
// return, unwind, or unreachable basic blocks in the CFG.
@@ -41,7 +41,7 @@ public:
BasicBlock *getUnwindBlock() const { return UnwindBlock; }
BasicBlock *getUnreachableBlock() const { return UnreachableBlock; }
- virtual bool runOnFunction(Function &F);
+ bool runOnFunction(Function &F) override;
};
Pass *createUnifyFunctionExitNodesPass();
diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h
index f175e83..0bbd572 100644
--- a/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -21,9 +21,11 @@ namespace llvm {
class Loop;
class LoopInfo;
class LPPassManager;
+class Pass;
bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime,
- unsigned TripMultiple, LoopInfo* LI, LPPassManager* LPM);
+ unsigned TripMultiple, LoopInfo *LI, Pass *PP,
+ LPPassManager *LPM);
bool UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
LPPassManager* LPM);
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index d56ac07..e96610e 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -15,7 +15,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
-#include "llvm/ADT/ValueMap.h"
+#include "llvm/IR/ValueMap.h"
namespace llvm {
class Value;
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index 823c5fb..e93b39a 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -114,7 +114,8 @@ createBBVectorizePass(const VectorizeConfig &C = VectorizeConfig());
//
// LoopVectorize - Create a loop vectorization pass.
//
-Pass *createLoopVectorizePass(bool NoUnrolling = false);
+Pass *createLoopVectorizePass(bool NoUnrolling = false,
+ bool AlwaysVectorize = true);
//===----------------------------------------------------------------------===//
//